内存独享
分段
段表全程段描述符(segment descriptors),放在全局描述符表 GDT(Global Descriptor Table)里面。
分页
- 内存管理包含: 物理内存管理; 虚拟内存管理; 两者的映射
- 除了内存管理模块, 其他都使用虚拟地址(包括内核)
- 虚拟内存空间包含: 内核空间(高地址); 用户空间(低地址)
- 用户空间从低到高布局为: 代码段; DATA 段; BSS 段(未初始化静态变量); 堆段; 内存映射段; 栈地址空间段
- 多个进程看到的用户空间是独立的
- 内核空间: 多个进程看到同一内核空间, 但内核栈每个进程不一样
- 内核代码也仅能访问内核空间
- 内核也有内核代码段, DATA 段, 和 BSS 段; 位于内核空间低地址
内核代码也是 ELF 格式
虚拟内存地址到物理内存地址的映射
- 分段
- 虚拟地址 = 段选择子(段寄存器) + 段内偏移量
- 段选择子 = 段号(段表索引) + 标识位
- 段表 = 物理基地址 + 段界限(偏移量范围) + 特权等级
- Linux 分段实现
- 段表称为段描述符表, 放在全局标识符表中
- Linux 将段基地址都初始化为 0, 不用于地址映射
- Linux 分段功能主要用于权限检查
- Linux 通过分页实现映射
- 物理内存被换分为大小固定(4 KB)的页, 物理页可在内存与硬盘间换出/换入
- 页表 = 虚拟页号 + 物理页号; 用于定位页
- 虚拟地址 = 虚拟页号 + 页内偏移
- 若采用单页表, 32 位系统中一个页表将有 1M 页表项, 占用 4MB(每项 4B)
- Linux 32 位系统采用两级页表: 页表目录(1K项, 10bit) + 页表(1K项, 10bit)(页大小(4KB, 12bit))
- 映射 4GB 内存理论需要 1K 个页表目录项 + 1K*1K=1M 页表项, 将占用 4KB+4MB 空间
- 因为完整的页表目录可以满足所有地址的查询, 因此页表只需在对应地址有内存分配时才生成;
- 64 为系统采用 4 级页表