分页管理之全局目录表、页表项的初始化的困惑
本帖最后由 wo3002807 于 2016-02-20 00:08 编辑通过阅读/arch/x86/kernel/head_32.s里的初始化分页代码:代码如下,
/*
* Initialize page tables.This creates a PDE and a set of page
* tables, which are located immediately beyond __brk_base.The variable
* _brk_end is set up to point to the first "safe" location.
* Mappings are created both at virtual address 0 (identity mapping)
* and PAGE_OFFSET for up to _end.
*/
#ifdef CONFIG_X86_PAE
.......
#else /* Not PAE */
page_pde_offset = (__PAGE_OFFSET >> 20);
movl $pa(__brk_base), %edi
movl $pa(initial_page_table), %edx
movl $PTE_IDENT_ATTR, %eax
10:
leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */
movl %ecx,(%edx) /* Store identity PDE entry */
movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
addl $4,%edx
movl $1024, %ecx
11:
stosl
addl $0x1000,%eax
loop 11b
/*
* End condition: we must map up to the end + MAPPING_BEYOND_END.
*/
movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp
cmpl %ebp,%eax
jb 10b
addl $__PAGE_OFFSET, %edi
movl %edi, pa(_brk_end)
shrl $12, %eax
movl %eax, pa(max_pfn_mapped)
/* Do early initialization of the fixmap area */
movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax
movl %eax,pa(initial_page_table+0xffc)
#endif/*
* Initialize page tables.This creates a PDE and a set of page
* tables, which are located immediately beyond __brk_base.The variable
* _brk_end is set up to point to the first "safe" location.
* Mappings are created both at virtual address 0 (identity mapping)
* and PAGE_OFFSET for up to _end.
*/
从上述的代码,我绘制了如下图:
__brk_base开始到__brk_base+4K,该区间存储全局目录项,里面的值为:0x1003,0x2003,..,0x4003(每一项是4byte,共1024项,故占4K)
接下来是页表项:0x401003,0x402003,..,0x800003
假设一个线性地址是0x0c040009,转换成二进制:11,0000000100,000000001001.从中得到pgd=0x3,pte=0x4,offset=0x9
那么根据线性地址转换成物理的规则:获取全局目录项的索引=0x3-0x001,然而无法获取pte的偏移量,即是说0x4-0x401,则为负,这样不合理。
那么我错在哪里?麻烦了!!!!! 理想情况下:
全局目录表:0x1003,0x2003,...,0x400003.
页表项:0x1003,0x2003,.....,0x400003。这样才合理。
如果是这样的话,上面的代码中的%eax的值是一值增大的,而不会回流。所以,不可能页表项的内容跟全局目录表的内容一样。 之前理解错误了,我知道错在哪里了。。。
上面的图是正确的,上面的图只是写了一部分的数据。初始化的PDT和PTE,里面共有一个PDE,1024个PTE,每个PTE拥有1024个。即是说,初始化页表、页目录共占4M+4K大小的内容。
那么PDT里面的值:0x1003,0x2003,0x3003,....,0x400003。
那么第一个PTE的值:0x401003,0x402003,0x403003,....,0x800003。
第二个PTE:0x801003,0x802003,0x803003,....,0xc00003
根据上面的线性地址:0x0c040009,转换成二进制:11,0000000100,000000001001.从中得到pgd=0x3,pte=0x4,offset=0x9
从得到物理地址:3*1024*1024+4*1024+9 = 3162121 = 0x0304009
请问这个是否正确? 之前理解错误了,我知道错在哪里了。。。
上面的图是正确的,上面的图只是写了一部分的数据。初始化的PDT和PTE,里面共有一个PDE,1024个PTE,每个PTE拥有1024个。即是说,初始化页表、页目录共占4M+4K大小的内容。
那么PDT里面的值:0x1003,0x2003,0x3003,....,0x400003。
那么第一个PTE的值:0x401003,0x402003,0x403003,....,0x800003。
第二个PTE:0x801003,0x802003,0x803003,....,0xc00003
根据上面的线性地址:0x0c040009,转换成二进制:11,0000000100,000000001001.从中得到pgd=0x3,pte=0x4,offset=0x9
从得到物理地址:3*1024*1024+4*1024+9 = 3162121 = 0x0304009
请问这个是否正确?
页:
[1]