一、系統(tǒng)調(diào)用mmap
虛擬內(nèi)存區(qū)域使用起始地址和結(jié)束地址描述,鏈表按起始地址遞增排序。兩系統(tǒng)調(diào)用區(qū)別:mmap指定的偏移的單位是字節(jié),而mmap2指定的偏移的單位是頁。ARM64架構(gòu)實(shí)現(xiàn)系統(tǒng)調(diào)用mmap。
二、系統(tǒng)調(diào)用munmap
系統(tǒng)調(diào)用munmap用來刪除內(nèi)存映射,它有兩個參數(shù):起始地址和長度即可。它的主要工作委托給內(nèi)核源碼文件處理“mm/mmap.c”中的函數(shù)do_munmap。
vm_munmap -->do_munmap -->vma=find_vma(mm,start) -->error=__split_vma(mm,vma,start,0) -->last=find_vma(mm,end) -->interror=__split_vma(mm,last,end,1) -->munlock_vma_pages_all -->detach_vmas_to_be_unmapped -->unmap_region -->arch_unmap -->remove_vma_list
vma = find_vma(mm,start);//根據(jù)起始地址找到要刪除的第一個虛擬內(nèi)存區(qū)域vma
error = __split_vma(mm,vma,start,0);//如果只刪除虛擬內(nèi)存區(qū)域vma的部分,那么分裂虛擬內(nèi)存區(qū)域vma
last = find_vma(mm,end);//根據(jù)結(jié)束地址找到要刪除的最后一個虛擬內(nèi)存區(qū)域vma
int error = __split_vma(mm,last,end,1);//如果只刪除虛擬內(nèi)存區(qū)域last的一部分,那么分裂虛擬內(nèi)存區(qū)域vma
munlock_vma_pages_all;//針對所有刪除目標(biāo),如果虛擬內(nèi)存區(qū)域被鎖定在內(nèi)存中(不允許換出到交換區(qū)),調(diào)用函數(shù)解除鎖定
detach_vmas_to_be_unmapped;//調(diào)用此函數(shù),把所有刪除目標(biāo)從進(jìn)程虛擬內(nèi)存區(qū)域鏈表和樹中刪除,單獨(dú)組成一條臨時(shí)鏈表
unmap_region;//調(diào)用此函數(shù),針對所有刪除目標(biāo),在進(jìn)程的頁表中刪除映射,并且從處理器的頁表緩存中刪除映射
arch_unmap;//調(diào)用此函數(shù)執(zhí)行處理器架構(gòu)特定的處理操作
remove_vma_list;//調(diào)用此函數(shù),刪除所有目標(biāo)
三、物理內(nèi)存組織結(jié)構(gòu)
1.體系結(jié)構(gòu)
目前多處理器系統(tǒng)有兩種體系結(jié)構(gòu):
非一致內(nèi)存訪問(Non-Unit Memory Access,NUMA):指內(nèi)存被劃分成多個內(nèi)存節(jié)點(diǎn)的多處理器系統(tǒng)。訪問一個內(nèi)存節(jié)點(diǎn)花費(fèi)的時(shí)間取決于處理器和內(nèi)存節(jié)點(diǎn)的距離。
對稱多處理器(Sysmmetric Muti-Processor,SMP):即一致內(nèi)存訪問(Uniform Memory Access,UMA),所有處理器訪問內(nèi)存花費(fèi)的時(shí)間是相同的。
2.內(nèi)存模型
內(nèi)存模型是從處理器角度看到的物理內(nèi)存分布,內(nèi)核管理不同內(nèi)存模型的方式存在差異。內(nèi)存管理子系統(tǒng)支持3種內(nèi)存模型:
平坦內(nèi)存(Flat Memory):內(nèi)存的物理地址空間是連續(xù)的,沒有空洞。
不連續(xù)內(nèi)存(Discontiguous Memory):內(nèi)存的物理地址空間存在空洞,這種模型可以高效地處理空洞。
稀疏內(nèi)存(Space Memory):內(nèi)存物理地址空間存在空洞,如果要支持內(nèi)存熱插拔,只能選擇稀疏內(nèi)存模型。
3.三級結(jié)構(gòu)
內(nèi)存管理子系統(tǒng)使用節(jié)點(diǎn)(node)、區(qū)域(zone)、頁(page)三級結(jié)構(gòu)描述物理內(nèi)存。
3.1 內(nèi)存節(jié)點(diǎn)--->分為兩種情況
NUMA體系的內(nèi)存節(jié)點(diǎn),根據(jù)處理器和內(nèi)存距離劃分;
在具有不連續(xù)內(nèi)存的NUMA系統(tǒng)中,表示比區(qū)域的級別更高的內(nèi)存區(qū)域,根據(jù)物理地址是否連續(xù),每塊物理地址連續(xù)的內(nèi)存是一個內(nèi)存節(jié)點(diǎn)。
內(nèi)存節(jié)點(diǎn)使用結(jié)構(gòu)體pglist_data描述內(nèi)存布局
Linux內(nèi)核源碼如下:
typedefstructpglist_data{ structzonenode_zones[MAX_NR_ZONES];//內(nèi)存區(qū)域數(shù)組 structzonelistnode_zonelists[MAX_ZONELISTS];//備用區(qū)域列表 intnr_zones;//該節(jié)點(diǎn)包含內(nèi)存區(qū)域數(shù)量 #ifdefCONFIG_FLAT_NODE_MEM_MAP/*means!SPARSEMEM*///除了稀疏內(nèi)存模型以外 structpage*node_mem_map;//頁描述符數(shù)組 #ifdefCONFIG_PAGE_EXTENSION structpage_ext*node_page_ext;//頁的擴(kuò)展屬性 #endif #endif #ifndefCONFIG_NO_BOOTMEM structbootmem_data*bdata; #endif #ifdefCONFIG_MEMORY_HOTPLUG /* *Mustbeheldanytimeyouexpectnode_start_pfn,node_present_pages *ornode_spanned_pagesstayconstant.Holdingthiswillalso *guaranteethatanypfn_valid()staysthatway. * *pgdat_resize_lock()andpgdat_resize_unlock()areprovidedto *manipulatenode_size_lockwithoutcheckingforCONFIG_MEMORY_HOTPLUG. * *Nestsabovezone->lockandzone->span_seqlock */ spinlock_tnode_size_lock; #endif unsignedlongnode_start_pfn;//該節(jié)點(diǎn)的起始物理頁號 unsignedlongnode_present_pages;/*物理頁總數(shù)*/ unsignedlongnode_spanned_pages;/*物理頁范圍總的長度,包括空間*/ intnode_id;//節(jié)點(diǎn)標(biāo)識符 wait_queue_head_tkswapd_wait; wait_queue_head_tpfmemalloc_wait; structtask_struct*kswapd;/*Protectedby mem_hotplug_begin/end()*/ intkswapd_max_order; enumzone_typeclasszone_idx; #ifdefCONFIG_NUMA_BALANCING /*Lockserializingthemigrateratelimitingwindow*/ spinlock_tnumabalancing_migrate_lock; /*Ratelimitingtimeinterval*/ unsignedlongnumabalancing_migrate_next_window; /*Numberofpagesmigratedduringtheratelimitingtimeinterval*/ unsignedlongnumabalancing_migrate_nr_pages; #endif #ifdefCONFIG_DEFERRED_STRUCT_PAGE_INIT /* *Ifmemoryinitialisationonlargemachinesisdeferredthenthis *isthefirstPFNthatneedstobeinitialised. */ unsignedlongfirst_deferred_pfn; #endif/*CONFIG_DEFERRED_STRUCT_PAGE_INIT*/ }pg_data_t;
node_mem_map此成員指向頁描述符數(shù)組,每個物理頁對應(yīng)一個頁描述符。
Node是內(nèi)存管理最頂層的結(jié)構(gòu),在NUMA架構(gòu)下,CPU平均劃分為多個Node,每個Node有自己的內(nèi)存控制器及內(nèi)存插槽。CPU訪問自己Node上內(nèi)存速度快,而訪問其他CPU所關(guān)聯(lián)Node的內(nèi)存速度慢。UMA被當(dāng)作只一個Node的NUMA系統(tǒng)。
3.2 內(nèi)存區(qū)域(zone)
內(nèi)存節(jié)點(diǎn)被劃分為內(nèi)存區(qū)域。Linux內(nèi)核源碼分析:include/linux/mmzone.h
enumzone_type{ #ifdefCONFIG_ZONE_DMA /* *ZONE_DMAisusedwhentherearedevicesthatarenotable *todoDMAtoallofaddressablememory(ZONE_NORMAL).Thenwe *carveouttheportionofmemorythatisneededforthesedevices. *Therangeisarchspecific. * *Someexamples * *ArchitectureLimit *--------------------------- *parisc,ia64,sparc<4G ??*?s390???<2G ??*?arm???Various ??*?alpha??Unlimited?or?0-16MB. ??* ??*?i386,?x86_64?and?multiple?other?arches ??*????<16M. ??*/ ?ZONE_DMA,?/*Direct Memory Access,直接內(nèi)存訪問。如果有些設(shè)備不能直接訪問所有內(nèi)存,需要使用DMA區(qū)域。ISA*/ #endif #ifdef?CONFIG_ZONE_DMA32 ?/* ??*?x86_64?needs?two?ZONE_DMAs?because?it?supports?devices?that?are ??*?only?able?to?do?DMA?to?the?lower?16M?but?also?32?bit?devices?that ??*?can?only?do?DMA?areas?below?4G. ??*/ ?ZONE_DMA32,?/*?64位系統(tǒng),如果既要支持能直接訪問16MB以下內(nèi)存設(shè)備,又要支持能直接訪問4GB以下內(nèi)存的32設(shè)備,必須使用此DMA32區(qū)域*/ #endif ?/* ??*?Normal?addressable?memory?is?in?ZONE_NORMAL.?DMA?operations?can?be ??*?performed?on?pages?in?ZONE_NORMAL?if?the?DMA?devices?support ??*?transfers?to?all?addressable?memory. ??*/ ?/*普通內(nèi)存區(qū)域: ?直接映射到內(nèi)核虛擬地址空間的內(nèi)存區(qū)域,又稱為普通區(qū)域,又稱為直接映射區(qū)域,又稱為線性映射區(qū)域*/ ?ZONE_NORMAL, #ifdef?CONFIG_HIGHMEM ?/* ??*?A?memory?area?that?is?only?addressable?by?the?kernel?through ??*?mapping?portions?into?its?own?address?space.?This?is?for?example ??*?used?by?i386?to?allow?the?kernel?to?address?the?memory?beyond ??*?900MB.?The?kernel?will?set?up?special?mappings?(page ??*?table?entries?on?i386)?for?each?page?that?the?kernel?needs?to ??*?access. ??*/ ?/*高端內(nèi)存區(qū)域: ?此區(qū)域是32位時(shí)代的產(chǎn)物,內(nèi)核和用戶地址空間按1:3劃分, ?內(nèi)核地址空間只有1GB,不能把1GB以上內(nèi)存直接映射到該地址*/ ?ZONE_HIGHMEM, #endif ?/*可移動區(qū)域: ?它是一個偽內(nèi)存區(qū)域,用來防止內(nèi)存碎片*/ ?ZONE_MOVABLE, #ifdef?CONFIG_ZONE_DEVICE ?/*設(shè)備區(qū)域: ?為支持持久內(nèi)存熱插拔增加的內(nèi)存區(qū)域,每一個內(nèi)存區(qū)域用一個zone結(jié)構(gòu)體來描述*/ ?ZONE_DEVICE, #endif ?__MAX_NR_ZONES };
每個內(nèi)存區(qū)域使用一個zone結(jié)構(gòu)體描述,如下為主要成員:
structzone{ /*Read-mostlyfields*/ /*zonewatermarks,accesswith*_wmark_pages(zone)macros*/ unsignedlongwatermark[NR_WMARK];//頁分配器使用的水線 unsignedlongnr_reserved_highatomic; /* *Wedon'tknowifthememorythatwe'regoingtoallocatewillbe *freeableor/anditwillbereleasedeventually,sotoavoidtotally *wastingseveralGBoframwemustreservesomeofthelowerzone *memory(otherwisewerisktorunOOMonthelowerzonesdespite *therebeingtonsoffreeableramonthehigherzones).Thisarrayis *recalculatedatruntimeifthesysctl_lowmem_reserve_ratiosysctl *changes. */ longlowmem_reserve[MAX_NR_ZONES];//頁分配器使用,當(dāng)前區(qū)域保留多少頁不能借給高的區(qū)域類型 #ifdefCONFIG_NUMA intnode; #endif /* *ThetargetratioofACTIVE_ANONtoINACTIVE_ANONpageson *thiszone'sLRU.Maintainedbythepageoutcode. */ unsignedintinactive_ratio; structpglist_data*zone_pgdat;//指向內(nèi)存節(jié)點(diǎn)的pglist_data實(shí)例 structper_cpu_pageset__percpu*pageset;//每處理頁集合 /* *Thisisaper-zonereserveofpagesthatshouldnotbe *considereddirtyablememory. */ unsignedlongdirty_balance_reserve; #ifndefCONFIG_SPARSEMEM /* *Flagsforapageblock_nr_pagesblock.Seepageblock-flags.h. *InSPARSEMEM,thismapisstoredinstructmem_section */ unsignedlong*pageblock_flags; #endif/*CONFIG_SPARSEMEM*/ #ifdefCONFIG_NUMA /* *zonereclaimbecomesactiveifmoreunmappedpagesexist. */ unsignedlongmin_unmapped_pages; unsignedlongmin_slab_pages; #endif/*CONFIG_NUMA*/ /*zone_start_pfn==zone_start_paddr>>PAGE_SHIFT*/ unsignedlongzone_start_pfn;//當(dāng)前區(qū)域的起始物理頁號 /* *spanned_pagesisthetotalpagesspannedbythezone,including *holes,whichiscalculatedas: *spanned_pages=zone_end_pfn-zone_start_pfn; * *present_pagesisphysicalpagesexistingwithinthezone,which *iscalculatedas: *present_pages=spanned_pages-absent_pages(pagesinholes); * *managed_pagesispresentpagesmanagedbythebuddysystem,which *iscalculatedas(reserved_pagesincludespagesallocatedbythe *bootmemallocator): *managed_pages=present_pages-reserved_pages; * *Sopresent_pagesmaybeusedbymemoryhotplugormemorypower *managementlogictofigureoutunmanagedpagesbychecking *(present_pages-managed_pages).Andmanaged_pagesshouldbeused *bypageallocatorandvmscannertocalculateallkindsofwatermarks *andthresholds. * *Lockingrules: * *zone_start_pfnandspanned_pagesareprotectedbyspan_seqlock. *Itisaseqlockbecauseithastobereadoutsideofzone->lock, *anditisdoneinthemainallocatorpath.But,itiswritten *quiteinfrequently. * *Thespan_seqlockisdeclaredalongwithzone->lockbecauseitis *frequentlyreadinproximitytozone->lock.It'sgoodto *givethemachanceofbeinginthesamecacheline. * *Writeaccesstopresent_pagesatruntimeshouldbeprotectedby *mem_hotplug_begin/end().Anyreaderwhocan'ttolerantdriftof *present_pagesshouldget_online_mems()togetastablevalue. * *Readaccesstomanaged_pagesshouldbesafebecauseit'sunsigned *long.Writeaccesstozone->managed_pagesandtotalram_pagesare *protectedbymanaged_page_count_lockatruntime.Idealyonly *adjust_managed_page_count()shouldbeusedinsteadofdirectly *touchingzone->managed_pagesandtotalram_pages. */ unsignedlongmanaged_pages;//伙伴分配器管理的物理頁的數(shù)量 unsignedlongspanned_pages;//當(dāng)前區(qū)域跨越的總頁數(shù),包括空洞 unsignedlongpresent_pages;//當(dāng)前區(qū)域存在的物理頁的數(shù)量,不包括空洞 constchar*name;//區(qū)域名稱 #ifdefCONFIG_MEMORY_ISOLATION /* *Numberofisolatedpageblock.Itisusedtosolveincorrect *freepagecountingproblemduetoracyretrievingmigratetype *ofpageblock.Protectedbyzone->lock. */ unsignedlongnr_isolate_pageblock; #endif #ifdefCONFIG_MEMORY_HOTPLUG /*seespanned/present_pagesformoredescription*/ seqlock_tspan_seqlock; #endif /* *wait_table--thearrayholdingthehashtable *wait_table_hash_nr_entries--thesizeofthehashtablearray *wait_table_bits--wait_table_size==(1<
3.3 物理頁
頁是內(nèi)存管理當(dāng)中最小單位,頁面中的內(nèi)存其物理地址是連續(xù)的,每個物理頁由struct page描述。為了節(jié)省內(nèi)存,struct page是個聯(lián)合體。
頁,又稱為頁幀,在內(nèi)核當(dāng)中,內(nèi)存管理單元MMU(負(fù)責(zé)虛擬地址和物理地址轉(zhuǎn)換的硬件)是把物理頁page作為內(nèi)存管理的基本單位。體系結(jié)構(gòu)不同,支持的頁大小也不同。(32位體系結(jié)構(gòu)支持4KB的頁、64位體系結(jié)構(gòu)支持8KB的頁、MIPS64架構(gòu)體系支持16KB的頁)
審核編輯:湯梓紅
-
ARM
+關(guān)注
關(guān)注
134文章
9178瀏覽量
369372 -
內(nèi)核
+關(guān)注
關(guān)注
3文章
1383瀏覽量
40439 -
Linux
+關(guān)注
關(guān)注
87文章
11350瀏覽量
210477 -
物理內(nèi)存
+關(guān)注
關(guān)注
0文章
11瀏覽量
8485 -
虛擬內(nèi)存
+關(guān)注
關(guān)注
0文章
77瀏覽量
8091
原文標(biāo)題:Linux內(nèi)核 | 物理內(nèi)存組織結(jié)構(gòu)
文章出處:【微信號:嵌入式開發(fā)AIoT,微信公眾號:嵌入式開發(fā)AIoT】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
一文詳解Linux內(nèi)核源碼組織結(jié)構(gòu)
Linux的內(nèi)存管理是什么,Linux的內(nèi)存管理詳解
![<b class='flag-5'>Linux</b>的<b class='flag-5'>內(nèi)存</b>管理是什么,<b class='flag-5'>Linux</b>的<b class='flag-5'>內(nèi)存</b>管理詳解](https://file.elecfans.com//web2/M00/43/01/pYYBAGJ7h8qAfJe-AAA3U8e_SDc509.jpg)
走進(jìn)Linux內(nèi)存系統(tǒng)探尋內(nèi)存管理的機(jī)制和奧秘
Linux內(nèi)核內(nèi)存泄漏怎么辦
Linux內(nèi)存相關(guān)知識科普
![<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)存</b>相關(guān)知識科普](https://file1.elecfans.com/web2/M00/8D/BB/wKgaomS_bzuAIY8XAAD0agexI4g205.jpg)
Linux內(nèi)核的物理內(nèi)存組織結(jié)構(gòu)詳解
![<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>的<b class='flag-5'>物理</b><b class='flag-5'>內(nèi)存</b><b class='flag-5'>組織</b><b class='flag-5'>結(jié)構(gòu)</b>詳解](https://file1.elecfans.com/web2/M00/94/1E/wKgaomTjEuuAHt-yAAAsspOszxo835.jpg)
Linux內(nèi)核的內(nèi)存管理詳解
![<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>的<b class='flag-5'>內(nèi)存</b>管理詳解](https://file1.elecfans.com/web2/M00/A2/74/wKgaomTwN4yAXOQuAAJj6uZ89wI389.png)
Linux內(nèi)核內(nèi)存管理之內(nèi)核非連續(xù)物理內(nèi)存分配
![<b class='flag-5'>Linux</b><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'>物理</b><b class='flag-5'>內(nèi)存</b>分配](https://file1.elecfans.com/web2/M00/C1/9D/wKgaomXX-KCADAsrAAAaZXMwKKg445.png)
Linux內(nèi)核地址映射模型與Linux內(nèi)核高端內(nèi)存詳解
![<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>地址映射模型與<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>高端<b class='flag-5'>內(nèi)存</b>詳解](https://file1.elecfans.com//web2/M00/A7/46/wKgZomUMQ36ANQMWAAATFoFa5Ok330.png)
帶你了解Linux內(nèi)核體系結(jié)構(gòu)
Linux內(nèi)核結(jié)構(gòu)詳解
如何避免Linux的物理內(nèi)存碎片化
![如何避免<b class='flag-5'>Linux</b>的<b class='flag-5'>物理</b><b class='flag-5'>內(nèi)存</b>碎片化](https://file.elecfans.com/web1/M00/4F/C9/o4YBAFri43yAUBH3AAAeiuQDZ2o967.png)
Linux0.11-內(nèi)存組織和進(jìn)程結(jié)構(gòu)
![<b class='flag-5'>Linux</b>0.11-<b class='flag-5'>內(nèi)存</b><b class='flag-5'>組織</b>和進(jìn)程<b class='flag-5'>結(jié)構(gòu)</b>](https://file.elecfans.com/web1/M00/91/D1/o4YBAFzbhJGAdyYPAALxn8YMMYc148.png)
一文解析Linux內(nèi)存系統(tǒng)
![一文解析<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)存</b>系統(tǒng)](https://file.elecfans.com/web1/M00/C5/58/o4YBAF9NtPaAPl16AAAUaU8hg9k121.jpg)
STM32MP157 Linux系統(tǒng)移植開發(fā)篇7:Linux內(nèi)核目錄結(jié)構(gòu)詳解
![STM32MP157 <b class='flag-5'>Linux</b>系統(tǒng)移植開發(fā)篇7:<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>目錄<b class='flag-5'>結(jié)構(gòu)</b>詳解](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評論