oak
oak copied to clipboard
Move the kernel to the higher half of virtual address space
Our kernel right now expects identity mapping between physical and virtual addresses, and thus resides in the lower half of the canonical address space (see https://en.wikipedia.org/wiki/X86-64#Virtual_address_space_details for more details).
Traditionally kernels live in the upper half, leaving the lower half for userspace. We should move our code to the upper half as well.
Estimate of things to do:
- [ ] change the linker script to set VirtAddrs to the upper half (note that PhysAddr will stay the same!)
- [ ] when setting up initial paging, map pages containing kernel code to their correct virtual addresses instead of using identity mapping
A good guide as to what the memory layout should be can be found in the Linux kernel documentation: https://docs.kernel.org/x86/x86_64/mm.html#complete-virtual-memory-map-with-4-level-page-tables
and if you examine vmlinux
using readelf
, here's some interesting bits:
ELF Header:
Entry point address: 0x1000000
Section Headers:
[ 1] .text PROGBITS ffffffff81000000 200000 c01e40 00 AX 0 0 4096
[ 2] .rodata PROGBITS ffffffff81e00000 1000000 404ff7 00 WA 0 0 4096
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x200000 0xffffffff81000000 0x0000000001000000 0x1644220 0x1644220 R E 0x200000
Note that code with virtual addresses in the higher half are still loaded to physaddr of zero.