3.7 KiB
musl → UniversalisOS POSIX personality port (T8-1.2a)
Track: T8 · Task: T8-1.2a (musl syscall-glue layer) Status: syscall-glue skeleton DONE + verified (aarch64) · full musl port = multi-week
A musl libc port that runs userspace directly on the UniversalisOS native POSIX syscall ABI (
POSIX_SVC_*,0xB0–0xC4) — NOT a Linux guest. This is the primary hardened_malloc import target (the freestanding EL2 kernel is not a target). Seeuniversalisos/docs/T8-1.2_MUSL_POSIX_PERSONALITY.md.
What is here
arch/uos/syscall_arch.h — the syscall-glue header: maps musl's __syscallN onto
the UOS POSIX_SVC_* opcodes (incl. the T8-1.2b MM
extensions mprotect/madvise/mremap). Verified: compiles
for aarch64 and emits `mov x8,#0xB1; svc #0` etc.
The syscall surface (authoritative source: kernel/src/core/abi/uos_posix_abi.h)
| UOS opcode | POSIX call | musl/Linux it replaces |
|---|---|---|
| 0xB0/0xB1 | read/write | linux 63/64 |
| 0xB2/0xB3 | open/close | linux 56/57 |
| 0xB4 | yield | linux 124 |
| 0xB5 | exit | linux 93/94 |
| 0xB6 | getpid | linux 172 |
| 0xB7–0xB9 | lseek/fstat/ioctl | linux 62/80/29 |
| 0xBA/0xBB | mmap/munmap | linux 222/215 |
| 0xBC/0xBD | fork/waitpid | linux 220/260 |
| 0xBE–0xC1 | socket/bind/listen/accept | linux 198–202 |
| 0xC2 | mprotect (T8-1.2b) | linux 226 |
| 0xC3 | madvise (T8-1.2b) | linux 233 |
| 0xC4 | mremap (T8-1.2b) | linux 216 |
The 0xC2–0xC4 MM extensions are exactly what hardened_malloc needs beyond mmap/munmap (guard pages via mprotect, quarantine purge via madvise, large realloc via mremap).
Integration strategy
musl's generic syscall layer calls __syscallN(nr, …) with a Linux syscall number. Two ways
to target UOS:
- (A) Number-remap (chosen): substitute the Linux numbers musl uses with the
SYS_UOS_*opcodes insyscall_arch.h, keep musl's aarch64 SVC convention (x8=nr, x0–x5=args,svc #0). Simplest; this header sets it up. - (B) Glue-translate: keep Linux numbers in musl, translate in
__syscallNvia a switch. More code; not needed given (A).
Porting steps (the remaining multi-week work — T8-1.2c–f)
- Toolchain:
aarch64-linux-musl— buildroot (guests/linux-aarch64/buildroot-2025.02,BR2_TOOLCHAIN_BUILDROOT_LIBC="musl") or a prebuilt musl-cross. - musl
arch/uos: dropsyscall_arch.hin, provide the arch syscall-number table using theSYS_UOS_*remap, and the crt/start files for a UOS partition entry. - Personality loader (T8-1.2c): load a musl static ELF as a UOS partition (reuse
guest.cppload path or a lighter personality loader). - hello-world (T8-1.2d):
printf→SYS_UOS_write,malloc→hardened_malloc. - Wire hardened_malloc (T8-1.2e): link
libhardened_malloc.so(built for musl/aarch64,CONFIG_SELF_INIT=true) ahead of musl's malloc. - Gate (T8-1.2f): personality boots, hello-world allocates/frees via hardened_malloc,
make test(cross-built) green.
Verification done this session
arch/uos/syscall_arch.hcompiles for aarch64 (aarch64-linux-gnu-gcc).- Disassembly confirms correct opcode emission:
mov x8,#0xb1; svc #0(write),#0xba(mmap),#0xc2(mprotect),#0xc4(mremap). - The kernel-side MM syscalls (T8-1.2b) these glue onto are implemented in
kernel/src/core/abi/uos_posix_abi.cpp+kernel/src/core/mm.cppand compile/link for ARMv7.
Note on the LSP diagnostics
The host clang is x86_64 and flags Unknown register name 'x8' — a red herring; the file
targets aarch64 and compiles cleanly with the aarch64 cross-compiler (verified above).