跳转到内容

内存布局

0xFFFFFFFFFFFFFFFF ┌────────────────────┐
│ │
│ 内核空间 │ Ring 0
│ (256 TiB - 128 TiB)│
0xFFFFFFFF80000000 ├────────────────────┤ ← KERNEL_OFFSET
│ │
│ 未映射间隙 │
│ (128 TiB) │
│ │
0x0000800000000000 ├────────────────────┤
│ │
│ 用户空间 │ Ring 3
│ (128 TiB) │
│ │
0x0000000000000000 └────────────────────┘
0xFFFFFFFFFFFFFFFF ┌────────────────────┐
│ 保留 │
0xFFFFFFFFFFFFFF00 ├────────────────────┤
│ IST[0] │ 20 KiB(双重故障栈)
0xFFFFFFFFFFFFB000 ├────────────────────┤
│ 内核栈 (RSP0) │ 32 KiB
0xFFFFFFFFFFFAB000 ├────────────────────┤
│ ... │
0xFFFFFFFF80110000 ├────────────────────┤
│ .data / .bss │ ~16 KiB
0xFFFFFFFF80100000 ├────────────────────┤ ← 内核 .text
│ .text / .rodata │ ~64 KiB
0xFFFFFFFF80000000 ├────────────────────┤ ← KERNEL_OFFSET
│ ... │
0x444444440000 ├────────────────────┤ ← 堆起始
│ 内核堆 │ 100 KiB
0x444444430000 ├────────────────────┤ ← 堆结束
│ ... │
0x00000000B8000 ├────────────────────┤ ← VGA 缓冲区
│ VGA 文本缓冲区 │ 4 KiB
0x00000000B7C00 └────────────────────┘
区域虚拟地址大小权限说明
VGA 文本缓冲区0xB80004 KiBRW恒等映射
内核 .text0xFFFFFFFF80100000~64 KiBRX代码段
内核 .data/.bss0xFFFFFFFF80110000~16 KiBRW数据段
内核堆0x4444_4444_0000100 KiBRW堆分配器
内核栈 (RSP0)TSS.rsp032 KiBRW内核栈
IST[0]TSS.ist[0]20 KiBRW双重故障栈
0x00007FFFFFFFFFFF ┌────────────────────┐
│ 用户栈顶 │
│ (向下增长) │
0x00007FFF00000000 ├────────────────────┤
│ │
│ 用户代码/数据 │
│ (ELF 加载) │
│ │
0x0000000000400000 ├────────────────────┤ ← 用户程序基址
│ (保留/空) │
0x0000000000000000 └────────────────────┘
区域虚拟地址大小权限说明
用户代码0x400000可变R-XELF .text
用户数据0x400000 + offset可变RW-ELF .data/.bss
用户栈0x7FFF0000000016 KiBRW-向下增长
标志说明
Present0页面是否在内存中
Writable1是否可写
User2用户态是否可访问
Write-Through3写透模式
Cache Disabled4禁用缓存
Accessed5是否被访问过
Dirty6是否被写入过
Page Size7大页面(2 MiB / 1 GiB)
NX63禁止执行
映射PresentWritableUserNX
内核代码
内核数据
用户代码
用户数据
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)
0x00100000 (1 MiB) ← 内核物理加载地址
页表映射
0xFFFFFFFF80100000 ← 内核虚拟地址
kernel/src/arch/x86_64/linker.ld
KERNEL_OFFSET = 0xFFFFFFFF80000000
PHYSICAL_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-)
  1. 页表权限位 - 硬件强制执行
  2. SMEP - 防止内核执行用户页面
  3. SMAP - 防止内核访问用户页面
  4. NX 位 - 防止执行数据页面
区域策略说明
内核代码Write-Back最佳性能
内核数据Write-Back最佳性能
VGA 缓冲区Uncached内存映射 I/O
设备 MMIOUncached硬件寄存器