由此可以看出,在初始的页目录 swapper_pg_dir 中,用户空间和内核空间都只映射了开头的两个目录项,即 8MB 的空间,而且有着相同的映射,如图:
文章插图
内核开始运行后运行在内核空间,那么,为什么把用户空间的低区(8M)也
进行映射,而且与内核空间低区的映射相同?
简而言之,是为了从实模式到保护模式的平稳过渡 。具体地说,当 CPU 进入内核代码的起点 startup_32 后,是以物理地址来取指令的 。在这种情况下,如果页目录只映射内核空间,而不映射用户空间的低区,则一旦开启页映射机制以后就不能继续执行了,这是因为,此时 CPU 中的指令寄存器 EIP 仍指向低区,仍会以物理地址取指令,直到以某个符号地址为目标作绝对转移或调用子程序为止 。所以,Linux 内核就采取了上述的解决办法 。
比如不映射用户空间的低区,内核代码的起点 startup_32 后,是以物理地址来取指令的,比如 eip 里面的地址为 0x0010010,当开启页面映射后,eip 里面的地址就要按照虚拟地址来处理了,这个时候要通过查页表进行把虚拟地址 0x0010010 转换为物理地址,这个时候没有映射用户空间的低区,找不到虚拟地址 0x0010010 到物理地址的映射,这个时候就会出现问题 。
在 CPU 转入内核空间以后,应该把用户空间低区的映射清除掉 。后面将会看到,页目录 swapper_pg_dir 经扩充后就成为所有内核线程的页目录 。在内核线程的正常运行中,处于内核态的 CPU 是不应该通过用户空间的虚拟地址访问内存的 。清除了低区的映射以后,如果发生 CPU 在内核中通过用户空间的虚拟地址访问内存,就可以因为产生页面异常而捕获这个错误 。
经过这个阶段的初始化,初始化阶段页目录及几个页表在物理空间中的位置如图所示 。
文章插图
/*
* ZERO_PAGE is a global shared page that is always zero: used
* for zero-mapped memory areas etc..
*/
extern unsigned long empty_zero_page[1024];
其中 empty_zero_page 中存放的是在操作系统的引导过程中所收集的一些数据,叫做引导参数 。因为这个页面开始的内容全为 0,所以叫做“零页”,代码中常常通过宏定义 ZERO_PAGE 来引用这个页面 。不过,这个页面要到初始化完成,系统转入正常运行时才会用到 。
那 swapper_pg_dir 和 pg0 、pg1 怎么对物理内存进行映射的呢?
从上面的物理内存分布可知,swapper_pg_dir 、pg0 、pg1存在物理内存中,swapper_pg_dir [0] 和 swapper_pg_dir [768] 指向 pg0 所在的物理地址,swapper_pg_dir [1] 和 swapper_pg_dir [769]指向pg1所在的物理地址 。而他们每一项对应的映射为 4M 。pg0 和 pg1 二者映射物理内存的前 8M 空间 。如下图:
文章插图
比如当访问虚拟内核地址空间 0xC0001002,通过 swapper_pg_dir 进行虚拟地址到物理地址转换时,发现 0xC0001002 处于 swapper_pg_dir [768],而 swapper_pg_dir [768] 指向 pg0 的物理内存地址,然后经过 pg0 找到其对应的物理页框 。
关于整个虚拟地址空间和物理空间分布关系如下:
【linux内核虚拟地址空间】
文章插图
推荐阅读
- 吃红螺有什么功效作用,什么海洋生物不具有再生功能
- 美图秀秀怎么拍证件照的,美图秀秀怎样才可以录制小
- Excel可以怎么批量插行或列
- 苹果日历提醒事项怎么设置闹钟,苹果手机日历应该要如何才能设置
- 胡萝卜是水果,水果胡萝卜是直接吃吗
- 哪个app可以把反色,美图秀秀反差色滤镜在哪
- 梦幻新诛仙奇缘哪些已经关闭了,梦幻新诛仙最难触发的奇缘
- 小龙虾是避孕药养的吗,小龙虾是用避孕药养殖的
- 角磨机如何更换磨片,角磨机片的正确安装方法