Linux从头学14:【分页机制】-看了这篇文章还没彻底搞懂?我自罚三杯!
时间:2021-10-15 16:20:20
手机看文章
扫描二维码
随时随地手机看文章
[导读]作 者:道哥,10年嵌入式开发老兵,专注于:C/C、嵌入式、Linux。关注下方公众号,回复【书籍】,获取Linux、嵌入式领域经典书籍;回复【PDF】,获取所有原创文章(PDF格式)。目录分段存储的坏处物理内存的管理映射表一个线性地址的寻址过程终于开始介绍分页机制了,作为一名L...
作 者:道哥,10 年嵌入式开发老兵,专注于:C/C 、嵌入式、Linux。目录关注下方公众号,回复【书籍】,获取 Linux、嵌入式领域经典书籍;回复【PDF】,获取所有原创文章( PDF 格式)。
-
分段存储的坏处
-
物理内存的管理
-
映射表
-
一个线性地址的寻址过程
一共分 3 篇文章:
这篇文章主要介绍单映射表;下一篇介绍两级映射(页目录和页表);
最后一篇介绍对映射表自身的操作。
分段存储的坏处
在之前的文章中,我们多次描写了一个段描述符的结构,其中就包括段的开始地址、界限和各种段的属性。
所以 Linux 系统中,为了“不使用”分段机制,但是又无法绕过,只好定义了“平坦”的分段模型。在没有开启分页机制的情况下,分段单元输出的线性地址就等于物理地址。
物理内存的管理
关于映射表的细节,下一个主题再聊,先来看一下操作系统对物理内存的状态管理。
bit = 1: 表示该物理页被使用;262144个页需要262144个bit位,也就是32768个字节。bit = 0:表示该物理页空闲;
- 每一个物理页是 4KB,所以地址中最后 12 个 bit 都是 0;
- map 结构本身也需要存储在物理内存中的,因此 32768 个字节,一共需要 8 个物理页来存储(32768 / 4 * 1024 = 8)。
映射表
在32位系统中,虚拟内存的最大空间是4GB,这是每一个用户程序都拥有的虚拟内存空间。
但是,实际的物理内存只有1GB(假设值),那么操作系统就要使用自己的腾挪大法,让用户程序认为4GB的内存空间全部可用。
- 实际上,操作系统都会把虚拟内存的高地址部分,用作操作系统,低地址部分留给用户程序使用;
- Linux 系统中,高地址的 1GB 空间是操作系统使用;Windows 系统中,高地址的 2GB 的空间被操作系统使用,但是可以调整;
正是因为使用一个映射表,需要占用这么大的物理内存空间,所以才有后面的多级分页机制。虚拟内存看上去被虚线“分割”成4KB的单元,其实并不是分割,虚拟内存仍然是连续的。
也就是说:
- 虚拟内存的 0 ~ 4KB 空间,对应映射表第 0 个表项中,其中存储的物理地址是 0x3FFF_F000(最后一个物理页);
- 虚拟内存的 4KB ~ 8KB 空间,对应映射表第 1 个表项中,其中存储的物理地址是 0x0000_0000(第 0 个物理页);
- 虚拟内存的最后 4KB 空间,对应映射表最后一个表项中,其中存储的物理地址是 0x0000_1000(第 1 个物理页);
一个线性地址的寻址过程
我们假设用户程序中有一个代码段,那么在这个程序的LDT(局部描述符表)中,段描述的结构如下:
我们的目标是:查找线性地址0xC000_2020所对应的物理地址。
- 虚拟内存(32位系统):4GB,实际的物理内存 1GB;
- 代码段的开始地址位于 3 GB 的地方,也就是 0xC000_0000;
- 代码段的长度是 1 MB;
界限一共有 20 位,假设粒度是 4KB,那么 1 MB 的长度除以 4KB,结果就是 0x00100。代码段的开始地址(线性地址)0xC000_0000,位于虚拟内存靠近高端四分之一的位置,那么映射表中对应的表项,也是位于高端的四分之一的位置。
高 20 位 0xC0002: 是映射表索引;索引值0xC002,对应于下图中从3GB开始的第2个表项:低 12 位 0x020: 是物理页内的偏移地址;
------ End ------
本文描述了:通过一个映射表,把连续的虚拟内存,映射到离散的物理页,极大的利用了物理内存。