LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 815|回复: 3

在内核态下,设置cr3前后程序是否仍然连续?

[复制链接]
发表于 2005-5-7 09:54:06 | 显示全部楼层 |阅读模式
在内核态下,当需要准备执行一个进程的时候,需要给这个进程准备好目录表和页表;
执行这个进程前,需要设置cr3寄存器的值,以指定相应的目录表结构。

我的问题是,当执行“设置cr3值的这条语句”完成以后(当然是在内核态下),程序仍然是连续执行的,而不会从此跳转到新的进程(因为指定了新的目录表和页表,所以自然会有这个疑问)。

在《linux源码情景分析》中是这样解释的:因为不管是什么进程,只要到了内核态,他们均有着同样的目录表和页表,所以程序在此仍然是连续进行的。(大意是这样的)

虽然把原文看了N遍,但是仍然不理解。

希望各位高手指点。谢谢!
发表于 2005-5-8 10:38:42 | 显示全部楼层
找到知音人了阿,我也为这个问题困惑了好久,不过现在搞懂了,和楼上的分享一下。
你要搞明白这个问题,要从内核的启动过程说起,故事有点长,Ha~~

就从内核在内存中被解压缩这个过程说起吧,此时保护模式已经开启(保护模式的开启
是在arch/i386/boot/setup.S中实现的,但是分页模式没有开启,所以线性地址就是
物理地址),在arch/i386/boot/compressed/head.S中执行解压过程之后执行了下
面这条汇编语句

ljmp $(__BOOT_CS), $0x100000

这个指令的含义是跳转到物理地址$(__BOOT_CS)0x100000,如果你仔细看解压
缩的代码,你就会发现内核被解压缩到了0x100000处。也就是arch/i386/kernel/head.S
代码开始的地方,这这个head.S中比较关键的部分就是开启分页代码的前后,也就是你关心
的了

189     orl $0x80000000,%eax
190     movl %eax,%cr0          /* ..and set paging (PG) bit */

这两条语句用来开启分页模式。然而,在执行第189行的指令时,此时EIP的值应该是第
190行指令的物理地址,它的形式是0x0010****,然后CPU开始执行第190行的指令,
此时EIP的值会被设定成第191条指令的地址。在执行完第190条指令,CPU开启了分页模
式,但是此时EIP中的值还是191条指令的物理地址,所以CPU在开启分页模式的情况下,
用类似0x0010****的形式去获取第191条指令,这里要注意的是,只要开启了分页模式,
EIP的值就是虚拟地址了,所以为了保证这条指令可以正确被获取,内核的临时页表中把虚拟
地址0~8MB和PAGEOFFSET~PAGEOFFSET+8MB映射到了物理地址空间0~8MB,就是
为了191行的这一条指令阿。

再来看一下191行的这条指令都作了什么:
191  ljmp $__BOOT_CS,$1f     /* Clear prefetch and normalize %eip */
192 1:

作了一个跳转,用来清空指令预取队列,这里$1f的地址是以0xC000****的形式出现的(
详见vmlinux.lds),所以从第191行的下一个指令开始,EIP的值就完全是0xC000****
的形式了,也就完成了你所说的过渡过程,不知道我说清楚了没有,欢迎各位高手指教。
回复 支持 反对

使用道具 举报

发表于 2005-5-10 15:22:25 | 显示全部楼层
感觉你说的这个书上解释的还是蛮清晰的.
想想在执行“设置cr3值的这条语句”的时候,那时候的地址空间是什么样的?应该在3--4G吧,而每个进程对于这段地址的映射都是同样的,所以,即使cr3里的内容变了,但是所指向的那张页目录表的后1/4项没变,就是说,你现在所在的线性地址对应的物理地址还是那里,注意,这时候ip并没有变,当然就会接着执行了.
晕~~~~~~ 说的连自己都糊了 ^_^
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-11 10:39:52 | 显示全部楼层
这几天因为要等待激活帐号,所以无法及时回复。

谢谢puretears兄弟和rickxbx兄弟的解答。

puretears兄弟说得是在页式映射开启之前到开启页式映射的这个过程中,内核式

如何通过一些措施使得程序能够顺利的连续运行。

而rickxbx兄弟则从映射的内容上解释了为什么设置不同的cr3的值,而程序仍然

能够连续运行,是因为所有的进程所映射到的3G-4G的内核空间的页表都是一致

的(并且共享)。


综合起来,在内核中设置不同的进程对应的cr3的值,程序仍然能够在内核中连续

运行,是因为每个进程都共享3G-4G的内核线性空间,而这个空间的页式映射对

每个进程都是相同的,并且是共享的。


虽然我还不能彻底地理解,但经过各位的解释,总算有些体会。谢谢各位的帮忙。

希望能看到各位更多的真知灼见。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表