内存布局
虚拟地址空间
Section titled “虚拟地址空间”0xFFFFFFFFFFFFFFFF ┌────────────────────┐ │ │ │ 内核空间 │ Ring 0 │ (256 TiB - 128 TiB)│0xFFFFFFFF80000000 ├────────────────────┤ ← KERNEL_OFFSET │ │ │ 未映射间隙 │ │ (128 TiB) │ │ │0x0000800000000000 ├────────────────────┤ │ │ │ 用户空间 │ Ring 3 │ (128 TiB) │ │ │0x0000000000000000 └────────────────────┘内核空间详细布局
Section titled “内核空间详细布局”0xFFFFFFFFFFFFFFFF ┌────────────────────┐ │ 保留 │0xFFFFFFFFFFFFFF00 ├────────────────────┤ │ IST[0] │ 20 KiB(双重故障栈)0xFFFFFFFFFFFFB000 ├────────────────────┤ │ 内核栈 (RSP0) │ 32 KiB0xFFFFFFFFFFFAB000 ├────────────────────┤ │ ... │0xFFFFFFFF80110000 ├────────────────────┤ │ .data / .bss │ ~16 KiB0xFFFFFFFF80100000 ├────────────────────┤ ← 内核 .text │ .text / .rodata │ ~64 KiB0xFFFFFFFF80000000 ├────────────────────┤ ← KERNEL_OFFSET │ ... │0x444444440000 ├────────────────────┤ ← 堆起始 │ 内核堆 │ 100 KiB0x444444430000 ├────────────────────┤ ← 堆结束 │ ... │0x00000000B8000 ├────────────────────┤ ← VGA 缓冲区 │ VGA 文本缓冲区 │ 4 KiB0x00000000B7C00 └────────────────────┘内核内存映射表
Section titled “内核内存映射表”| 区域 | 虚拟地址 | 大小 | 权限 | 说明 |
|---|---|---|---|---|
| VGA 文本缓冲区 | 0xB8000 | 4 KiB | RW | 恒等映射 |
| 内核 .text | 0xFFFFFFFF80100000 | ~64 KiB | RX | 代码段 |
| 内核 .data/.bss | 0xFFFFFFFF80110000 | ~16 KiB | RW | 数据段 |
| 内核堆 | 0x4444_4444_0000 | 100 KiB | RW | 堆分配器 |
| 内核栈 (RSP0) | TSS.rsp0 | 32 KiB | RW | 内核栈 |
| IST[0] | TSS.ist[0] | 20 KiB | RW | 双重故障栈 |
用户空间布局
Section titled “用户空间布局”0x00007FFFFFFFFFFF ┌────────────────────┐ │ 用户栈顶 │ │ (向下增长) │0x00007FFF00000000 ├────────────────────┤ │ │ │ 用户代码/数据 │ │ (ELF 加载) │ │ │0x0000000000400000 ├────────────────────┤ ← 用户程序基址 │ (保留/空) │0x0000000000000000 └────────────────────┘用户空间映射表
Section titled “用户空间映射表”| 区域 | 虚拟地址 | 大小 | 权限 | 说明 |
|---|---|---|---|---|
| 用户代码 | 0x400000 | 可变 | R-X | ELF .text |
| 用户数据 | 0x400000 + offset | 可变 | RW- | ELF .data/.bss |
| 用户栈 | 0x7FFF00000000 | 16 KiB | RW- | 向下增长 |
| 标志 | 位 | 说明 |
|---|---|---|
| Present | 0 | 页面是否在内存中 |
| Writable | 1 | 是否可写 |
| User | 2 | 用户态是否可访问 |
| Write-Through | 3 | 写透模式 |
| Cache Disabled | 4 | 禁用缓存 |
| Accessed | 5 | 是否被访问过 |
| Dirty | 6 | 是否被写入过 |
| Page Size | 7 | 大页面(2 MiB / 1 GiB) |
| NX | 63 | 禁止执行 |
| 映射 | Present | Writable | User | NX |
|---|---|---|---|---|
| 内核代码 | ✓ | ✗ | ✗ | ✗ |
| 内核数据 | ✓ | ✓ | ✗ | ✓ |
| 用户代码 | ✓ | ✗ | ✓ | ✗ |
| 用户数据 | ✓ | ✓ | ✓ | ✓ |
物理内存布局
Section titled “物理内存布局”BIOS 内存映射
Section titled “BIOS 内存映射”0x00000000 - 0x000003FF 中断向量表 (IVT)0x00000400 - 0x000004FF BIOS 数据区0x00000500 - 0x00007BFF 自由内存0x00007C00 - 0x00007DFF 引导扇区0x00007E00 - 0x0007FFFF 自由内存0x00080000 - 0x0009FFFF EBDA(扩展 BIOS 数据区)0x000A0000 - 0x000BFFFF VGA 显示内存0x000C0000 - 0x000FFFFF ROM 区域0x00100000 - 0x00FFFFFF 自由内存(1 MiB - 16 MiB)0x01000000 - ... 自由内存(>16 MiB)内核物理加载地址
Section titled “内核物理加载地址”0x00100000 (1 MiB) ← 内核物理加载地址 ↓ 页表映射 ↓0xFFFFFFFF80100000 ← 内核虚拟地址KERNEL_OFFSET = 0xFFFFFFFF80000000PHYSICAL_OFFSET = 0x100000
ENTRY(_start)
SECTIONS { . = KERNEL_OFFSET + PHYSICAL_OFFSET;
.text : AT(ADDR(.text) - KERNEL_OFFSET) { *(.text .text.*) }
.rodata : AT(ADDR(.rodata) - KERNEL_OFFSET) { *(.rodata .rodata.*) }
.data : AT(ADDR(.data) - KERNEL_OFFSET) { *(.data .data.*) }
.bss : AT(ADDR(.bss) - KERNEL_OFFSET) { *(.bss .bss.*) }}- 内核代码 - 只读、可执行(RX)
- 内核数据 - 可读写、不可执行(RW)
- 用户代码 - 用户可访问、只读、可执行(R-X)
- 用户数据 - 用户可访问、可读写、不可执行(RW-)
硬件保护机制
Section titled “硬件保护机制”- 页表权限位 - 硬件强制执行
- SMEP - 防止内核执行用户页面
- SMAP - 防止内核访问用户页面
- NX 位 - 防止执行数据页面
| 区域 | 策略 | 说明 |
|---|---|---|
| 内核代码 | Write-Back | 最佳性能 |
| 内核数据 | Write-Back | 最佳性能 |
| VGA 缓冲区 | Uncached | 内存映射 I/O |
| 设备 MMIO | Uncached | 硬件寄存器 |