目录

Linux重谈地址空间

目录

【Linux】重谈地址空间

https://i-blog.csdnimg.cn/direct/ed0cbd50f72b49b39de24cbbf3860185.png

当 CPU 给 MMU 传新虚拟地址之后, MMU 先去问 TLB 那边有没有,如果有就直接拿到物理地址发到总线给内存,齐活。但 TLB 容量比较小,难免发生 Cache Miss ,这时候 MMU 还有保底的⽼武器页表,在页表中找到之后 MMU 除了把地址发到总线传给内存,还把这条映射关系给到TLB,让它记录⼀下刷新缓存。

设想,CPU 给 MMU 的虚拟地址,在 TLB 和页表都没有找到对应的物理页,该怎么办呢?其实这就是缺页异常 Page Fault,它是一个由硬件中断触发的可以由软件逻辑纠正的错误。

假如目标内存页在物理内存中没有对应的物理页或者存在但无对应权限,CPU 就无法获取数据,这种情况下 CPU 就会报告一个缺页错误。

由于 CPU 没有数据就无法进行计算,CPU 罢工了用户进程也就出现了缺页中断,进程会从用户态切换到内核态,并将缺页中断交给内核的 Page Fault Handler 处理。

https://i-blog.csdnimg.cn/direct/b0eb363f4fb6426c954adfe985400e1d.png

缺页中断会交给 PageFaultHandler 处理,其根据缺页中断的不同类型会进行不同的处理:

Hard Page Fault 也被称为 Major Page Fault,翻译为硬缺页错误 / 主要缺页错误,这时物理内存中没有对应的物理页,需要 CPU 打开磁盘设备读取到物理内存中,再让 MMU 建立虚拟地址和物理地址的映射。

Soft Page Fault 也被称为 Minor Page Fault,翻译为软缺页错误 / 次要缺页错误,这时物理内存中是存在对应物理页的,只不过可能是其他进程调入的,发出缺页异常的进程不知道而已,此时 MMU 只需要建立映射即可,无需从磁盘读取写入内存,一般出现在多进程共享内存区域。

Invalid Page Fault 翻译为无效缺页错误,比如进程访问的内存地址越界访问,又比如对空指针解引用内核就会报 segment fault 错误中断进程直接挂掉。

假如我们只有一个4kb大小的程序我们叫他为main,我们编译链接形成的是ELF格式,当我们main程序在运行,虚拟地址初始化操作系统为进程分配独立的虚拟地址空间,并根据 ELF 文件的 程序头表 将代码段、数据段等映射到虚拟地址空间此时 仅分配虚拟地址范围物理内存尚未加载 ,页表项初始化为无效。 页表按需建立, 当 CPU 执行 第一条指令 (即 ELF 入口点,存储于 EIP 寄存器( 随着程序运行动态变化。 )时,MMU 发现页表项无效,触发 缺页中断 。此时内核将 ELF 文件对应的数据从磁盘加载到物理页更新页表项,建立 虚拟地址到物理地址的映射, 之后IR、 EIP、CR3、MMU 等共同协作完成指令的取指和地址转换。

  • 如何理解我们之前的 new 和 malloc?

new和malloc只需要申请虚拟空间,当我们要用的时候才会缺页中断

  • 如何理解我们之前学习的写时拷贝?

是按照4kb为单位的进行写时拷贝

  • 申请内存,究竟是在干什么?

申请虚拟地址和填充修改页表

  • 如何区分是缺页了,还是真的越界了?
  1. 页号合法性检查:操作系统在处理中断或异常时,首先检查触发事件的虚拟地址的页号是否合法。如果页号合法但页面不在内存中,则为缺页中断;如果页号非法,则为越界访问。
  2. 内存映射检查:操作系统还可以检查触发事件的虚拟地址是否在当前进程的内存映射范围内。如果地址在映射范围内但页面不在内存中,则为缺页中断;如果地址不在映射范围内,则为越界访问。
  • 一个问题,越界了一定会保存吗?
  1. 线程资源划分的真相:只要将虚拟地址空间进行划分,进程资源就天然被划分好了。