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操作系统》,推荐该课程。

相关推荐
牧以南歌〆2 小时前
在Ubuntu主机中修改ARM Linux开发板的根文件系统
linux·arm开发·驱动开发·ubuntu
夜月yeyue3 小时前
设计模式分析
linux·c++·stm32·单片机·嵌入式硬件
kfepiza4 小时前
Debian的`/etc/network/interfaces`的`allow-hotplug`和`auto`对比讲解 笔记250704
linux·服务器·网络·笔记·debian
cuijiecheng20185 小时前
Ubuntu下布署mediasoup-demo
linux·运维·ubuntu
独行soc7 小时前
2025年渗透测试面试题总结-2025年HW(护网面试) 33(题目+回答)
linux·科技·安全·网络安全·面试·职场和发展·护网
java龙王*7 小时前
开放端口,开通数据库连接权限,无法连接远程数据库 解决方案
linux
bcbobo21cn8 小时前
Linux命令的命令历史
linux·histsize·histfile
jingyu飞鸟9 小时前
linux系统源代码安装apache、编译隐藏版本号
linux·运维·apache
世事如云有卷舒9 小时前
Ubunt20.04搭建GitLab服务器,并借助cpolar实现公网访问
linux·服务器·gitlab
2401_8582861110 小时前
OS15.【Linux】gdb调试器的简单使用
linux·运维·服务器·开发语言·gdb