ajhahn.de
← FlashOS
plain text 69 lines
/*
 * Linker script for user_space/init_main.zig — produces the
 * standalone pid1.elf that the kernel ELF-loads as PID 1.
 * Same single-PT_LOAD shape as
 * tools/flibc_demo_linker.ld: .text / .rodata / .data / .bss all fold
 * into one R+X LOAD segment at the page-aligned base 0x100000.
 *
 * pid1.elf carries the whole user_space/kernel_tests.zig harness, so
 * it is the largest of the staged ELFs. Folding rodata/data/bss into
 * the single LOAD keeps it to one segment, which the FlashOS ELF
 * loader (page-grain mapper, rejects non-page-aligned p_vaddr, does
 * not coalesce overlapping segments) maps without special-casing.
 *
 * Unlike the test payloads pid1.elf is loaded by kernel_process via
 * prepare_move_to_user_elf directly (not through sys_exec), so it is
 * NOT subject to sys_exec's PAGE_SIZE snapshot cap — prepare_move_to_
 * user_elf walks the PT_LOAD page by page. The harness still builds
 * ReleaseSmall + strip to keep the initramfs small.
 *
 * Layout:
 *   . = 0         — start of the only LOAD segment, page-aligned.
 *   .text         — code (entry point _start lives here).
 *   .rodata*      — the harness's [TEST]/[PASS]/[FAIL] string table.
 *   .data* / .bss* — comptime-emitted constants (expected zero-sized;
 *                    a non-zero .bss would store-fault on first write
 *                    because the LOAD is R+X — a clear runtime signal
 *                    the harness grew module-level mutable state).
 *
 * eh_frame/note/comment/dyn* sections are discarded — the harness is
 * pure syscall-wrapper inline asm with no unwind tables, and the
 * stock LLD layout would otherwise split .eh_frame_hdr / .eh_frame
 * into a leading R-only LOAD that bumps .text past the page-aligned
 * base the loader requires.
 */

ENTRY(_start)

PHDRS {
    text PT_LOAD FLAGS(5); /* PF_R | PF_X */
}

SECTIONS {
    . = 0;

    .text : {
        *(.text._start)
        *(.text .text.*)
        *(.rodata .rodata.*)
        *(.data .data.*)
        *(.bss .bss.*)
        *(COMMON)
    } :text

    /DISCARD/ : {
        *(.eh_frame*)
        *(.note*)
        *(.comment*)
        *(.dynamic)
        *(.dynsym)
        *(.dynstr)
        *(.gnu.hash)
        *(.hash)
        *(.gnu.version*)
        *(.interp)
        *(.rela*)
        *(.rel*)
    }
}