Chinaunix首页 | 论坛 | 博客
  • 博客访问: 545434
  • 博文数量: 101
  • 博客积分: 1889
  • 博客等级: 上尉
  • 技术积分: 906
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-14 16:22
文章分类

全部博文(101)

文章存档

2012年(11)

2011年(19)

2010年(59)

2009年(12)

我的朋友

分类: LINUX

2009-09-16 07:21:36

请教关于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) |
给主人留下些什么吧!~~