Linux内存管理的分页机制

分段机制的原理如下:

分段机制下的虚拟地址由两部分组成,段选择子段内偏移量。段选择子就保存在段寄存器里面。段选择子里面最重要的是段号,用作段表的索引。段表里面保存的是这个段的基地址、段的界限和特权等级等。虚拟地址中的段内偏移量应该位于 0 和段界限之间。如果段内偏移量是合法的,就将段基地址加上段内偏移量得到物理内存地址。

将上面的虚拟空间分成以下 4 个段,用 0~3 来编号。每个段在段表中有一个项,在物理空间中,段的排列如下图的右边所示。

如果要访问段 2 中偏移量 600 的虚拟地址,我们可以计算出物理地址为,段 2 基地址 2000 + 偏移量 600 = 2600。

在 Linux 里面,段表全称段描述符表(segment descriptors),放在全局描述符表 GDT(Global Descriptor Table)里面,会有下面的宏来初始化段描述符表里面的表项。

复制代码
#define GDT_ENTRY_INIT(flags, base, limit) { { { \
    .a = ((limit) & 0xffff) | (((base) & 0xffff) << 16), \
    .b = (((base) & 0xff0000) >> 16) | (((flags) & 0xf0ff) << 8) | \
      ((limit) & 0xf0000) | ((base) & 0xff000000), \
  } } }

一个段表项由段基地址 base、段界限 limit,还有一些标识符组成。

其实 Linux 倾向于另外一种从虚拟地址到物理地址的转换方式,称为分页(Paging)。

对于物理内存,操作系统把它分成一块一块大小相同的页,这样更方便管理,例如有的内存页面长时间不用了,可以暂时写到硬盘上,称为换出。一旦需要的时候,再加载进来,叫做换入。这样可以扩大可用物理内存的大小,提高物理内存的利用率。

这个换入和换出都是以页为单位的。页面的大小一般为 4KB。为了能够定位和访问每个页,需要有个页表,保存每个页的起始地址,再加上在页内的偏移量,组成线性地址,就能对于内存中的每个位置进行访问了。

虚拟地址分为两部分,页号页内偏移。页号作为页表的索引,页表包含物理页每页所在物理内存的基地址。这个基地址与页内偏移的组合就形成了物理内存地址。

当然对于 64 位的系统,两级肯定不够了,就变成了四级目录,分别是全局页目录项 PGD(Page Global Directory)、上层页目录项 PUD(Page Upper Directory)、中间页目录项 PMD(Page Middle Directory)和页表项 PTE(Page Table Entry)。

此文章为11月Day1学习笔记,内容来源于极客时间《趣谈Linux操作系统》,推荐该课程。

相关推荐
GeW16 小时前
超详细!RHCE10版通用备考策略,内含评分细则解读
linux
用户0413284651317 小时前
Linux 服务开机自启动怎么配置?systemctl enable 原理详解
linux
草莓熊Lotso1 天前
【Redis 初阶】Set 类型深度解析:去重集合的运算能力与实战场景
linux·网络·数据库·windows·redis·tcp/ip·缓存
张文君1 天前
ubuntu26.04坏道坏块分区隔离急速版260831-V0.12
linux·python
贝锐1 天前
从国产化信创设备到商用安卓终端,向日葵如何帮助企业实现统一运维管理?
linux·运维·远程控制
Julien20041 天前
调查和解决 SELinux 问题
linux·运维·服务器·网络·学习方法
小张同学a.2 天前
Docker 容器实战 1—— docker 基础与镜像构建
linux·运维·docker·容器
Best-Wishes2 天前
BurpSuite Pro教育版在linux系统中配置
linux·运维·服务器·网络安全·burpsuite
wuminyu2 天前
深入剖析 Panama Off-heap 的性能损耗与开销
java·linux·c语言·jvm·c++
虎王物联2 天前
RK3568嵌入式Linux跑Docker:内核配置排查到AIoT容器化的完整路径
linux·运维·docker·rk3568·aiot·嵌入式linux