LeonOS Documentation

Syscalls

LeonOS targets the native Linux v6.12 x86-64 user ABI. The current full status is recorded in LINUX_ABI_SYSCALLS_2026-09-07.csv and LINUX_ABI_PROGRESS_2026-09-08.md. The tables below are an extension reference and historical subset, not a complete compatibility claim.

Login system information

The dynamic MOTD uses uname, time/localtime_r, Linux sysinfo, statvfs, and the Linux SIOCGIFCONF/SIOCGIFFLAGS network ioctls. Terminal width comes from TIOCGWINSZ, including PAM_TTY when PAM redirects stdout to a pipe. No private syscall is used or added.

sysinfo.loads now reports real 1/5/15-minute exponentially weighted runnable load averages with Linux's Q16 scaling. The BSP samples non-idle RUNNING/READY tasks every five seconds under the scheduler lock. Current BLOCKED tasks are sleepers/waiters; the scheduler does not have a separate uninterruptible I/O state. Memory percentage is allocated physical RAM (totalram - freeram); root usage excludes blocks reserved from ordinary users, like df.

/etc/motd and /etc/motd.zh_CN hold the short, editable link footer. /usr/lib/leonos/motd honors the PAM user's .hushlogin before running the standard-interface helper motd-status. It selects one language using LC_ALL, LC_MESSAGES, then LANG. Versions, times and state are read at login; unavailable measurements are labelled rather than invented. UTF-8 cell widths determine aligned 3/2/1-column layouts and wrapping.

Entry Convention

musl enters the kernel with the native syscall instruction. The LeonOS extension assembly helpers in userland/libc/src/syscall.S translate C call arguments into the syscall ABI:

Return values follow the kernel convention:

The public userland numbers and wrappers are in:

The kernel-side numbers and errno constants are in:

Implemented Syscall Table

NumberNamelibc wrapperNotes
0readreadReads files, directories, stdin PTY input, and directory entries.
1writewriteWrites files, stdout/stderr console output, and PTY output.
2openopenOpens files, directories, and synthetic /dev/* device nodes.
3closecloseCloses task file descriptors above the stdio/device range.
4statstatStats a path into struct leonos_stat.
5fstatfstatStats an open file descriptor.
8lseeklseekSupports files and directory cursors.
9mmapmmapSupports private anonymous/file mappings and writable /dev/fb0 framebuffer mappings.
11munmapmunmapSupports whole and partial unmapping of existing VMAs.
16ioctlioctlDevice-ABI extension point: Linux fbdev/block/evdev/OSS/termios requests, LEONOS_FBIOBLIT, GPU extensions on /dev/gpu, net control on an AF_INET fd, and driver control on /dev/driverctl.
24sched_yieldsched_yieldYields the current task if another task can run.
35nanosleepsleep_mslibc passes milliseconds; kernel also accepts a Linux-like timespec pointer.
39getpidgetpidReturns the current scheduler PID.
57forkforkCreates a copy-on-write child; the child receives zero.
58vforkvforkCurrently has the same copy-on-write behavior as fork.
59execveexecveReplaces the current process image with an ELF program.
60exitexitReleases process-owned files, windows, PTYs, and exits with a code.
61wait4wait4Waits for a child and writes a Linux-style shifted status.
79getcwdgetcwdCopies the task current directory.
80chdirchdirChanges the task current directory after path lookup.
82renamerenameRenames exFAT, FAT32, or ext2 files/directories within one filesystem.
83mkdirmkdirCreates an exFAT, FAT32, or ext2 directory.
84rmdirrmdirRemoves an empty exFAT, FAT32, or ext2 directory.
87unlinkunlinkRemoves an exFAT, FAT32, or ext2 file.

GPU Calls

GPU extensions use syscall 16 (ioctl) on a descriptor opened for /dev/gpu (legacy fd 3 calls are translated to that node by libc). The commands in include/leonos/gpu.h are LEONOS_IOCTL_GPU_INFO (0x4c475001), CREATE (0x4c475002), RENDER (0x4c475003), DESTROY (0x4c475004) and DIAGNOSTICS (0x4c475005). DIAGNOSTICS returns the latest device render-failure snapshot only to its owner. Requests carry exact structure size and ABI version 1; pointers are 64-bit user addresses. Invalid ranges return -EFAULT, invalid versions or counts return -EINVAL, and unavailable hardware returns a negative SVGA status. Only the creator can use a render handle. See SVGA3D.md for details.

File and Directory Calls

Paths use Unix syntax such as /usr/lib/leonos/apps/desktop/desktop.elf. Relative paths are resolved against the task current directory by fs_permissions_resolve() in the kernel, which also checks directory search permission on every component it walks. Inputs containing : are rejected.

Open flags are defined in include/leonos/fs.h:

Seek modes are:

Directory reads return one struct leonos_dir_entry per successful read. The higher-level leonos_list_dir() libc helper can also list a directory into a caller-provided array.

Memory Calls

mmap(addr, len, prot, flags, fd, offset) records a task VMA and maps pages according to the mapping type.

Supported protection bits:

Supported mapping flags:

Anonymous mappings require:

File mappings currently require:

File mappings are lazy. The page fault handler maps file-backed pages on first read. Writable file-backed mappings are still -ENOSYS.

If a page fault cannot be recovered by the lazy mapping path, kernel-mode faults and the desktop window-server fault path still go to bugcheck. Ordinary Ring-3 applications are terminated instead: the kernel releases their open file state, destroys their GUI/PTY ownership, records exit code 0x8000000e, schedules the next runnable user task, and posts an Application Page Fault desktop window with PID, path, user, fault address, error flags, RIP/RSP/RBP, general registers, CS, RFLAGS, and tick details.

munmap(addr, len) requires a page-aligned start address inside user space and an existing VMA that fully covers the requested range. It can trim the front or back of a VMA, remove a whole VMA, or split a VMA in the middle.

The libc heap allocator uses anonymous private mmap arenas and may release large page-aligned free blocks with munmap.

Process and Scheduler Calls

fork() creates a copy-on-write child with inherited file descriptors. The parent receives the child PID and the child receives zero. execve(path, argv, envp) validates and copies the user argument vectors, then replaces the current process image while preserving its PID, working directory, identity, PTY and descriptors not marked FD_CLOEXEC. Use fork() followed by execve() to start a child; GUI applications can use leonos_spawn_argv().

wait4(pid, status, options, rusage) waits for a child process. options and rusage are accepted for ABI shape but are not a full Linux wait implementation.

nanosleep has two call shapes:

Ioctl Groups

ioctl(fd, request, arg) is the extension point for device ABIs. The private LeonOS ioctl multiplexers (auth, GUI windows, appearance, system info, device list, audio, network sockets, text layout, PTY, signal) have been removed; those services now use Linux UAPI device ioctls, standard syscalls, or AF_UNIX service protocols. What the kernel still accepts, keyed by the /dev node the descriptor was opened on:

The legacy fd 3 control channel is translated by libc to the matching /dev node for older binaries. System inventory (leonos_device_list()), auth (include/leonos/auth.h over /etc/passwd + PAM), signals (rt_sigaction/rt_sigprocmask), and appearance (windowd messages) are service/libc APIs without any ioctl request codes.

Networking

The network ABI is defined in include/leonos/net.h. Legacy configuration and diagnostic helpers are wrapped by libc as:

The TCP client socket ABI is wrapped as:

IPv4 values are host-order packed addresses. For example, 10.0.2.2 is 0x0a000202.

The kernel supports a polling Intel e1000 MMIO driver, ARP, IPv4, ICMP Echo, UDP transmit/receive for DNS, DNS A record lookups, a small ARP cache, and active-open TCP client sockets over standard socket syscalls. At boot the kernel brings the interface up with no address; IPv4 configuration comes exclusively from the userspace leonos-dhcp OpenRC service (BusyBox udhcpc -f -i eth0). Its hook applies the address with ifconfig/route (the kernel records it through the standard SIOCSIF* ioctls) and publishes the lease atomically at /run/leonos/dhcp-lease; libc merges that file into leonos_net_config() results as the DHCP source. If DHCP never succeeds the interface simply stays unconfigured. QEMU user-network guests normally receive 10.0.2.15/24 with gateway 10.0.2.2 from the built-in lease server.

netctl.elf can still request a renew after the desktop is running; leonos_net_dhcp_renew() restarts the leonos-dhcp service through rcctl.elf, which the libc elevates via the sudo path for non-root callers. Non-admin users may read network status and use DNS/HTTP/socket APIs. The kernel-side LEONOS_NET_CONTROL_DHCP operation returns EOPNOTSUPP (the in-kernel DHCP client was removed); lease renewal is purely the OpenRC service. netctl.elf also queries leonos_net_connections and displays TCP client sockets in SYN_SENT, ESTABLISHED, TIME_WAIT, or CLOSED. Administrators and trusted service tasks see the full socket table; normal users see only connections owned by their uid.

Background DHCP is handled by the OpenRC service leonos-dhcp (root-owned udhcpc); leonos_net_dhcp_renew() restarts it via rcctl-style leonos_openrc_run("leonos-dhcp", "restart") and then reads the lease the hook publishes at /run/leonos/dhcp-lease. The legacy serviced.elf background retry loop and /run/leonos/services.state are gone; the desktop servicemgr surfaces service state instead.

leonos_socket_tcp() is a thin wrapper over socket(AF_INET, SOCK_STREAM, 0) and returns a real socket fd. leonos_socket_connect accepts a host name or IPv4 literal, resolves DNS A records when needed, tries each returned address, and records the selected remote IP and local port. leonos_socket_send and leonos_socket_recv adapt the socket fd to the legacy status-record shape with per-call timeouts. Closing uses standard close(2) on the fd.

include/leonos/http.h provides the higher-level userland HTTP client: leonos_http_get, leonos_http_request, and leonos_http_resolve_url. The client uses the socket wrappers, follows bounded redirects, decodes chunked transfer responses, exposes response headers, content type, body length, final URL, redirect count, and truncation flags. It sends plain HTTP/1.1 for http://, and uses Mbed TLS 2.28.8 for TLS 1.2, CA-chain, hostname, and clock validation of https://. httpget.elf and browser.elf use this library for both schemes. The older fixed-buffer leonos_net_http_get helper remains as a compatibility wrapper for small diagnostic callers.

downloadmgr.elf also uses the HTTP client. It is currently fixed-buffer and reports oversized responses through the truncation flag instead of streaming large files incrementally.

The LEONOS_NET_CONTROL_IOCTL requests return 0 when the control structure was processed. Per operation results are reported in the structure status field. Timeouts are bounded by the kernel even if a larger value is requested; socket, HTTP, DNS, and DHCP paths currently cap requested waits at 10000 ms.

Authentication and Authorization

The authentication ABI is defined in include/leonos/auth.h. libc exposes:

Interactive login runs through the standard PAM stack in login.elf (pam_leonos_password verifies /etc/shadow), not through a libc leonos_auth_login wrapper. Successful login updates the current desktop session identity in the scheduler: uid, role, session_id, username, and home are attached to the desktop task and inherited by child applications. Logout clears the session identity and kills ordinary user tasks in the session, then desktop returns to login.elf.

The kernel makes every file, task-kill, user-management, and installer-storage decision itself in kernel/ntclks/permissions.c, against the permissions the storage layer reports: the LEONACL.SYS sidecar on exFAT and FAT32, native inode fields on ext2 and tmpfs, and fixed modes for PTY and device nodes. The mapping is:

Normal users can access their own home through Owner permissions and shared temporary files through the /tmp default ACL. Bundled help files under /docs are treated as a system tree: normal users receive read/execute access by default, while administrators retain full control. Administrators can manage users and can take ownership or repair corrupt ACL metadata. Shutdown and reboot remain available to any logged-in user.

Current behavior and limitations

Standard C/POSIX wrappers, pthread and signals use musl. The kernel supports native signal frames, a clone/futex thread subset and Unix STREAM/DGRAM/ SEQPACKET sockets including SCM_RIGHTS. Tested behavior and outstanding flags, errors, lifecycle and concurrency cases remain itemized in the ABI ledger.