关于内存管理

刚看完第八章,对内存管理好像还有点迷糊,决定还是先停下来写点东西理一理

一些个专有名词

  • 逻辑地址
  • 线性地址
  • 虚拟内存
  • 平坦模型

逻辑地址—(GDT)—>线性地址—(分页)—>物理地址

平坦模型逻辑地址 == 线性地址

全局描述符表 GDT

是保护模式下,对物理内存段进行登记的数据结构,可以做到对内存段的保护,可以向下兼容16位寻址。

段描述符是8字节大小,其中包括段基址,段界限和控制位。内存的访问使用“段基址+段内偏移地址”,如果偏移地址超过了段界限表示的限制,则抛异常。

由于历史遗留问题,段描述符数据分布很乱。

  • 进入保护模式前,为什么需要创建好描述符、选择子、GDT?这些是必要条件吗? 是的,保护模式寻址流程:选择子——>在GDT中找到描述符——>在描述符中找到段基地址,再加上偏移量就ok了。所以必须先准备好GDT才可以在保护模式使用内存。

另外,本书学习Linux使用平坦模型,也就是说只有一个段,该段大小为4GB。段基地址为0,段界限*粒度为4GB。这4GB就是全部虚拟内存地址空间。(实际物理内存大小在bochsrc.disk中定义了是32MB)

页表

分页是CPU在设计的时候就原生支持的功能,很好地体现了软硬件发展的相互促进。

高10位为页目录项,中间10位页表索引,后12位是偏移量。

书中采用二级页表,CPU中CR3寄存器指向页目录项pde,放在了0x100000处。pde最后一个目录项指向它自己。

内核处在低端1MB内,书中把0xc0000000~0xc003fffff映射到物理地址0x0~0x3fffff上(4MB)

  • 启动分页的准备工作: 因为内核的位置发生改变,需要重新加载GDT;将各种段基地址改为3GB以上;将栈指针移到3GB以上
  • 开启分页后: 今后所有的寻址都要通过虚拟地址进行,地址的转换是CPU自动进行的,转换的规则就是位于CR3寄存器的pde和配套的pte

为什么要用虚拟内存

虚拟内存是操作系统物理内存和进程之间的中间层,它为进程隐藏了物理内存这一概念,为进程提供了更加简洁和易用的接口以及更加复杂的功能。

简单来说就是一层抽象,以前的话物理内存是多大就只能用多大,不够用憋着,没有丝毫商量的空间。有了虚拟内存,就可以假装自己内存很大,然后通过软件调度的方式动态规划内存的使用。

虚拟内存的可行性

现代计算机能提供极快的内存随机访问速度,所以即使实际地址不连续,对读取速度的影响也不大。

位图

用1bit来映射单位更大的资源,在内存管理中可以用来表示页的状态,虚拟内存和物理内存都有自己专属的位图。因为位图很小,可以塞进低端1MB内.

书中采用的策略是:虚拟地址空间用户低3GB,内核高1GB;物理内存空间用户和内核对半分,都是16MB。

内存管理

文中采用修改页表的方式分配内存,添加虚拟地址与物理地址的映射。