LINUX 内核代码备忘录
1.
swapper_pg_dir : Global Page Directory (全局頁(yè)目錄,即最頂層頁(yè)目錄,PGD) 的地址
pgd_index(addr): 宏函數(shù),返回PGD包含的項(xiàng)中,地址字段 值為addr的項(xiàng)的索引。
PAGE_OFFSET:宏函數(shù),返回進(jìn)程地址空間(線性地址)中kernel所屬的地址空間的起始地址,x86_32下是0xc0000000
PAGE_SIZE:宏函數(shù),返回頁(yè)大小(4096B或2MB)
max_low_pfn:宏函數(shù),返回一個(gè)物理內(nèi)存的頁(yè)塊號(hào),該頁(yè)塊是最后一個(gè)由kernel直接進(jìn)行 邏輯/物理 映射的頁(yè)塊
set_pmd:宏函數(shù),將值寫(xiě)入PMD(Page Middle Directory)中指定的項(xiàng)
__pmd:宏函數(shù),將一個(gè)無(wú)符號(hào)整數(shù)值轉(zhuǎn)換成PMD表項(xiàng)類(lèi)型,即pmd_t
pgprot_val:宏函數(shù),將一個(gè)無(wú)符號(hào)整數(shù)轉(zhuǎn)換成__prot類(lèi)型,該類(lèi)型保存一個(gè)頁(yè)表/頁(yè)目錄項(xiàng)的保護(hù)標(biāo)志位
__pgprot:宏函數(shù),將一個(gè)__prot類(lèi)型的值轉(zhuǎn)換成一個(gè)無(wú)符號(hào)整數(shù)
?
物理內(nèi)存在4GB以?xún)?nèi)時(shí),kernel重初始化內(nèi)核頁(yè)表的過(guò)程。(此時(shí)為2級(jí)分頁(yè)P(yáng)GD->PTE->PF),由于LINUX內(nèi)核總是使用大頁(yè)面(即一頁(yè)面為2MB或4MB,而非常規(guī)的4096B),
即PTE->PF(共10+12=22位,4MB)不設(shè)置頁(yè)表,而是直接將內(nèi)存看作頁(yè)面。此模式下,PGD共有1024項(xiàng),其中內(nèi)核占768~1023項(xiàng),總計(jì)內(nèi)核尋址空間為256*4MB = 1GB
代碼 pgd = swapper_pg_dir + pgd_index(PAGE_OFFSET); /* 768 */phys_addr = 0x00000000;
while (phys_addr < (max_low_pfn * PAGE_SIZE) ) {
pmd = one_md_table_init(pgd); /* returns pgd itself */
set_pmd(pmd, __pmd(phys_addr | pgprot_val( __pgprot(0x1e3))));
/* 0x1e3 == Present , Accessed ,Dirty, Read/Write, Page Size, Global */
phys_addr += PTRS_PER_PTE * PAGE_SIZE; /* 0x400000 */
++pgd;
}
?
開(kāi)啟PAE(Physical Address Extending)或物理內(nèi)存大于4GB時(shí),kernel重初始化內(nèi)核頁(yè)表的過(guò)程。(此時(shí)為3級(jí)分頁(yè)P(yáng)GD->PMD->PTE->PF),在這種情況下,PTE與PF尋址位數(shù)為9+12=21,即此時(shí)LINUX內(nèi)核使用2MB大小的頁(yè)面。此模式下,PDG共4項(xiàng),其中內(nèi)核占第三項(xiàng),PMG共512項(xiàng),總計(jì)內(nèi)核尋址空間為512*2MB = 1GB
?
代碼 pgd_idx = pgd_index(PAGE_OFFSET); /* 3 */for (i=0; i<pdg_idx; i++)
set_pgd(swapper_pg_dir + i , __pgd( __pa(empty_zero_page) | 0x001) );
/* 0x001 == Present */
pgd = swapper_pg_dir + pgd_idx;
phys_addr = 0x00000000;
for( ; i<PTRS_PER_PGD; ++i , ++pgd) {
pmd = (pmd_t*) alloc_bootmem_low_pages(PAGE_SIZE);
set_pgd(pgd, __pa(pmd) | 0x001); /* 0x001 == Present */
if( phys_addr < max_low_pfn * PAGE_SIZE)
for(j=0; j<PTRS_PER_PMD && hys_addr < max_low_pfn * PAGE_SIZE; ++j) {
set_pmd(pmd, __pmd(phys_addr | pgprot_val(__pgprot(0x1e3))));
/* 0x1e3 == Present , Accessed ,Dirty, Read/Write, Page Size, Global */
phys_addr += PTRS_PER_PMD * PAGE_SIZE;
}
}
swapper_pg_dir[0] = swapper_pg_dir[pgd_idx];
轉(zhuǎn)載于:https://www.cnblogs.com/klzwj1988/archive/2010/12/14/1905435.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的LINUX 内核代码备忘录的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: RMI 说明
- 下一篇: linux 其他常用命令