关于内存映射请教一个问题
时间:2006-03-29
来源:互联网
每个进程都有自己的页表目录,映射虚存空间0-3G到物理内存,不包含3-4G吧?
每个进程有不同的cr3值。
内核占用虚存空间3-4G,不过看情景分析最后系统启动一章上解释的内核启动时
同样会设置自己的页表目录的首地址到cr3寄存器去,这个值不应该和各个进程
设置的一样吧?
那么就出现这样一个问题,如果一条指令要把用户空间地址(比方说0x100)上的
数移动到内核空间的地址(比方说0xC0001000),在执行这条指令时不是只有一个
cr3么(哪个呢?),mmu对于不同空间的地址该如何解释(换算为物理地址)呢?
3x!
每个进程有不同的cr3值。
内核占用虚存空间3-4G,不过看情景分析最后系统启动一章上解释的内核启动时
同样会设置自己的页表目录的首地址到cr3寄存器去,这个值不应该和各个进程
设置的一样吧?
那么就出现这样一个问题,如果一条指令要把用户空间地址(比方说0x100)上的
数移动到内核空间的地址(比方说0xC0001000),在执行这条指令时不是只有一个
cr3么(哪个呢?),mmu对于不同空间的地址该如何解释(换算为物理地址)呢?
3x!
作者: corperl 发布时间: 2006-03-29
搞清楚了,发贴澄清一下.
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号进程"几乎一样",不一样的部分会在
需要时建立映射.
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号进程"几乎一样",不一样的部分会在
需要时建立映射.
作者: corperl 发布时间: 2006-03-31
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28