Building and Running
uniOS builds with Meson using the LLVM toolchain as a cross build. Configuring without the cross file is a hard error.
Requirements
meson(>= 1.4.0) andninjaclang,clang++,ld.lld,lld-link,llvm-ar,llvm-stripnasmqemu-system-x86_64and OVMF UEFI firmware (for running)python3withPillowandCairoSVG(asset generation tools)
CI additionally installs clang-format, clang-tidy, and cppcheck for the developer checks.
Configure and Build
# Release image
meson setup build/release --cross-file toolchains/llvm.ini --buildtype release
meson compile -C build/release boot-disk iso
# Debug image
meson setup build/debug --cross-file toolchains/llvm.ini --buildtype debug
meson compile -C build/debug boot-disk iso
Debug builds keep boot logs, run registered kernel tests, and print boot-phase timings. Release builds boot straight to the desktop.
Build Outputs
Generated artifacts live in the build directory. Never hand-edit them; they are rebuilt by ninja targets.
| Artifact | Built by | Contents |
|---|---|---|
kernel.elf |
ld.lld with linker.ld |
Higher-half kernel, link base 0xffffffff80000000 |
BOOTX64.EFI |
lld-link (/subsystem:efi_application) |
Meridian UEFI loader (PE/COFF) |
unifs.img |
tools/mkunifs.py |
Read-only root filesystem image |
efi.img |
tools/build_efi_image.py --mode fat |
FAT32 EFI system partition image |
boot.img |
tools/build_efi_image.py --mode disk |
Raw disk: ESP + writable UNI_DATA FAT32 partition |
uniOS.iso |
tools/create_iso.py |
UEFI-bootable ISO9660 image |
See Boot images for the on-disk layouts.
Run Targets
All run targets boot boot.img in QEMU unless noted. The QEMU machine is q35 on Linux and pc on Windows; display is virtio-vga at 1920x1080 with 512 MiB RAM.
| Target | Description |
|---|---|
run |
Standard graphical run |
run-serial |
Serial console on stdio |
run-headless |
No VGA output, serial on stdio |
run-usb |
xHCI controller with USB keyboard and mouse |
run-qemu-net |
User-mode networking with an e1000 NIC |
run-qemu-full |
USB devices + network + serial |
run-esp-usb |
Boot efi.img from an emulated USB stick |
run-smp / run-smp4 |
2-core / 4-core boots (default targets are single-core) |
Suffix variants exist for most targets (-serial, -headless).
meson compile -C build/release run
Tests
Smoke tests boot the real image headless in QEMU and watch the serial log.
meson test -C build/debug --suite smoke --print-errorlogs
A run passes when the log shows first desktop frame submitted (and ktest suite passed in debug builds), and fails on KERNEL PANIC or ktest suite failed.
SMP suites are opt-in:
meson test -C build/debug --suite smoke-smp # 2 cores
meson test -C build/debug --suite smoke-smp4 # 4 cores (slow)
meson compile -C build/debug smp-soak # repeated 4-core boots
See Testing for the test framework and validation guidance.
Developer Checks
meson compile -C build/debug lint # cppcheck (optional tool)
meson compile -C build/debug analyze # clang-tidy (optional tool)
meson compile -C build/debug format # clang-format in place
CI runs lint and a format check (git diff --exit-code after format) as continue-on-error steps; keep the tree format-clean locally.
These targets are whole-tree: format rewrites every src/ and include/ source in place, and lint/analyze scan all sources. When working on a change, scope the checks to the files you modified — clang-format -i <file> and clang-tidy -p build/debug <file>.cpp — and do not commit reformatting or fixes for files you did not touch.
clang-tidy reads the curated .clang-tidy at the repository root (bugprone, clang-analyzer, and performance checks tuned for freestanding code, with the noisy or OS-hostile checks disabled). The file is required: without a config clang-tidy errors out with no checks enabled.
Adding Sources and Apps
Kernel and userspace source lists are computed by tools/meson_list_sources.py at meson setup time:
- A new kernel
.cppmay be invisible to an already-configured build directory. Runmeson setup --reconfigure build/debug, or add the file to the hardcoded keep-visible list near the top ofmeson.build. - New apps must be registered in the
app_sourcesmap inmeson.build. Apps link againstcrt0+ libc (+ libgui, unless the app isshellorinit) and are staged automatically as/bin/<name>.elf.
Nothing reaches the runtime image until it is staged into the build rootfs and unifs.img is regenerated, which the build does automatically.
Toolchain Notes
- Kernel:
--target=x86_64-unknown-none-elf,-mcmodel=kernel,-mno-red-zone,-mgeneral-regs-only(the kernel never touches vector registers so interrupts cannot corrupt FPU state),-fno-pie,-fno-exceptions,-fno-rtti,-fno-omit-frame-pointer. - Meridian: compiled for
x86_64-pc-windows-msvcand linked withlld-linkbecause UEFI applications are PE/COFF, not ELF. It is never linked withld.lld. toolchains/llvm.inisetshost_machine.system = 'none'and selectslldfor kernel linking.- The kernel build bakes
git rev-parse --short HEADin asGIT_COMMIT; it is visible in theaboutapp andSYS_GETSYSINFO.