Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

B2 — Linux AArch64 syscalls vs ctos SVC

Track B child issue #42 (parent #40). Frame: ADR-031. Freestanding ABI: ADR-021 / syscall.md.

This page is a gap map. It does not add Linux syscall numbers to src/. It does not decide compat layer vs reimplement vs never (B6 / #46). Not claiming Linux userspace. File presence of this note is not a Linux ABI.

Probe (what Verified means here)

ClaimProbeStatus
Linux AArch64 numbers in the tableRead include/uapi/asm-generic/unistd.h from Linux v6.10 (torvalds/linux). AArch64 uses that generic table (svc #0, number in x8).Document inspection
ctos public / reserved SVC surfaceRead src/syscall.rs (SYS_* 16–23) + ADR-021 + ADR-027 + reserved 0–2 in ADR-013 on this treeDocument inspection
Linux userspace / musl / Alpine on the guestNo such serial markerNot claimed. Ledger “Guest runs host apps” stays Planned.

A later kernel qemu-smoke is a different row. This mile did not edit src/.

Status words

StatusMeans
presentSame Linux AArch64 number and comparable semantics, callable by a Linux svc #0 / x8 binary with no translation.
partialA Track A SVC exists with a related effect. Number, calling convention, args, or meaning still differ.
absentNo ctos analog. B3–B6 may still discuss a named subset. Not a promise to implement.
never-per-ADR-031Would imply a full Linux host / distro / container promise that ADR-031 already ruled out (guest OCI also ADR-029).

No Linux AArch64 syscall is present. The convention and the number space both miss.

Calling convention (the first gap)

ItemLinux AArch64ctos (ADR-021)
Instructionsvc #0 (immediate is always 0)SVC #<n> — n is the number
Number registerx8Immediate (not x8)
Argsx0–x5x0, x1, x2 only
Returnx0; negative Linux errnox0; 0 or u64::MAX reject (not errno)
Unknown number-ENOSYSUnhandled immediate parks (fail-closed)

Linux svc #0 collides with the ADR-013 first-mile probe (SVC #0). ADR-021 rejected adopting the Linux convention for that reason. A translation shim would be a later epic after B6 — not this page.

Public ctos numbers 16–26 are also not the Linux meaning of those integers:

Immediate / x8Linux AArch64 (v6.10 generic)ctos
0io_setupADR-013 first-mile return (reserved)
1io_destroyADR-013 standing announce (reserved)
2io_cancelADR-013 standing restore (reserved)
16fremovexattrexit
17getcwduart_write
18lookup_dcookieyield
19eventfd2fs_create
20epoll_create1fs_open
21epoll_ctlfs_read
22epoll_pwaitfs_write
23dupfs_close
24dup3net_mac
25fcntlnet_ping
26inotify_init1net_udp_dns

You cannot “just accept Linux numbers” in the SVC immediate, and you cannot treat today’s 16–26 as Linux.

ctos surface (inspection)

Reserved 0–2 are probe-only. Public:

ctos #NameRelated Linux name(s)Why not present
16exitexit (93), exit_group (94)Ends the standing EL0 trip; no process table; not exit_group.
17uart_writewrite (64) to a TTYPL011 only; no fd; cap 64; \n → \r\n.
18yieldsched_yield (124)Dispatch-only hint; does not run EL1 sched::yield_now (ADR-010).
19fs_createopenat (56) + O_CREATFlat memfs name; no dirfd, flags, or mode.
20fs_openopenat (56)Existing name only; FAT /probe and /hello are the known on-disk files.
21fs_readread (63)Handle 1–4; cap 64; no stdin. UART RX is kernel-side, not this SVC.
22fs_writewrite (64)memfs only (FAT write is ReadOnly); cap 64; not fd 1/2.
23fs_closeclose (57)Drops the handle; the file stays. Four handles max.
24net_mac—Guest MAC copy; not Linux dup3 (24). Kernel owns NIC (ADR-068).
25net_ping—Quiet ICMP echo; not Linux fcntl (25).
26net_udp_dns—Quiet UDP DNS probe; not Linux inotify_init1 (26). DNS bait only (ADR-071).

Unknown immediates park. Not POSIX. Not Linux VFS.

Gap table (representative Linux AArch64 set)

Numbers from Linux v6.10 asm-generic/unistd.h. AArch64 has no fork, open, creat, dup2, pipe, poll, or select syscalls — those are clone / openat / dup3 / pipe2 / ppoll / pselect6. __NR_syscalls in that header is 463. This table is a slice, not the full list.

Process and lifetime (B3)

Linux #Namectos statusNotes
93exitpartialAnalog SYS_EXIT 16. Halts the EL0 trip and returns to the EL1 caller. Status is recorded. Not a thread/process exit.
94exit_groupabsentNo process group. musl/glibc CRT usually ends here.
—forkabsentNot in the Linux AArch64 table. Userspace fork() is clone. Stance: ADR-035 / B3 / #43.
220cloneabsentNo child address space, no CLONE_*. Standing EL0 (ADR-024) is one loaded trip, not clone (ADR-035). CLONE_NEW* is never-per-ADR-031 (see namespace rows).
435clone3absentSame class as clone.
221execveabsentA3 maps freestanding PT_LOAD and rejects PT_INTERP. A9 FAT /hello is an EL1 load path, not execve (ADR-035). ELF / auxv / interpreter gap: ADR-033 (B4).
281execveatabsentSame class as execve.
260wait4absentNo child to wait for. ADR-035.
95waitidabsentADR-035.
129killabsentNo pid / signal delivery.
172getpidabsentNo process table.
178gettidabsentNo tid.
96set_tid_addressabsentTypical musl/glibc _start requirement.

File descriptors and I/O (B5 concept compare: ADR-034)

Linux #Namectos statusNotes
56openatpartialfs_open 20 / fs_create 19. Path is / + [a-z0-9_-] (1–15). No dirfd, O_*, or mode. At most 8 files. ADR-027.
437openat2absentNo open_how.
57closepartialfs_close 23. File stays after close.
63readpartialfs_read 21. Cap 64. No fd 0 / line discipline.
64writepartialuart_write 17 (console, no fd) or fs_write 22 (memfs). Neither is POSIX write(1, …).
65 / 66readv / writevabsentNo iovec.
67pread64absentHandle offset exists inside VFS; no positioned SVC.
62lseekabsentNo seek SVC.
29ioctlabsentNo TTY (TCGETS / TIOCGWINSZ), no block ioctl. PL011 is kernel-owned.
25fcntlabsentNo F_GETFL / F_DUPFD.
23 / 24dup / dup3absentHandles 1–4 only; no dup. Linux 23 is dup; ctos 23 is fs_close.
59pipe2absentNo pipes.
61getdents64absentNo directory listing. Flat namespace.
79 / 80newfstatat / fstatabsentNo stat.
291statxabsentNo stat.
48faccessatabsent
34mkdiratabsentNo directories.
35unlinkatabsent
38renameatabsent
49chdirabsentNo cwd.
17getcwdabsentLinux 17 is getcwd; ctos 17 is uart_write.

Memory (loader / libc heap)

Linux #Namectos statusNotes
214brkabsentKernel first-fit heap is EL1 (ADR-009). No user program break.
222mmapabsentA3 maps PT_LOAD at load time into the user window. No mmap SVC. Anonymous / file maps are out.
215munmapabsent
226mprotectabsentImage W^X is a kernel policy (ADR-015), not an EL0 syscall.
233madviseabsent

Scheduling, time, sync, identity

Linux #Namectos statusNotes
124sched_yieldpartialAnalog yield 18 is a recorded hint and ERET to EL0. It does not switch EL1 tasks.
101nanosleepabsentCNTP tick is EL1.
113clock_gettimeabsentNo guest clock SVC. CNTPCT probes are kernel/NFR-07.
98futexabsentNo user futex.
99set_robust_listabsentTypical libc _start.
134 / 135 / 139rt_sigaction / rt_sigprocmask / rt_sigreturnabsentLower-EL IRQ still parks. No POSIX signals.
73ppollabsent
160unameabsent
167prctlabsent
163 / 261getrlimit / prlimit64absent
278getrandomabsent

Sockets (not a Track B promise)

Linux #Namectos statusNotes
198socketabsentNo virtio-net, no stack. Same class as the host-apps “sockets” gap. Not a B2 implementation item.

Namespace / mount — never on this track

Linux #Namectos statusNotes
97unsharenever-per-ADR-031Linux namespaces. Guest OCI is a non-goal (ADR-029).
268setnsnever-per-ADR-031Same.
40mountnever-per-ADR-031Linux mount/overlay class. A7 FAT is not mount(2). Concept compare: ADR-034 (B5). Must not grow POSIX mount.
39umount2never-per-ADR-031Same.
41pivot_rootnever-per-ADR-031Same.

clone with CLONE_NEWNS / CLONE_NEWPID / CLONE_NEWNET is the same never-per-ADR-031 class. A later clone subset, if B6 ever names one, would still exclude those flags.

If a subset is ever useful (not a decision)

Issue #42 asked to prioritize a minimal subset if any. This is a research hint for B6, not an implementation list.

  1. In-tree libctos apps need no Linux numbers. A1–A9 already have exit / uart_write / yield / memfs / FAT /hello. Keep that path.
  2. A static musl “hello” is not a small subset. Besides convention translation, typical CRT wants set_tid_address, exit_group, brk or mmap, often write on fd 1, uname / geteuid-class probes, and signal/prctl stubs. That is already a libc-shaped surface. ADR-031 rejected “runs musl / Alpine” as a Track B promise.
  3. The smallest named research slice (only if B6 chooses a compat path, and only with a probe) would still be: convention translation + exit/exit_group + write to a console fd. openat/read/close are the next file slice. brk/mmap are the next heap slice. clone/execve/wait4 are the process gap (ADR-035); they are not a small add-on.
  4. Do not start with ioctl, sockets, or mount. ioctl is a device encyclopedia. Sockets need a stack. mount/unshare stay never-per-ADR-031.

B3 is Documented (ADR-035). B4 is Documented (ADR-033). B5 is Documented (ADR-034). They must not add Linux numbers to src/. B6 may choose never.

Honesty

  • Analysis Verified means: this file was read against src/syscall.rs and Linux v6.10 unistd.h. It is not ABI Verified and not Linux userspace.
  • Do not say “ctos implements write(2)” because uart_write or fs_write exists.
  • Do not mint FR-16+ / NFR-15+. Frozen set: fr-nfr.md.
  • Guest containers stay non-goal. Host docker-smoke.sh is unrelated.

Roadmap: track-b.md. Extra stance: host-apps.md.