分页机制
页表是凌驾于分段机制之上的,也凌驾于保护模式的段描述符之上的
逻辑地址 线性地址 和 物理地址
逻辑地址 ds里存放选择子,通过选择子找到段描述符,段描述符映射到段基地址 :偏移量 => 线性地址。
线性地址 关闭分页 ==> 物理地址 开启分页 -> 查页目录和页表 ->找到物理地址
┌───────────────────────┐
│ 逻辑地址 (Logical) │
│ 例如: DS:0x1234 │
└───────────┬───────────┘
│
▼
┌───────────────────────┐
│ 段描述符 (Segmentation) │
│ GDT/LDT 提供 Base+Limit│
└───────────┬───────────┘
│
▼
┌───────────────────────┐
│ 线性地址 (Linear) │
│ Base + Offset │
│ 例如: 0x00401234 │
└───────────┬───────────┘
│
[分页开关 CR0.PG=1?]
│
┌───────────────┴─────────────────┐
│ │
▼ ▼
┌─────────────────────┐ ┌──────────────────────┐ │ 分页机制关闭 │ │ 分页机制开启 │ │ Linear = Physical │ │ 查页目录 + 页表 │ └───────────┬─────────┘ └───────────┬──────────┘ │ │ ▼ ▼ ┌──────────────────┐ ┌───────────────────┐ │ 物理地址 (Physical) │ │ 物理地址 (Physical) │ │ 直接访问 RAM 芯片 │ │ 页表映射后的地址 │ └──────────────────┘ └───────────────────┘
开启分页后的逻辑 => 线性地址到物理地址
线性地址32位 分为三段 31-22 页目录索引 Page Directory(页目录) 用于查到目录项(pde) 21-12 页表索引 从pde里通过Page Table(pt)找到页表项(pte) 11-0 页内偏移 对应物理页的偏移量
举个例子: 0x12345678 12 3 45 678
12 = 18 => 0001 0010 3 = 0011 pd(10bit)= 0001 0010 00 = 0100 1000 = 0x48 pt(10bit)= 11 0100 0101 = 0x345 偏移 = 0x678
- 查页目录->通过0x48找到页表的物理地址
- 查页表 -> 通过0x345找到页框基地址
- 找到具体地址 -> 页框基地址+0x678 等到物理地址
物理页帧和页项
都是4k为单位,如果4g内存会划分 1m个页表项,每个页表项4字节,需要4m来存储
一级页表
段部件输出线性地址 线性地址的 高20位是索引(1m) 低12位(4k)为偏移量 查页表 -> 获取到页表项里的物理地址基地址 物理地址基地址+12位偏移量 -> 找到具体的物理地址
pte 页表项
pte 4b => 32位 高20位 表示物理页框号 低12位用于权限等元数据 物理页框号*4k + 偏移量 就能找到 具体的物理内存
一级页表 如果要表示4g的空间,一个pte 能表示 4k的空间,则需要 4g/4k * 4 的内存来存储 4g/4k = 1m
二级页表
一个页表项范围是4k,页尺寸不变都是4k,则一个页能有4k/4=1024个页表项 所以 4k * 1024 = 4m 代表一个页表能映射4m 4g/4m = 1024个页表,则二级页表需要有1024个页目录项 1024个页目录项*4 = 4k,则正好又等于一个物理页的大小