這篇文紀錄通過 QEMU + gdb 的方式,徒手把 Virtual Address 轉成 Physical Address 的過程
文中會先補理論的重點再紀錄實作
理論和實作的基礎是建立於 x86-64 的 Linux 4.17.0
(上圖來自 AMD 手冊)
Virtual memory map with 4 level page tables:
0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm
hole caused by [47:63] sign extension
ffff800000000000 - ffff87ffffffffff (=43 bits) guard hole, reserved for hypervisor
ffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memory
ffffc80000000000 - ffffc8ffffffffff (=40 bits) hole
ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
... unused hole ...
ffffec0000000000 - fffffbffffffffff (=44 bits) kasan shadow memory (16TB)
... unused hole ...
vaddr_end for KASLR
fffffe0000000000 - fffffe7fffffffff (=39 bits) cpu_entry_area mapping
fffffe8000000000 - fffffeffffffffff (=39 bits) LDT remap for PTI
ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
... unused hole ...
ffffffef00000000 - fffffffeffffffff (=64 GB) EFI region mapping space
... unused hole ...
ffffffff80000000 - ffffffff9fffffff (=512 MB) kernel text mapping, from phys 0
ffffffffa0000000 - fffffffffeffffff (1520 MB) module mapping space
[fixmap start] - ffffffffff5fffff kernel-internal fixmap range
ffffffffff600000 - ffffffffff600fff (=4 kB) legacy vsyscall ABI
ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
頁表 | binary | decimal |
---|---|---|
PML4I | 0b111111111 | 511 |
PDPI | 0b111111110 | 510 |
PDI | 0b000001000 | 8 |
PTI | 0b100011100 | 284 |
Offset | 0b001110011000 | 920 |
CR3
的值,其為 PML4 Base Address,注意其為 PA
頁表 | binary | decimal |
---|---|---|
PML4I | 0b111111111 | 511 |
PDPI | 0b111111110 | 510 |
PDI | 0b000001000 | 8 |
Offset | 0b100011100001110011000 | 1164184 |