- 论坛徽章:
- 0
|
本帖最后由 cluter 于 2011-02-20 22:29 编辑
Non-PAE模式:
在non-PAE模式下,x86系统采用2-level页表。
相关的宏定义如下:
在Pgtable-2level_types.h文件中
//页全局目录的掩码
#define PGDIR_SHIFT 22
//页全局目录1024项
#define PTRS_PER_PGD 1024
//页表1024项
#define PTRS_PER_PTE 1024
在Page_32_types.h文件中
//定义内核大小为512MB---只是限制内核最大512MB
#define KERNEL_IMAGE_SIZE (512 * 1024 * 1024)
代码分析:
1 相关的宏定义
//页表的大小=页数量 / 每个页表中页目录的个数
#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
//映射内核线性地址空间需要的内存大小
MAPPING_BEYOND_END = \
PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
//内核页数量==(内核的大小+映射内核线性地址空间的页表的大小) / 页大小
//可以看出这个是 worst-case 下需要的内核页数量
KERNEL_PAGES = (KERNEL_IMAGE_SIZE + MAPPING_BEYOND_END)>>PAGE_SHIFT
//INIT_MAP_SIZE=初始化的时候必须要映射的内存大小,也就是上面kernel_pages的大小
INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm
//在brk段 预留名字为pagetables大小为INIT_MAP_SIZE的空间
RESERVE_BRK(pagetables, INIT_MAP_SIZE)
2 页表相关数据的内存分配
//为页全局目录(pgd)分配1024*4byte的内存空间
ENTRY(swapper_pg_dir)
.fill 1024,4,0
//为固定映射页表分配1024*4byte的内存空间
swapper_pg_fixmap:
.fill 1024,4,0
//分配一页并初始化为0
ENTRY(empty_zero_page)
.fill 4096,1,0
3 临时页表初始化代码
//内核线性地址开始的地方在pgd中的偏移位置
//__PAGE_OFFSET>>12>>10计算出在pgd中的页目录项index
//(__PAGE_OFFSET>>12>>10)<<2计算出偏移地址(因为每个页目录项4byte)
page_pde_offset = (__PAGE_OFFSET >> 20);
//把开始存放页表(page table)的物理地址写入edi
movl $pa(__brk_base), %edi
//把页全局目录(pgd)的物理地址写入edx
movl $pa(swapper_pg_dir), %edx
//把页表项(pte)属性写入eax
movl $PTE_IDENT_ATTR, %eax
10:
//创建一个页表项(地址+属性)
leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */
//把页表项存入页全局目录(pgd)
movl %ecx,(%edx) /* Store identity PDE entry */
movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
//指向页全局目录的下一项
addl $4,%edx
//建立一个页表
movl $1024, %ecx
11:
//把eax中的内容(页地址+页属性)写入edi指向的物理地址,同时edi+4
stosl
addl $0x1000,%eax
loop 11b
//必须映射(KERNEL_IMAGE_SIZE+PAGE_TABLE_SIZE)大小的内存区域
movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
cmpl %ebp,%eax
//如果还没有映射到则继续
jb 10b
//把页表结束的线性地址写入_brk_end变量中--->safe location
addl $__PAGE_OFFSET, %edi
movl %edi, pa(_brk_end)
//把最大映射的页框数量写入max_pfn_mapped变量中
shrl $12, %eax
movl %eax, pa(max_pfn_mapped)
//把pgd中的最后一个页全局目录项(pgd entry)设置成固定内存映射(fixmap)项
movl $pa(swapper_pg_fixmap)+PDE_IDENT_ATTR,%eax
movl %eax,pa(swapper_pg_dir+0xffc) |
评分
-
查看全部评分
|