内存管理
1 基础
1.1 地址分类
- 虚拟地址(Virtual Address):即我们在应用程序中所使用的地址,例如使用
%p
所打印出的地址就是虚拟地址
- 线性地址(Linear Address):虚拟地址经过分段处理就变成了线性地址
- 物理地址(Physical Address):线性地址经过内存管理单元(MMU)转换后就会成为物理地址,此转换过程称为分页
- 线性地址空间的页是逻辑上的页,称为页表(Page Table),是虚拟的;物理空间的页,称为页框(Page Frame),是真实存在的,只是在逻辑上被划分为一页一页地,页大小一般为4K(也可能为2M、4M或1G)。后续说的分页就是将页表与页框联系起来的一个过程,具体分页有两个动作,其一是从页表上的地址找到页框上的地址(即寻址),其二是建立页表与页框之间的映射关系
1.2 分段与分页
- Linux主要的4个段分别为:用户代码段(
__USER_CS
)、用户数据段(__USER_DS
)、内核代码段(__KERNEL_CS
和内核数据段(__KERNEL_DS
),由于各段的段描述符的基准地址全为0,故转换后的线性地址与虚拟地址相等
- 分页从字面理解就是将内存逻辑上分为一页一页的,当CPU要访问某个地址(物理地址)的时候,必须先找到包含该地址的页,而这个页的地址又存在上一级页的项中;上一级页的地址又存在上上一级页的项中。以此类推,最高一级的页地址存在CPU的寄存器中
- 故最终地址的索引流程为:寄存器->一级页->...->最终页->物理地址。这类似于身份证前6位的定位一样,前两位表示省份,34位表示市,56位表示区县
2 寻址
2.1 一个例子
- 假设有一个寻宝游戏,玩家在一开始知道一个藏宝图
[0x10, 0x20, 0x30, 0x40]
和一个地点(市民广场),于是玩家来到了市民广场并在0x10坐标找到了第二个地点(深圳湾);之后玩家来到深圳湾并在0x20坐标处找到了第3个地点(梧桐山)并在0x30坐标找到了第4个地点(大鹏湾),最后玩家在大鹏湾的0x40坐标处寻得宝藏
- 该玩家整体寻宝过程为:
市民广场(Base1)+0x10(offset)
->深圳湾(Base2)
;深圳湾(Base2)+0x20(offset)->梧桐山(Base3)
;梧桐山(Base3)+0x30->大鹏湾(Base4)
;大鹏湾(Base4)+0x40->宝藏
。对玩家而言,他只是拿到偏移量