0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

內(nèi)核內(nèi)存布局

電子工程師 ? 來源:嵌入式開發(fā)AIoT ? 作者:嵌入式開發(fā)AIoT ? 2022-08-08 17:14 ? 次閱讀

一、內(nèi)核內(nèi)存布局

64位Linux一般使用48位表示虛擬地址空間,43位表示物理地址,通過命令:cat /proc/cpuinfo

32401ca6-16c0-11ed-ba43-dac502259ad0.png
  • ARM64架構(gòu)處理器采用48位物理尋址機(jī)制,最大可尋找256TB的物理地址空間。對于 目前應(yīng)用完全足夠,不需要擴(kuò)展到64位的物理尋址。虛擬地址也同樣最大支持48位尋址,所以 在處理器架構(gòu)設(shè)計(jì)上,把虛擬地址空間劃分為兩個空間,每個空間最大支持256TB,linux內(nèi)核 在大多數(shù)體系結(jié)構(gòu)上都把兩個地址劃分為:用戶空間和內(nèi)核空間。

  • 用戶空間:0x0000_0000_0000_0000至0x0000_ffff_ffff_ffff;

  • 內(nèi)核空間:0xffff_0000_0000_0000至0xffff_ffff_ffff_ffff;

QEMU平臺,可以打印ARM64架構(gòu)linux內(nèi)核內(nèi)存分布情況

327151a4-16c0-11ed-ba43-dac502259ad0.png

二、堆管理

堆是進(jìn)程中主要用于動態(tài)分配變量和數(shù)據(jù)的內(nèi)存區(qū)域,堆的管理對應(yīng)程序員不是直接可見的。因?yàn)樗蕾嚇?biāo)準(zhǔn)庫提供的各個輔助函數(shù)(其中最重要的是malloc)來分配任意長度的內(nèi)存區(qū)。malloc和內(nèi)核之間的經(jīng)典接口是brk系統(tǒng)調(diào)用,負(fù)責(zé)擴(kuò)展/收縮堆。

329df57e-16c0-11ed-ba43-dac502259ad0.png
  • 堆是一個連續(xù)的內(nèi)存區(qū)域,在擴(kuò)展時(shí)自下至上增長。其中mm_struct結(jié)構(gòu),包含堆在虛擬地 址空間中的起始和當(dāng)前結(jié)束地址(start_brk和brk)。
  • brk系統(tǒng)調(diào)用用于指定堆在虛擬地址空間中新的結(jié)束地址(如果堆將要收縮,當(dāng)然可以小于當(dāng)前值)。brk系統(tǒng)調(diào)用通過do_brk增長動態(tài)分配區(qū)(內(nèi)核源碼分mm/mmap.c)

三、sys_brk流程

  1. 檢查資源限制;

  2. 將brk值對齊到頁;

  3. 是否想增加brk值?(這個地方要結(jié)合源碼看)

    是-->do_brk();返回新的brk的值;

    否-->do_munmap();返回新的brk的值;

brk機(jī)制不是一個獨(dú)立的內(nèi)核概念,而是基于匿名映射實(shí)現(xiàn),以減少內(nèi)部的開銷。在檢查過用brk的值的新地址未超出推的限制之后,sys_brk第一個重要操作是請求的地址按頁長對齊。brk()用于進(jìn)程向內(nèi)核申請空間,用于擴(kuò)展用戶堆??臻g,或者回收堆棧空間。

  • malloc為小空間申請,brk()為大塊空間申請。do_brk()用于增長動態(tài)分配區(qū)。do_munmap()釋放動態(tài)分配區(qū);
  • do_brk()源碼分析:
staticunsignedlongdo_brk(unsignedlongaddr,unsignedlonglen)
{
structmm_struct*mm=current->mm;
structvm_area_struct*vma,*prev;
unsignedlongflags;
structrb_node**rb_link,*rb_parent;
pgoff_tpgoff=addr>>PAGE_SHIFT;
interror;

//首先對len這個長度進(jìn)行頁面對齊去判斷頁面對齊之后是否超出邊界
len=PAGE_ALIGN(len);
if(!len)
returnaddr;

flags=VM_DATA_DEFAULT_FLAGS|VM_ACCOUNT|mm->def_flags;

//檢查是否有足夠內(nèi)存空間來分析len大小的內(nèi)存。判斷虛擬地址空間是否足夠
error=get_unmapped_area(NULL,addr,len,0,MAP_FIXED);
if(offset_in_page(error))
returnerror;

error=mlock_future_check(mm,mm->def_flags,len);
if(error)
returnerror;

/*
*mm->mmap_semisrequiredtoprotectagainstanotherthread
*changingthemappingsincasewesleep.
*/
verify_mm_writelocked(mm);

/*
*Clearoldmaps.thisalsodoessomeerrorcheckingforus
*/
//循環(huán)遍歷用戶進(jìn)程紅黑樹中VMA,然后根據(jù)addr來查找合適的插入點(diǎn)
while(find_vma_links(mm,addr,addr+len,&prev,&rb_link,
&rb_parent)){
if(do_munmap(mm,addr,len))
return-ENOMEM;
}

/*Checkagainstaddressspacelimits*after*clearingoldmaps...*/
//檢查是否要對此虛擬區(qū)間進(jìn)行擴(kuò)充
if(!may_expand_vm(mm,len>>PAGE_SHIFT))
return-ENOMEM;

if(mm->map_count>sysctl_max_map_count)
return-ENOMEM;
//判斷系統(tǒng)是否有足夠內(nèi)存
if(security_vm_enough_memory_mm(mm,len>>PAGE_SHIFT))
return-ENOMEM;

/*Canwejustexpandanoldprivateanonymousmapping?*/
//判讀是否可以合并,如果可以合并就合并成為一個vam區(qū)
vma=vma_merge(mm,prev,addr,addr+len,flags,
NULL,NULL,pgoff,NULL,NULL_VM_UFFD_CTX);

//如果能合并直接gotoout
if(vma)
gotoout;

/*
*createavmastructforananonymousmapping
*/

//如果沒有辦法合并,只有新創(chuàng)建一個VMA,VMA地址空間是【addr,addr+len】
vma=kmem_cache_zalloc(vm_area_cachep,GFP_KERNEL);
if(!vma){
vm_unacct_memory(len>>PAGE_SHIFT);
return-ENOMEM;
}

//指向匿名域指針
INIT_LIST_HEAD(&vma->anon_vma_chain);
vma->vm_mm=mm;//指向VMA所屬于進(jìn)程structmm_struct結(jié)構(gòu)
vma->vm_start=addr;
vma->vm_end=addr+len;
vma->vm_pgoff=pgoff;
vma->vm_flags=flags;
vma->vm_page_prot=vm_get_page_prot(flags);
vma_link(mm,vma,prev,rb_link,rb_parent);
out://增加進(jìn)程地址空間長度
perf_event_mmap(vma);
mm->total_vm+=len>>PAGE_SHIFT;
if(flags&VM_LOCKED)
mm->locked_vm+=(len>>PAGE_SHIFT);
vma->vm_flags|=VM_SOFTDIRTY;
returnaddr;
}

- END -


審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 處理器
    +關(guān)注

    關(guān)注

    68

    文章

    19404

    瀏覽量

    230914
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1382

    瀏覽量

    40385
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11342

    瀏覽量

    210222
  • AIoT
    +關(guān)注

    關(guān)注

    8

    文章

    1418

    瀏覽量

    30887

原文標(biāo)題:接上一篇續(xù)集

文章出處:【微信號:嵌入式開發(fā)AIoT,微信公眾號:嵌入式開發(fā)AIoT】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Linux服務(wù)器卡頓救星之一招釋放Cache內(nèi)存

    為了加速操作和減少磁盤I/O,內(nèi)核通常會盡可能多地緩存內(nèi)存,這部分內(nèi)存就是Cache Memory(緩存內(nèi)存)。根據(jù)設(shè)計(jì),包含緩存數(shù)據(jù)的頁面可以按需重新用于其他用途(例如,應(yīng)用程序)。
    的頭像 發(fā)表于 01-16 10:04 ?207次閱讀

    Linux下如何管理虛擬內(nèi)存 使用虛擬內(nèi)存時(shí)的常見問題

    在Linux系統(tǒng)中,虛擬內(nèi)存管理是操作系統(tǒng)內(nèi)核的一個重要功能,負(fù)責(zé)管理物理內(nèi)存和磁盤上的交換空間。以下是對Linux下如何管理虛擬內(nèi)存以及使用虛擬內(nèi)
    的頭像 發(fā)表于 12-04 09:19 ?616次閱讀

    虛擬內(nèi)存不足如何解決 虛擬內(nèi)存和物理內(nèi)存的區(qū)別

    虛擬內(nèi)存不足的解決方案 虛擬內(nèi)存不足是計(jì)算機(jī)用戶經(jīng)常遇到的問題,尤其是在運(yùn)行大型軟件或多任務(wù)處理時(shí)。以下是一些解決虛擬內(nèi)存不足問題的方法: 增加物理內(nèi)存(RAM) : 這是最直接的解決
    的頭像 發(fā)表于 12-04 09:14 ?547次閱讀

    邏輯內(nèi)存和物理內(nèi)存的區(qū)別

    邏輯內(nèi)存和物理內(nèi)存是計(jì)算機(jī)系統(tǒng)中兩個重要的概念,它們在計(jì)算機(jī)的運(yùn)行和數(shù)據(jù)處理中起著至關(guān)重要的作用。 1. 物理內(nèi)存(Physical Memory) 物理內(nèi)存,也稱為RAM(Rando
    的頭像 發(fā)表于 09-27 15:38 ?900次閱讀

    內(nèi)存管理的硬件結(jié)構(gòu)

    常見的內(nèi)存分配函數(shù)有malloc,mmap等,但大家有沒有想過,這些函數(shù)在內(nèi)核中是怎么實(shí)現(xiàn)的?換句話說,Linux內(nèi)核內(nèi)存管理是怎么實(shí)現(xiàn)的?
    的頭像 發(fā)表于 09-04 14:28 ?381次閱讀
    <b class='flag-5'>內(nèi)存</b>管理的硬件結(jié)構(gòu)

    操作系統(tǒng)的內(nèi)存布局介紹

    32位操作系統(tǒng)的內(nèi)存布局很經(jīng)典,很多書籍都是以32位系統(tǒng)為例子去講解的。32位的系統(tǒng)可訪問的地址空間為4GB,用戶空間為1GB ~ 3GB,內(nèi)核空間為3GB ~ 4GB。
    的頭像 發(fā)表于 08-07 15:47 ?447次閱讀
    操作系統(tǒng)的<b class='flag-5'>內(nèi)存</b><b class='flag-5'>布局</b>介紹

    ESP-IDF內(nèi)核中的內(nèi)存管理如何驗(yàn)證?

    請教一下,ESP-IDF 內(nèi)核中的內(nèi)存管理如何驗(yàn)證
    發(fā)表于 06-19 06:30

    臺灣地區(qū)DRAM內(nèi)存產(chǎn)能受地震影響停止報(bào)價(jià)

    報(bào)告顯示,美光在臺灣擁有豐富的產(chǎn)能布局,包含位于新北林口及臺中的工廠,主要生產(chǎn)尖端的 1-beta 內(nèi)存產(chǎn)品以及預(yù)定將陸續(xù)推出的 1-gamma 制程內(nèi)存。
    的頭像 發(fā)表于 04-07 15:19 ?552次閱讀

    微軟發(fā)布Linux內(nèi)核Rust模塊優(yōu)化補(bǔ)丁

    在此之前,Linux 內(nèi)核中要想實(shí)現(xiàn)模塊初始化,必須先創(chuàng)建一個實(shí)例,再將其移至特定內(nèi)存空間。然而,經(jīng)過新補(bǔ)丁調(diào)整后,各模塊可直接在預(yù)設(shè)定好的內(nèi)存地址上完成初始化工作。
    的頭像 發(fā)表于 04-02 15:11 ?494次閱讀

    linux內(nèi)核常用調(diào)優(yōu)參數(shù)

     1. vm.swappiness:該參數(shù)控制系統(tǒng)在內(nèi)存不足時(shí),內(nèi)核將頁面交換到磁盤的程度。默認(rèn)值為60,建議值為10-30。   2. vm.overcommit_memory:該參數(shù)控制系統(tǒng)是否允許超額分配內(nèi)存。默認(rèn)值
    的頭像 發(fā)表于 04-01 10:31 ?2080次閱讀

    瑞薩推出采用自研CPU內(nèi)核的通用32位RISC-V MCU 加強(qiáng)RISC-V生態(tài)系統(tǒng)布局

    瑞薩推出采用自研CPU內(nèi)核的通用32位RISC-V MCU 加強(qiáng)RISC-V生態(tài)系統(tǒng)布局 RISC-V MCU為開發(fā)人員帶來低功耗、高性能的全新選擇以及全面工具鏈支持。 全球半導(dǎo)體解決方案供應(yīng)商瑞薩
    發(fā)表于 03-28 19:00 ?625次閱讀

    什么是HBM3E內(nèi)存?Rambus HBM3E/3內(nèi)存控制器內(nèi)核

    Rambus HBM3E/3 內(nèi)存控制器內(nèi)核針對高帶寬和低延遲進(jìn)行了優(yōu)化,以緊湊的外形和高能效的封裝為人工智能訓(xùn)練提供了最大的性能和靈活性。
    發(fā)表于 03-20 14:12 ?2755次閱讀
    什么是HBM3E<b class='flag-5'>內(nèi)存</b>?Rambus HBM3E/3<b class='flag-5'>內(nèi)存</b>控制器<b class='flag-5'>內(nèi)核</b>

    在TC387微控制器上實(shí)現(xiàn)內(nèi)存映射,負(fù)載增加的原因是什么?

    我正在 TC387 微控制器上實(shí)現(xiàn)內(nèi)存映射。 關(guān)于內(nèi)存映射,在 Linker 腳本中定義了新區(qū)域,并將數(shù)據(jù)映射到這些區(qū)域。 從功能上看,在有內(nèi)存映射和沒有內(nèi)存映射的情況下,
    發(fā)表于 03-04 07:43

    Linux內(nèi)核內(nèi)存管理之內(nèi)核非連續(xù)物理內(nèi)存分配

    的主要優(yōu)點(diǎn)是避免了外部碎片,而缺點(diǎn)是需要修改內(nèi)核頁表。顯然,非連續(xù)內(nèi)存區(qū)域的大小必須是4096的倍數(shù)。Linux使用非連續(xù)物理內(nèi)存區(qū)的場景有幾種:(1)為swap區(qū)分配數(shù)據(jù)結(jié)構(gòu);(2)為模塊分配空間
    的頭像 發(fā)表于 02-23 09:44 ?1065次閱讀
    Linux<b class='flag-5'>內(nèi)核</b><b class='flag-5'>內(nèi)存</b>管理之<b class='flag-5'>內(nèi)核</b>非連續(xù)物理<b class='flag-5'>內(nèi)存</b>分配

    Linux內(nèi)核內(nèi)存管理之ZONE內(nèi)存分配器

    內(nèi)核中使用ZONE分配器滿足內(nèi)存分配請求。該分配器必須具有足夠的空閑頁幀,以便滿足各種內(nèi)存大小請求。
    的頭像 發(fā)表于 02-21 09:29 ?939次閱讀