- 論壇徽章:
- 0
|
本帖最后由 cluter 于 2011-02-20 22:29 編輯
Non-PAE模式:
在non-PAE模式下,x86系統(tǒng)采用2-level頁(yè)表。
相關(guān)的宏定義如下:
在Pgtable-2level_types.h文件中
//頁(yè)全局目錄的掩碼
#define PGDIR_SHIFT 22
//頁(yè)全局目錄1024項(xiàng)
#define PTRS_PER_PGD 1024
//頁(yè)表1024項(xiàng)
#define PTRS_PER_PTE 1024
在Page_32_types.h文件中
//定義內(nèi)核大小為512MB---只是限制內(nèi)核最大512MB
#define KERNEL_IMAGE_SIZE (512 * 1024 * 1024)
代碼分析:
1 相關(guān)的宏定義
//頁(yè)表的大小=頁(yè)數(shù)量 / 每個(gè)頁(yè)表中頁(yè)目錄的個(gè)數(shù)
#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
//映射內(nèi)核線性地址空間需要的內(nèi)存大小
MAPPING_BEYOND_END = \
PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
//內(nèi)核頁(yè)數(shù)量==(內(nèi)核的大小+映射內(nèi)核線性地址空間的頁(yè)表的大小) / 頁(yè)大小
//可以看出這個(gè)是 worst-case 下需要的內(nèi)核頁(yè)數(shù)量
KERNEL_PAGES = (KERNEL_IMAGE_SIZE + MAPPING_BEYOND_END)>>PAGE_SHIFT
//INIT_MAP_SIZE=初始化的時(shí)候必須要映射的內(nèi)存大小,也就是上面kernel_pages的大小
INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm
//在brk段 預(yù)留名字為pagetables大小為INIT_MAP_SIZE的空間
RESERVE_BRK(pagetables, INIT_MAP_SIZE)
2 頁(yè)表相關(guān)數(shù)據(jù)的內(nèi)存分配
//為頁(yè)全局目錄(pgd)分配1024*4byte的內(nèi)存空間
ENTRY(swapper_pg_dir)
.fill 1024,4,0
//為固定映射頁(yè)表分配1024*4byte的內(nèi)存空間
swapper_pg_fixmap:
.fill 1024,4,0
//分配一頁(yè)并初始化為0
ENTRY(empty_zero_page)
.fill 4096,1,0
3 臨時(shí)頁(yè)表初始化代碼
//內(nèi)核線性地址開(kāi)始的地方在pgd中的偏移位置
//__PAGE_OFFSET>>12>>10計(jì)算出在pgd中的頁(yè)目錄項(xiàng)index
//(__PAGE_OFFSET>>12>>10)<<2計(jì)算出偏移地址(因?yàn)槊總(gè)頁(yè)目錄項(xiàng)4byte)
page_pde_offset = (__PAGE_OFFSET >> 20);
//把開(kāi)始存放頁(yè)表(page table)的物理地址寫(xiě)入edi
movl $pa(__brk_base), %edi
//把頁(yè)全局目錄(pgd)的物理地址寫(xiě)入edx
movl $pa(swapper_pg_dir), %edx
//把頁(yè)表項(xiàng)(pte)屬性寫(xiě)入eax
movl $PTE_IDENT_ATTR, %eax
10:
//創(chuàng)建一個(gè)頁(yè)表項(xiàng)(地址+屬性)
leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */
//把頁(yè)表項(xiàng)存入頁(yè)全局目錄(pgd)
movl %ecx,(%edx) /* Store identity PDE entry */
movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
//指向頁(yè)全局目錄的下一項(xiàng)
addl $4,%edx
//建立一個(gè)頁(yè)表
movl $1024, %ecx
11:
//把eax中的內(nèi)容(頁(yè)地址+頁(yè)屬性)寫(xiě)入edi指向的物理地址,同時(shí)edi+4
stosl
addl $0x1000,%eax
loop 11b
//必須映射(KERNEL_IMAGE_SIZE+PAGE_TABLE_SIZE)大小的內(nèi)存區(qū)域
movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
cmpl %ebp,%eax
//如果還沒(méi)有映射到則繼續(xù)
jb 10b
//把頁(yè)表結(jié)束的線性地址寫(xiě)入_brk_end變量中--->safe location
addl $__PAGE_OFFSET, %edi
movl %edi, pa(_brk_end)
//把最大映射的頁(yè)框數(shù)量寫(xiě)入max_pfn_mapped變量中
shrl $12, %eax
movl %eax, pa(max_pfn_mapped)
//把pgd中的最后一個(gè)頁(yè)全局目錄項(xiàng)(pgd entry)設(shè)置成固定內(nèi)存映射(fixmap)項(xiàng)
movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
movl %eax,pa(swapper_pg_dir+0xffc) |
評(píng)分
-
查看全部評(píng)分
|