Add lib/ — the shared user-space runtime every user binary links against (init now, servers/drivers later): syscall wrappers, the heap, IPC stub, and the process start shim. - lib/heap.zig: the kernel first-fit free-list ported to user space, grown via the mmap syscall instead of pmm+mapPage. Dual API over one global free list: extern "C" malloc/free/calloc/realloc (C ABI for future C code) and a std.mem.Allocator adapter (with in-place resize) for Zig std containers. - lib/syscall.zig + sys.zig: raw syscall0..5 (arg3 in r10) and typed yield/write/sleep/exit/mmap/munmap over danos.Syscall. - lib/start.zig: naked _start -> rt_start -> root.main() (SysV realign via call), panic -> exit(127). - lib/user.ld: the user link script, moved from sbin/linker.ld (shared by all user binaries). - build.zig: register the `rt` module; add an addUserBinary() helper that is the one recipe for every user binary (freestanding, .large, use_lld, user.ld, image_base), replacing the bespoke init block. - sbin/init.zig: migrated onto rt; drops its hand-rolled syscall2/shims. Now proves the heap (alloc -> write from a heap pointer -> free) before the heartbeat loop. Serial shows "init: heap ok". Suite 28/28.
53 lines
1.5 KiB
Plaintext
53 lines
1.5 KiB
Plaintext
/* Shared link layout for every user binary (init, servers, drivers).
|
|
*
|
|
* Linked at a fixed user-space virtual base (set by `image_base` in build.zig,
|
|
* inside the kernel's user region). Same discipline as the kernel's script:
|
|
* one PT_LOAD per permission set, every section page-aligned, so the kernel's
|
|
* user-ELF loader can map each segment with exact W^X permissions. Note the
|
|
* linker also emits a read-only PT_LOAD covering the ELF headers at the image
|
|
* base, so the entry point comes from e_entry, not the base address.
|
|
*/
|
|
|
|
ENTRY(_start)
|
|
|
|
/* FLAGS bits: 1=X, 2=W, 4=R. */
|
|
PHDRS {
|
|
text PT_LOAD FLAGS(5); /* R + X */
|
|
rodata PT_LOAD FLAGS(4); /* R */
|
|
data PT_LOAD FLAGS(6); /* R + W */
|
|
}
|
|
|
|
SECTIONS {
|
|
/* The `.large` code model (needed for the >4 GiB image base) emits code and
|
|
* data into .ltext/.lrodata/.ldata/.lbss; fold those into the matching
|
|
* permission segment alongside the normal names. */
|
|
.text ALIGN(4K) : {
|
|
*(.text .text.*)
|
|
*(.ltext .ltext.*)
|
|
} :text
|
|
|
|
.rodata ALIGN(4K) : {
|
|
*(.rodata .rodata.*)
|
|
*(.lrodata .lrodata.*)
|
|
} :rodata
|
|
|
|
.data ALIGN(4K) : {
|
|
*(.data .data.*)
|
|
*(.ldata .ldata.*)
|
|
} :data
|
|
|
|
/* .bss occupies memory but not file space; the loader zeroes the
|
|
* filesz..memsz gap. */
|
|
.bss ALIGN(4K) : {
|
|
*(.bss .bss.*)
|
|
*(.lbss .lbss.*)
|
|
*(COMMON)
|
|
} :data
|
|
|
|
/DISCARD/ : {
|
|
*(.comment)
|
|
*(.note .note.*)
|
|
*(.eh_frame .eh_frame_hdr)
|
|
}
|
|
}
|