Userspace Runtime
Userspace programs are native ELF binaries under src/usr/, linked at 0x400000 by src/usr/user.ld, and staged into the root filesystem as /bin/<name>.elf.
crt0 and Program Startup
src/usr/libc/crt0.asm:
- Aligns the stack to 16 bytes and clears
rbp. - Runs
__init_arrayglobal constructors. - Calls
main()with no arguments (no argc/argv/envp or aux vector is delivered yet). - Calls
exit(retval); a hang loop catches returns.
It also exports __sigret (SYS_SIGRETURN trampoline), which libc installs as the signal restorer.
libc Subset
src/usr/libc/ is a freestanding C/C++ subset:
- Syscalls: inline wrappers
syscall0..syscall6using the System V syscall ABI (number inrax, argsrdi/rsi/rdx/r10/r8/r9). Wrappers exist for the whole syscall surface — files, processes, memory, display, events, sound, shm, network, extended calls (futex/threads/epoll/memfd/mprotect). Time helpers:get_ticks/get_uptime/get_tsc_freq,sleep_ms(a realSYS_SLEEP_MSsleep), andsleep_until_ticksfor deadline-paced animation loops. - string:
strlen/strcpy/strcat/strncpy/strncat/strcmp/strncmp/strchr/strrchr/strstr/strtok(single global strtok state),memset/memcpy/memmovewith SSE2 16-byte aligned-store fast paths (forward and backward),memcmp,itoa(base 2-36, INT64_MIN-safe). - stdio:
printf/sprintf/snprintf/vsnprintfinto a 4 KiB stack buffer with raw fd writes — supports%s %d %i %u %o %x %X %p %c,-/0flags, widths,l/ll. No floats, noFILE*, no buffering. - stdlib: a region allocator over
SYS_MMAP— 64 KiB regions with magic-validated block lists, first-fit + split, coalescing free, fully-free regions unmapped, dedicated blocks above 32 KiB;callocwith overflow checks;reallocwith in-place growth;atoi; a simple LCGrand. - socket: POSIX-shaped wrappers over the network syscalls plus byte-order helpers.
- wav: userspace RIFF/WAV parser used by the shell
playcommand. - log: leveled
[sec.mmm] scope [mark] messagelogging to stdout. - config_utils:
key=valueconfig readers/writers used forSYSTEM.CFGand wallpaper settings. - math: freestanding
sqrt/sin/cos/tan/fabs/fmod(plusfvariants) — bit-seeded Newton sqrt (machine epsilon across the full double range) and range-reduced Taylor trig, so apps never hand-roll math. - cxx.cpp: global
new/deleteover malloc, a__cxa_pure_virtualfault handler, and the static-object runtime glue (__cxa_guard_acquire/release/abort,__cxa_atexit/__cxa_finalize/__dso_handle— single-threaded fast-path guards; static destructors are not run at exit because process teardown reclaims everything). - vec.h / str.h: header-only C++ containers for apps.
Vec<T>is a growable array for trivially-copyable elements (realloc + memmove growth;push/pop/insert/remove/resize/reserve, checkedat(), move-only ownership) that bounds-checks indexed access in debug builds and returns false on allocation failure instead of aborting.Stringis a growable NUL-terminated buffer (assign/append/equals, always-validc_str()). They replace fixed-size row/entry arrays so lists are no longer silently truncated.
libgui
src/usr/libgui/ is an immediate-mode GUI toolkit — no retained widget tree, no internal event loop:
- Surfaces:
Surfacewraps a BGRA buffer with width/height/pitch and an optional display-buffer handle. - Primitives: pixels, rectangles, rounded rectangles (8x8 supersampled corner masks), circles, alpha blits,
gui_fill_rect_blend(alpha-aware fill for dimming scrims). - Pixel core (
gui_pixops): SSE2 row primitives for XRGB8888 —pix_copy_row,pix_fill_row, premultiplied src-over blend rows (out = src + dst*(255-src_a)/255,/255via thex+128+((x+128)>>8)>>8approximation, bit-exact with the scalargui_blend_premultipliedreference). Cached stores only (targets are read back by the next pass).gui_blit_alphauses the blend row on non-overlapping spans and falls back to the directional scalar loop for in-buffer overlap;gui_fill_rectuses the fill row. A randomized self-test (gui_pixops_self_test) diffs SIMD against scalar; the WM runs it every boot in debug builds and behindSYSTEM_FLAG_WM_PIXEL_SELFTESTotherwise. - App widgets: header/nav/list/toggle/slider/segmented-control/text-field/button helpers, popup menus, cards/badges/metrics — the building blocks the apps compose. Buttons have a pressed variant (
gui_app_draw_button_ex) with centered labels; text fields reveal the text tail while focused so the caret stays visible past the field width. - Shared chrome: one drop-shadow recipe for every floating surface (
gui_draw_panel_shadow: popup menus, dialogs, shell overlays), one modal dialog (gui_dialog_layout+gui_draw_dialog: scrim from theoverlay_scrimpalette token, content-derived width, optional text field, Cancel/Confirm footer), one scrollbar (gui_draw_scrollbar+gui_scrollbar_w/gui_scrollbar_min_thumb), and one window-grade outline (gui_draw_chrome_frame/gui_draw_chrome_ring+gui_chrome_frame_colors): the same multi-layer frame the WM paints around windows — 1 px outline ring, tinted transition ring, inner highlight — shared by popup menus, dialogs, WM overlays and the dock so every floating edge is pixel-identical. - Design tokens: a fixed spacing scale (
gui_space_0_5/1/1_5/2/3/4= 4/8/12/16/24/32), radius scale (gui_radius_xs..xl= 4/6/8/12/16), and derived metrics (gui_app_row_h,gui_app_row_tall_h,gui_app_nav_h,gui_app_row_gap,gui_app_control_h, card-header/badge/dialog-button sizes) so every app and shell surface shares one rhythm. All floating surfaces (windows, popups, dialogs, overlays, dock) use thexlradius so their concentric frame layers — including card headers at radius-1 — stay pixel-aligned at the corners. - Theming: dark/light palettes synced from the shared registry, UI scaling helpers.
- Fonts (
.uof): atlas-based bitmap fonts with per-size loading, ASCII fast tables, alpha LUTs, measurement and clipped text drawing, built-in bitmap fallback. - Images:
.uoicicon,.uocucursor, and.uowpwallpaper loaders with entry selection by size/scale/variant, including a QOI decoder and scaled-cover blitting. - Window protocol: registration, resize handling, damage commits — see Window manager.
- System integration:
gui_set_window_titleupdates the window's titlebar live (the WM recomposes it on change);gui_notifyposts a toast through the registry (notify_generation) that the WM displays like its own notifications.gui_window_title_matchesis the shared app-identity test for registry window slots: a window matches its app on an exact title or adetail - Appsuffix, so apps that rename their window (Files, Latitude) stay discoverable by the dock, menubar, and WM launchers. - App menus: a focused app builds a
MenuModellocally (gui_menu_model_reset/add_menu/add_item/add_separator) and publishes it withgui_menu_publish(registry slot guarded by an odd/even seq protocol); the menubar renders it and dispatches activated item IDs through the window entry, which the app consumes withgui_menu_take_command. IDs >=MENU_CMD_RESERVED_BASEare menubar-owned.gui_clipboard_copy/gui_clipboard_pastemove text through the registry clipboard (4095-byte cap, seq-stable reads), shared by all apps. - Frame waits:
gui_wait_frame/gui_poll_framewrap display event waits for FLIP_COMPLETE/VBLANK.
libapp
src/usr/libapp/ is the application runtime and widget kit that every graphical app is built on. It owns the window, the double-buffered canvas, the event loop, resize/theme/menu/focus plumbing, and damage publishing, so an app supplies only drawing and interaction logic.
- Runtime (
app.h): an app fills anAppConfig(title, size, min size,WIN_FLAG_*, pacing, callbacks) and callsapp_run. The runtime registers the window, allocates a private backbuffer canvas, and loops.on_draw(canvas)paints a whole frame into the canvas; the app marks what changed withapp_invalidate/app_invalidate_alland the runtime copies only those rects to the window and publishes damage.on_eventreceives input and lifecycle events (close is handled by the runtime as a clean exit; resize arrives after the window and canvas were re-synced; scroll arrives after invalidation).on_menugets menubar commands,on_menusrebuilds the model at startup and on focus gain (callapp_publish_menusto refresh otherwise),on_settingsfires after a registry settings-generation change and theme re-sync, andon_idleruns each iteration for periodic work. - Pacing:
frame_ticks == 0runs event-driven —on_drawonly when something was invalidated, sleepingidle_ms(default 16) when idle.frame_ticks > 0runs continuous —on_drawevery frame, paced withsleep_until_ticksand catch-up (app_set_frame_ticksadjusts the interval live). - Scrollable content:
app_set_content_sizegrows the window backing and canvas so the whole content is retained and the WM scrolls it (app_scroll_x/yread the offset); call it at the start of a frame, before drawing into the grown area. - Manual mode: apps with an extra event source use
app_create/app_pump/app_commit/app_destroyinstead ofapp_runto interleave GUI plumbing with their own loop — the terminal does this around its epoll shell pipe and incremental renderer, withon_drawleft unset so it keeps drawing to the window directly. - Widgets (
widgets.h): stateful controls over the immediate-mode libgui primitives. Each owns its hover/press/focus/value state;*_eventreturnsWIDGET_*bitmasks (WIDGET_CHANGED= invalidate the rect) and*_drawrenders. Provided: buttons (release-to-apply with drag-away cancel, optional fire-on-down), toggle rows, sliders (live drag withgui_app_slider_track_recthit-testing and a release-to-persist click), segmented controls, text fields (caller-owned buffer, Enter/Escape, click-outside blur), popup menus (viewport-clamped placement), modal dialogs (confirm/cancel/dismiss with an optional field), help overlays, a scroll view (wheel + draggable vertical/horizontal thumbs, track page-jumps,widget_scroll_view_reveal_yfor keyboard nav), and a shared rect hit-test helper. - Standard menus and shortcuts (
app.h):app_menus_add_editpublishes a uniform Edit menu (Undo/Redo/Cut/Copy/Paste/Delete/Select All) with accelerators and per-entry enable flags under sharedAPP_CMD_*IDs;app_menus_add_helppublishes the standard Help menu (an optional tips entry plus the reserved About uniOS item);app_edit_shortcutmaps a Ctrl+letterEVT_KEY_DOWNto itsAPP_CMD_*. Apps with non-standard bindings (the terminal uses Ctrl+X for Copy because Ctrl+C is SIGINT) keep their own menu. - Settings (
app.h):app_setting_load_int/app_setting_save_intpersist per-app toggles in/data/APPS.CFG, kept separate fromSYSTEM.CFGso app writes never race WM/Preferences persistence of system settings.
Apps that bypass libapp still poll kernel events directly with poll_event/wait_event (SYS_GET_EVENT).
libmedia
src/usr/libmedia/ is a freestanding image codec library with no libc file I/O: callers load a whole file into memory and decode from the buffer.
- API (
media_image.h):media_image_decode(data, size, out)dispatches on magic bytes,media_image_scaledoes bilinear resize,media_image_freereleases the result. Output is straight-alpha ARGB8888 (A<<24 | R<<16 | G<<8 | B). - Codecs: PNG (zlib/DEFLATE, all color types, tRNS, 1/2/4/8/16-bit), baseline JPEG (Huffman, fixed-point IDCT, bilinear JFIF chroma upsampling, BT.601 full-range conversion), GIF (bounded LZW, interlace, transparency as alpha-zero palette color), BMP (24/32-bit BI_RGB), QOI.
- Limits:
MEDIA_MAX_DIMENSION16384,MEDIA_MAX_PIXELS16 Mi pixels (64 MiB ARGB). Progressive JPEG and Adam7 PNG are rejected; allocations go through libcmalloc. - Verified by a host-side harness against PIL references and hand-crafted malformed inputs.
Building Apps
Per meson.build:
crt0is assembled fromcrt0.asm(NASM elf64).libc,libgui,libapp, andlibmediaare static libraries built freestanding (-fno-exceptions -fno-rtti -mno-red-zone, no stack protector, no PIE).- The
app_sourcesmap lists each app directory; sources are globbed at setup time. Apps linkcrt0 + libc(shell,init) orcrt0 + libc + libapp + libgui(everything else) with--whole-archivethroughld.lldanduser.ld.libmediais linked after--no-whole-archivefor apps that need it (currentlyfilesandimageviewer), so only referenced codec objects are pulled in. - Each app ELF is staged as
/bin/<name>.elfand packed intounifs.img.
Current apps: shell, init, wm, menubar, dock, files, terminal, latitude, about, preferences, clock, calendar, calculator, imageviewer. Adding an app requires a map entry (see Building and running).