LinuxSir.cn,穿越时空的Linuxsir!

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

关于内存映射请教一个问题

[复制链接]
发表于 2006-3-29 19:02:53 | 显示全部楼层 |阅读模式
每个进程都有自己的页表目录,映射虚存空间0-3G到物理内存,不包含3-4G吧?
每个进程有不同的cr3值。

内核占用虚存空间3-4G,不过看情景分析最后系统启动一章上解释的内核启动时
同样会设置自己的页表目录的首地址到cr3寄存器去,这个值不应该和各个进程
设置的一样吧?

那么就出现这样一个问题,如果一条指令要把用户空间地址(比方说0x100)上的
数移动到内核空间的地址(比方说0xC0001000),在执行这条指令时不是只有一个
cr3么(哪个呢?),mmu对于不同空间的地址该如何解释(换算为物理地址)呢?

3x!
 楼主| 发表于 2006-3-31 01:08:06 | 显示全部楼层
搞清楚了,发贴澄清一下.

1.内核初始化时,内核页目录进行初始化,初始化的结果是,把3g--3g+物理内存大小之间
  线性地址线性的映射到物理地址(效果相当于直接减去3g就等于物理地址,但实际上还
  是要通过cpu的mmu来映射,也就是要通过cr3寄存器,这是内核初始话时精心设置的,不
  要怀疑其正确性,不信可以去读代码).也就是说,初始化过程中,0号进程的页面目录的
  高256项能初始化的都初始化了(还有一些没有初始化,取决于物理内存大小,如果物理
  内存只有512M,那么就只初始化其769--768+128项,后面的128项依然为空).

2.linux是通过do_fork来产生新的进程(或内核线程,本文暂不考虑它,实际上这个更简单)
  在fork一个进程的时候,必须建立进程自己的内核页目录项(内核页目录项要与用户空间
  的页目录放在同一个物理地址连续的页面上,所以不能共享,但所有进程的内核页表与进
  程0共享).
  这也就是为什么说所有的进程都享3g-4g的线性地址.
  附:实际上有时会出现内核的页面目录的高256项和进程的pgd所指向的页面目录的高256
  项不一致的情况(比方说在ioremap()或vmalloc()调用之后),接下来会解释.但是现在要
  清楚的是此时的0号进程的内存映射是最新的(因为ioremap或vmalloc更新的是init_mm
  的pgd所对应的内核页目录),我们需要做的事情是把其它进程的内核页目录更新,不过由
  于现在就全部更新消耗太大,所以都采用的是"用的时候再说",出现缺页时再更新.

3.在vmalloc和ioremap的时候因为分配的是内核虚拟空间,所以要设置相应的页目录和
  页表项.但是他们设置的都是0号进程对应的(也就是init_mm对应的页面映射目录或表),
  别的进程的内核页面目录可能并无映射,这时当该进程进行系统调用转入内核态时就
  可能发生缺页故障(这句话我还要斟酌).当一个进程在内核空间发生缺页故障的时候,
  就要通过0号进程的页目录来同步本进程的内核页目录,实际上就是拷贝0号进程的
  内核页目录到本进程中(内核页表与进程0共享,故不需要复制).
  这样的结果就是所有进程的内核页面目录都和0号进程"几乎一样",不一样的部分会在
  需要时建立映射.
回复 支持 反对

使用道具 举报

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

本版积分规则

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