plain text 87 lines
/*
* Kernel link script (RPi4, AArch64).
* PID 1 is ELF-loaded from the embedded initramfs:
* `/sbin/init` is the standalone `pid1.elf` artifact, and
* the kernel's `prepare_move_to_user_elf` maps it page-grain. The
* `user_init.o` blob — wrapped here in `.text.user` /
* `.rodata.user` / `.data.user` / `.bss.user` between `user_start`
* and `user_end` — is retired.
*/
SECTIONS
{
/DISCARD/ : { *(.eh_frame) *(.eh_frame_hdr) *(.note.*) *(.comment) }
/* RPi4 firmware loads kernel8.img at PA 0x80000 (the standard AArch64
* load address; see "Kernel relocated to 0x80000" in start4.elf log).
* Linking at the same base means linker-resolved global pointers
* actually point at the bytes the firmware placed — no relocator
* needed at boot. Previously the implicit base was 0x01000000, which
* sat above the 16 MB id-map and caused L2 translation faults the
* moment any global was dereferenced (e.g. ksyms in cal_ksyms_count). */
. = 0x80000;
.text.boot : { *(.text.boot) *(.text.boot.late) *(.text.boot.literals) }
.text : {
*(.text)
*(.text.*)
}
.rodata : {
*(.rodata)
*(.rodata.*)
}
.data : {
*(.data)
*(.data.*)
}
. = ALIGN(0x8);
__start_patchable_functions = .;
.patchable_function_entries : {
KEEP(*(__patchable_function_entries))
}
__stop_patchable_functions = .;
. = ALIGN(0x8);
ksyms = .;
symbols : {
KEEP(*(_symbols))
}
. = ALIGN(0x8);
bss_begin = .;
.bss : {
*(.bss)
*(.bss.*)
*(COMMON)
}
bss_end = .;
/* Embedded initramfs. Placed between bss_end and
* id_pg_dir; the kernel reads it through a TTBR1 linear-map
* alias in src/initramfs.zig. Size shifts everything past it
* (id_pg_dir, high_pg_dir), so the cpio bytes must be a
* deterministic function of the source tree (see
* scripts/build_initramfs.zig for the deterministic encoder). */
. = ALIGN(0x4);
.initramfs : {
KEEP(*(.initramfs))
}
. = ALIGN(0x1000);
id_pg_dir = .;
.data.id_pg_dir : { . += (3 * (1 << 12)); }
high_pg_dir = .;
.data.high_pg_dir : { . += (6 * (1 << 12)); }
/* End-of-reserved-PA marker for the get_free_page pool. Read by
* mem_map_reserve_below in kernel_main so the allocator never hands
* out a PA inside the kernel image / page-table reservations. On
* RPi4 the kernel sits at PA 0x80000–~0x200000, far below the
* pool's MALLOC_START (0x40000000), so the reserved range is empty
* and reserve_below is a no-op — but the symbol is still defined
* for cross-board parity with virt. */
. = ALIGN(0x1000);
_kernel_pa_end = .;
}