




下載本文檔
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、內存管理區(structpage)前面已經提到,物理內存被劃分為三個區來管理,它們是ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM每個區都用structzone_struct結構來表示,定義于include/linux/mmzone.htypedefstructzone_struct/*Commonlyaccessedfields:*/spinlock_tlock;unsignedlongfree_pages;unsignedlongpages_min,pages_low,pages_high;intneed_balance;/* freeareasofdifferents
2、izes* /free_area_tfree_areaMAX_ORDER;/* Discontigmemorysupportfields.* /structpglist_data*zone_pgdat;structpage*zone_mem_map;unsignedlongzone_start_paddr;unsignedlongzone_start_mapnr;/* rarelyusedfields:*/charname;unsignedlongsize;zone_t;#defineZONE_DMA0#defineZONE_NORMAL1#defineZONE_HIGHMEM2#define
3、MAX_NR_ZONES3對structzone_struct結構中每個域的描述如下:lock:用來保證對該結構中其它域的串行訪問free_pages:在這個區中現有空閑頁的個數pages_min、pages_low及pages_high是對這個區最少、此少及最多頁面個數的描述need_balance:與kswapd合在一起使用free_area:在伙伴分配系統中的位圖數組和頁面鏈表zone_pgdat:本管理區所在的存儲節點zone_mem_map:該管理區的內存映射表zone_start_paddr:該管理區的起始物理地址zone_start_mapnr:在mem_map中的索引(或下標)
4、name:該管理區的名字size:該管理區物理內存總的大小其中,free_area_t定義為:#difineMAX_ORDER10typestructfree_area_structstructlist_headfree_listunsignedint*mapfree_area_t因此,zone一_struct結構中的free_areaMAX_ORDER是一組“空閑區間”鏈表。 為什么要定義一組而不是一個空閑隊列呢?這是因為常常需要成塊地在物理空間分配連續的多個頁面, 所以要按塊的大小分別加以管理。因此,在管理區數據結構中既要有一個隊列來保持一些離散(連續長度為1)的物理頁面,還要有一個隊列來
5、保持一些連續長度為2的頁面塊以及連續長度為4、8、16、直至2MAX_ORDER(即4M字節)的隊列。如前所述,內存中每個物理頁面都有一個structpage結構,位于include/linux/mm.h,該結構包含了對物理頁面進行管理的所有信息,下面給由具體描述:typedefstructpagestructlist_headlist;structaddress_space*mapping;unsignedlongindex;structpage*next_hash;atomictcount;unsignedlongflags;structlist_headlru;wait_queue_he
6、ad_twait;structpage*pprev_hash;structbuffer_head*buffers;void*virtual;structzone_struct*zone;)mem_map_t;對每個域的描述如下:list:指向鏈表中的下一頁mapping:用來指定我們正在映射的索引節點(inode)index:在映射表中的偏移next_hash:指向頁高速緩存哈希表中下一個共享的頁count:引用這個頁的個數flags:頁面各種不同的屬性lru:用在active_list中wait:等待這一頁的頁隊列pprev_hash:與next_hash相對應buffers:把緩沖區映射到
7、一個磁盤塊zone:頁所在的內存管理區與內存管理區相關的三個主要函數為:build_zonelists()函數mem_init()函數1.free_area_init()函數這個函數用來初始化內存管理區并創建內存映射表,定義于mm/page_alloc.c中。函數原型為:voidfree_area_init(unsignedlong*zones_size);voidfree_area_init_core(intnid,pg_data_t*pgdat,structpage*gmap,unsignedlong*zones_size,unsignedlongzone_start_paddr,unsi
8、gnedlong*zholes_size,structpage*lmem_map);free_area_init()為封裝函數,而free_area_init_core()為真正實現的函數,對該函數詳細描述如下:structpage*p;unsignedlongi,j;unsignedlongmap_size;unsignedlongtotalpages,offset,realtotalpages;constunsignedlongzone_required_alignment=1UL<<(MAX_ORDER-1);if(zone_start_paddr&a
9、mp;PAGE_MASK)BUG();檢查該管理區的起始地址是否是一個頁的邊界。totalpages=0;for(i=0;i<MAX_NR_ZONES;i+)totalpages+=size;計算本存儲節點中頁面的個數。realtotalpages=totalpages;if(zholes_size)for(i=0;i<MAX_NR_ZONES;i+)realtotalpages-=zholes_sizei;printk(Onnode%dtotalpages:%lun,nid,realtotalpages);打印除空洞以外的實際頁面數。INIT_LIST_HEAD(
10、&active_list);INIT_LIST_HEAD(&inactive_list);初始化循環鏈表。/* Somearchitectures(withlotsofmemanddiscontinousmemory*maps)havetosearchforagoodmem_maparea:*Fordiscontigmem,theconceptualmemmaparraystartsfrom*PAGE_OFFSET,weneedtoaligntheactualarrayontoamemmap*boundary,sothatMAP_NRworks.*/map_si
11、ze=(totalpages+1)*sizeof(structpage);if(lmem_map=(structpage*)0)lmem_map=(structpage*)(PAGE_OFFSET+MAP_ALIGN(unsignedlong)lmem_map-PAGE_OFFSET);給局部內存(即本節點中的內存)映射分配空間, 并在sizeof(mem_map_t)邊界上對齊它。*gmap=pgdat->node_mem_map=lmem_map;pgdat->node_size=totalpages;pgdat->node_start_paddr
12、=zone_start_paddr;pgdat->node_start_mapnr=(lmem_map-mem_map);pgdat->nr_zones=0;初始化本節點中的域。/*Initiallyallpagesarereserved-freeonesarefreed*upbyfree_all_bootmem()oncetheearlybootprocessis*done.*/for(p=lmem_map;p<lmem_map+totalpages;p+)SetPageReserved(p);init_waitqueue_head(&
13、;p->wait);memlist_init(&p->list);仔細檢查所有的頁,并進行如下操作:把頁的使用計數(count域)置為0。把頁標記為保留。初始化該頁的等待隊列。初始化鏈表指針。offset=lmem_map-mem_map;變量mem_map是類型為structpages的全局稀疏矩陣。mem_map下標的起始值取決于第一個節點的第一個管理區。如果第一個管理區的起始地址為0,則下標就從0開始,并且與物理頁面號相對應,也就是說,頁面號就是mem_map的下標。每一個管理區都有自己的映射表,存放在zone_mem_map中,每個管理區又被
14、映射到它所在的節點node_mem_map中, 而每個節點又被映射到管理全局內存的mem_map中。在上面的這行代碼中,offset表示該節點放的內存映射表在全局mem_map中的入口點(下標)。在這里,offset為0,因為在i386上,只有一個節點。for(j=0;j<MAX_NR_ZONES;j+)這個循環對zone的域進行初始化。zone_t*zone=pgdat->node_zones+j;unsignedlongmask;unsignedlongsize,realsize;realsize=size=zones_sizej;管理區的實際數據是存放在節點中
15、的,因此,讓指針指向正確的管理區,并獲得該管理區的大小。if(zholes_size)realsize-=zholes_sizej;printk(zone(%lu):%lupages.n,j,size);計算各個區的實際大小,并進行打印。例如,在具有256MB的內存上,上面的輸生為:zone(0):4096pages.zone(1):61440pages.zone(2):0pages.這里,管理區2為0,因為只有256MB的RAM.zone->size=size;zone->name=zone_namesj;zone->lock=SPIN_LOCK_U
16、NLOCKED;zone->zone_pgdat=pgdat;zone->free_pages=0;zone->need_balance=0;初始化管理區中的各個域。if(!size)continue;如果一個管理區的大小為0pgdat->nr_zones=j+1;mask=(realsize/zone_balance_ratioj);if(mask<zone_balance_minj)mask=zone_balance_minj;elseif(mask>zone_balance_maxj)mask=zone_
17、balance_maxj;計算合適的平衡比率zone->pages_min=mask;zone->pages_low=mask*2;zone->pages_high=mask*3;zone->zone_mem_map=mem_map+offset;zone->zone_start_mapnr=offset;zone->zone_start_paddr=zone_start_paddr;設置該管理區中頁面數量的幾個界限,并把在全局變量mem_map中的入口點作為zone_mem_map的初值。 用全局變量mem_
18、map的下標初始化變量zone_start_mapnr。if(zone_start_paddr>>PAGE_SHIFT)&(zone_required_alignment-1)printk(BUG:wrongzonealignment,itwillcrashn);for(i=0;i<size;i+)structpage*page=mem_map+offset+i;page->zone=zone;if(j!=ZONE_HIGHMEM)page->virtual=_va(zone_start_paddr);zon
19、e_start_paddr+=PAGE_SIZE;對該管理區中的每一頁進行處理。首先,把structpage結構中的zone域初始化為指向該管理區(zone),如果這個管理區不是ZONE_HIGHMEM,則設置這一頁的虛地址(即物理地址+PAGE_OFFSET)。也就是說,建立起每一頁物理地址到虛地址的映射。offset+=size;把offset增加size,使它指向mem_map中下一個管理區的起始位置。for(i=0;i+)unsignedlongbitmap_size;memlist_init(&zone->free_areai.free_list);if
20、(i=MAX_ORDER-1)zone->free_areai.map=NULL;break;初始化free_area鏈表,把free_area中最后一個序號的位圖置為NULLo/* Pagebuddysystemusesindex>>(i+1),* whereindexisatmostsize-1.* Theextra+3istorounddowntobyte* size(8bitsperbyteassumption).Thus* weget(size-1)>>(i+4)”asthelastbyte* wecanacces
21、s.* The+1isbecausewewanttoroundthe* byteallocationupratherthandown.So* weshouldhavehada+7beforeweshifted* downbythree.Also,wehavetoaddoneas* weactually_use_thelastbit(its0,n* inclusive,not0,n).* Soweactuallyhad+7+1beforeweshift* downby3.But(n+8)>>3=(n* (modulooverflows,whichwedonothave
22、).*Finally,weLONG_ALIGNbecauseallbitmap* operationsareonlongs.*/bitmap_size=(size-1)>>(i+4);bitmap_size=LONG_ALIGN(bitmap_size+1);zone->free_areai.map=(unsignedlong*)alloc_bootmem_node(pgdat,bitmap_size);計算位圖的大小,然后調用alloc_bootmem_node給位圖分配空間。build_zonelists(pgdat);在節點中為不同的管理區創建鏈
23、表。2.build_zonelists()函數函數原型:staticinlinevoidbuild_zonelists(pg_data_t*pgdat)代碼如下:inti,j,k;for(i=0;i<=GFP_ZONEMASK;i+)zonelist_t*zonelist;zone_t*zone;zonelist=pgdat->node_zonelists+i;memset(zonelist,0,sizeof(*zonelist);獲得節點中指向管理區鏈表的域,并把它初始化為空j=0;k=ZONE_NORMAL;if(i&_GFP_HIGHMEM)k
24、=ZONE_HIGHMEM;if(i&_GFP_DMA)k=ZONE_DMA;把當前管理區掩碼與三個可用管理區掩碼相“與”,獲得一個管理區標識,把它用在下面的switch語句中。switch(k)default:BUG();/*fallthrough:*/caseZONEHIGHMEM:zone=pgdat->node_zones+ZONE_HIGHMEM;if(zone->size)#ifndefCONFIG_HIGHMEMBUG();#endifzonelist->zonesj+=zone;caseZONE_NORMAL:zone=
25、pgdat->node_zones+ZONE_NORMAL;if(zone->size)zonelist->zonesj+=zone;caseZONEDMA:zone=pgdat->node_zones+ZONE_DMA;if(zone->size)zonelist->zonesj+=zone;給定的管理區掩碼指定了優先順序,我們可以用它找到在switch語句中的入口點。如果掩碼為GFP_DMA,管理區鏈表zonelist將僅僅包含DMA管理區,如果為GFP_HIGHMEM,則管理區鏈表中就會依次有ZONE_H
26、IGHMEM、ZONE_NORMAL和ZONE_DMA。zonelist->zonesj+=NULL;用Null結束鏈表。3.mem_init()函數這個函數由start_kernel()調用,以對管理區的分配算法進行進一步的初始化,定義于arch/i386/mm/init.c中,具體解釋如下:intcodesize,reservedpages,datasize,initsize;inttmp;intbad_ppro;if(!mem_map)BUG();#ifdefCONFIG_HIGHMEMhighmem_start_page=mem_map+highstart_pfn;max
27、_mapnr=num_physpages=highend_pfn;如果HIGHMEM被激活,就要獲得HIGHMEM的起始地址和總的頁面數。#elsemax_mapnr=num_physpages=max_low_pfn;#endif否則,頁面數就是常規內存的頁面數high_memory=(void*)_va(max_low_pfn*PAGE_SIZE);獲得低區內存中最后一個頁面的虛地址。/*clearthezero-page*/memset(empty_zero_page,0,PAGE_SIZE);/*thiswillputalllowmemoryontothefreelists*/tota
28、lram_pages+=free_all_bootmem();reservedpages=0;free_all_b00tmem()函數本質上釋放所有的低區內存,從此以后,bootmem不再使用。/*OnlycountreservedRAMpages*/for(tmp=0;tmp<max_low_pfn;tmp+)if(page_is_ram(tmp)&&PageReserved(mem_map+tmp)reservedpages+;對mem_map查找一遍,并統計所保留的頁面數。#ifdefCONFIGHIGHMEMfor(tmp=highstart_pfn;tmp<highend_pfn;tmp+)if(!page_is_ram(tmp)SetPageReserved(page);continue;if(bad_ppro&&page_kills_ppro(tmp)SetPageReserved(page);continue;set_bit(PG_highmem,&page->flag
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025建筑工程監理委托合同
- 2025股權轉讓合同
- 初三學生國旗下演講稿《輕裝上陣迎中考 志存高遠勇拼搏》
- 運維服務管理優化匯報
- 模擬有限責任公司設立登記流程
- 膿胸的護理常規
- 2025年環境監測測驗試題
- 公司財務報銷費用培訓
- 2025年中醫執業醫師考試中藥學知識點總結模版
- 新質生產力日報
- 浙江開放大學2025年《行政復議法》形考作業2答案
- 消防改造協議書范本
- 職業心理健康課件
- 江蘇省南通市2025屆高三三模 地理試題(含答案)
- 年度安全生產月啟動講話稿材料
- 寧波中考社會試題及答案
- 2025年三級安全培訓考試試題及參考答案【完整版】
- 金華市金廈商品混凝土有限公司年產60萬方清潔型預拌混凝土遷建項目環評報告
- 2025年計算機科學與技術考試試題及答案
- 2024年福清市中醫院招聘筆試真題
- 物業經理模擬試題及答案
評論
0/150
提交評論