请教关于swapper_pg_dir和pg0,pg1的问题
Q:
正在对照着看陈老师翻译的ULK2和Understanding The Linux Virtual Memory Manager(以下简称书2)两本书,现在有了如下的疑问:
1、arch/i386/kernel/head.S文件中,启动代码在启用分页单元之前,首先要建立pg0和pg1两个临时内核页表来映射8MB的物理地址,请问这8MB的物理地址究竟是0-8MB(ULK2中的说法)还是1-9MB(书2中的说法)?
个人比较倾向于后面一种说法,因为内核是被加载到内存的1MB开始处的,第1个MB的内存某些地址是保留给BIOS传递参数用的。
2、ULK2中提到了swapper_pg_dir中的第0和768项、第1和769项的地址字段中填充的分别是pg0和pg1的物理地址,我在arch/i386/kernel/head.S文件中找到了如下的代码
380 .org 0x1000
381 ENTRY(swapper_pg_dir)
382 .long 0x00102007
383 .long 0x00103007
384 .fill BOOT_USER_PGD_PTRS-2,4,0
385 /* default: 766 entries */
386 .long 0x00102007
387 .long 0x00103007
388 /* default: 254 entries */
389 .fill BOOT_KERNEL_PGD_PTRS-2,4,0
请问这段代码就达到了上面所说的目的吗?
3、临时内核页表pg0和pg1中的内容又是什么呢?
最后给出我看的Linux 2.4.20的源代码中的arch/i386/kernel/head.S文件链接:
请知道答案的大侠指点一下,谢谢!
A:
请看 head.S 中这段代码:
/*
* Initialize page tables
*/
movl $pg0-__PAGE_OFFSET,%edi /* initialize page tables */
movl $007,%eax /* "007" doesn't mean with right to kill, but
PRESENT+RW+USER */
2: stosl
add $0x1000,%eax
cmp $empty_zero_page-__PAGE_OFFSET,%edi
jne 2b
我们知道,内核 image 的起始物理地址是 0x100000,而pg0 相对与 kernel image 的地址是 0x2000, pg1 是 0x3000, empty_zero_page 是 0x4000
这段代码要把 pg0 至 empty_zero_page 之间的共 8K 内存初始化。
初始化后,这 2048 项的内容是:
0x0007, 0x1007, 0x2007, 0x3007 .......
取这些 32 地址的高20位,将低12位设置为0,就得到了物理页面的其实地址,因此,pg0, pg1 映射的是 前8M的物理页面。
这里的低 3 bit 为 111,表示 PRESENT+RW+USER
再看 swapper_pg_dir 的第 0 项和第1项,分别是 0x00102007 和 0x00103007,其高 20 bit 正是指向 pg0 和 pg1的起始地址,至于低 3 bit 为 111,同样表示 PRESENT+RW+USER
请看附件我画的一张物理内存布局图
阅读(4088) | 评论(0) | 转发(0) |