# Kernel address Kernel address is place in RAM, where kernel is located. (for example uefi can place kernel to it) ## x86_64 0x100000 (1MiB) On x86, the first 1MiB of physical memory is a minefield of legacy hardware reservations dating back to the orignal IBM PC (1981): 0x00000000 - 0x000003FF IVT (Interrupt Vector Table) — real mode 0x00000400 - 0x000004FF BIOS Data Area 0x00000500 - 0x00007BFF Conventional memory (usable, but tiny) 0x00007C00 - 0x00007DFF Boot sector load address (BIOS legacy) 0x00007E00 - 0x0007FFFF More conventional memory 0x00080000 - 0x0009FFFF EBDA (Extended BIOS Data Area) 0x000A0000 - 0x000BFFFF VGA video memory (framebuffer) 0x000C0000 - 0x000C7FFF VGA BIOS ROM 0x000C8000 - 0x000EFFFF Other option ROMs 0x000F0000 - 0x000FFFFF System BIOS ROM ───────────────────────────────────────────────── 0x00100000 FIRST SAFE ADDRESS (1 MiB) 0x00100000 is the first address above all this legacy garbage. It's whene Linux loads its kernel too ("high memory" region). Because of using UEFI (and not current support of BIOS) i don't need all this fields. ## AArch64 0x40100000 AArch64 has no legacy baggage - theere's no fixed memory map baked into the arch (i think it's one of the problem of this arch). Instead of it each board/machine defiens where RAM starts. For QEMU's virt machine (that i use for first time: qemu-system-aarch64 -machine virt) RAM begins: 0x00000000 - 0x3FFFFFFF Device MMIO region (GIC, UART, virtio, flash, etc.) ───────────────────────────────────────────────── 0x40000000 RAM starts here on QEMU virt Technically i can succesfully use 0x40000000 as the first byte, but i need to add 1MiB offset for the UEFI firmware's own use (page tables, runtime services data, memory map and other). The UEFI firmware itself is loaded into early RAM and may have data structs there. On a real AArch64 hrdware RAM starts a completely different address (for exmaple at 0x0 on the Pi). That's why we need to read device tree blob or UEFI memory map to figure out where RAM actually is, rather than hardcoding. ## Future solutions Right now kernel is identity-mapped (virtual == phisical), so the linker script address must match where the kernel phiscyally lives. Once we implement higher-half mapping in next Developing Phase (Phase II), the picture must changes: Current (identity-mapped): Linker says 0x100000, loaded at 0x100000, runs at 0x100000 After higher-half (Phase 2): Linker says 0xFFFFFFFF80100000 (virtual, higher-half) Loaded at 0x100000 (physical, by EFI loader) Page tables map virtual → physical Kernel runs at its virtual address At that point, the physical load address becomes flexible - the ELF loader can use AllocateAnyPages and the page tables handle the translation. The linkes script address becomes the virtual address, and the two are decoupled. Linux works exactly this way: vmlinux is linked at a high virtual address like 0xFFFFFFFF81000000, but it's physically loaded wherever the bootloader puts it.