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

RustOS Documentation

English | 한국어

English

RustOS is a Rust-built hybrid microkernel with native binary compatibility for Linux ELF and Windows PE programs. The kernel keeps only the mechanisms that require ring0 — trap entry, paging, scheduling, IRQ/MMIO/DMA bridges, and a small set of gated brokers — and pushes everything else into userspace services. A built-in Wayland compositor in uiserver provides the desktop surface for both native and PE clients.

This book is split by audience:

  • Start: build, run, debug, and follow the OS execution flow.
  • Architecture: how the microkernel and services fit together, the Wayland UI server, the compat path, and repo structure/logging rules.
  • OS Developer APIs: kernel crate APIs, cargo xtask, the RUSTOS.package.toml manifest, and runtime control.
  • Guides: end-to-end recipes for adding services, apps, and drivers.
  • Reference: stable paths and environment variables.
  • AI Agent Reference: compact machine-oriented context under docs/ai/.

Recommended reading order:

  1. Getting Started
  2. Execution Flow
  3. Microkernel Overview
  4. Userspace Services
  5. Userspace Compatibility
  6. UI Server & Wayland
  7. Structure Guide
  8. Kernel API
  9. xtask API
  10. Package Manifest API
  11. Logging Guide
  12. Fault Injection

한국어

RustOS는 Rust로 작성된 hybrid microkernel이며, Linux ELF와 Windows PE 실행 파일에 대해 native binary compatibility를 목표로 합니다. 커널은 ring0가 반드시 필요한 mechanism — trap entry, paging, scheduling, IRQ/MMIO/DMA bridge, 그리고 소수의 gated broker — 만 남기고 나머지는 모두 userspace service로 옮깁니다. uiserver에 내장된 Wayland compositor 가 native client와 PE client 모두에게 desktop surface를 제공합니다.

이 문서는 대상별로 나뉩니다.

  • Start: build, run, debug, 그리고 OS 실행 흐름.
  • Architecture: microkernel과 service들이 어떻게 맞물리는지, Wayland UI server, 호환 경로, repo 구조와 logging 규칙.
  • OS Developer APIs: kernel crate API, cargo xtask, RUSTOS.package.toml manifest, runtime control.
  • Guides: service / app / driver를 추가하는 끝-끝 절차.
  • Reference: 안정적인 path와 environment variable.
  • AI Agent Reference: docs/ai/ 아래의 짧은 machine-oriented context.

추천 읽기 순서:

  1. 시작하기
  2. 실행 흐름
  3. Microkernel Overview
  4. Userspace Services
  5. Userspace Compatibility
  6. UI Server & Wayland
  7. Structure Guide
  8. Kernel API
  9. xtask API
  10. Package Manifest API
  11. 로깅 가이드
  12. Fault Injection

Getting Started

English | 한국어

English

Prerequisites

Ubuntu/Debian baseline:

sudo apt update
sudo apt install -y rustup gcc nasm qemu-system-x86 ovmf mingw-w64 grub-efi-amd64-bin grub-common gnupg

rustup default nightly
rustup component add rust-src llvm-tools-preview
rustup target add x86_64-unknown-linux-gnu

Default firmware path:

vendor/firmware/ovmf/OVMF.fd

Use OVMF_PATH=/path/to/OVMF.fd to override it.

Build

cargo xtask check
cargo xtask build

cargo xtask build validates layering, builds boot/user/kernel artifacts, builds modules and compatibility assets, stages the boot image, and writes runtime registries. If RUSTOS_GRUB_* is unset, xtask creates a local development GRUB signing key under build/dev-grub-gpg and exports build/dev-grub.pub. Release signing keys should still stay outside the repository and be supplied through the environment.

Run

cargo xtask run

cargo xtask run expects an existing build/image. Re-run cargo xtask build or cargo xtask stage after changing image contents.

Useful Run Modes

CommandPurpose
cargo xtask run -- --no-rebootPass raw QEMU args after --.
cargo xtask run --profile nvmeBoot using the NVMe QEMU profile.
cargo xtask run --accel-profile kvmUse KVM acceleration and host CPU profile.
cargo xtask run --usb-inputAttach USB keyboard/tablet devices for HID testing.
cargo xtask run --qemu-log intWrite QEMU interrupt trace to logs/qemu_interrupt.log.
cargo xtask run --debugcon stdioRoute debugcon to the terminal.

Debug

cargo xtask debug

This starts QEMU with -s -S and writes logs/rustos-debug.gdb.

Probe Display

cargo xtask probe-display

This uses the headless display probe path and is useful for framebuffer, surface, and dirty-rect regressions.

한국어

준비

Ubuntu/Debian 기준:

sudo apt update
sudo apt install -y rustup gcc nasm qemu-system-x86 ovmf mingw-w64 grub-efi-amd64-bin grub-common gnupg

rustup default nightly
rustup component add rust-src llvm-tools-preview
rustup target add x86_64-unknown-linux-gnu

기본 firmware 경로:

vendor/firmware/ovmf/OVMF.fd

다른 firmware를 쓰려면 OVMF_PATH=/path/to/OVMF.fd를 지정합니다.

빌드

cargo xtask check
cargo xtask build

cargo xtask build는 layering 검사, boot/user/kernel artifact 빌드, module과 compatibility asset 빌드, boot image staging, runtime registry 생성을 수행합니다. RUSTOS_GRUB_* 값이 없으면 xtask가 build/dev-grub-gpg 아래에 로컬 개발용 GRUB signing key를 만들고 build/dev-grub.pub를 export합니다. release signing key는 여전히 repository 밖에 두고 환경 변수로 주입해야 합니다.

실행

cargo xtask run

cargo xtask run은 기존 build/image를 사용합니다. image 내용이 바뀌면 cargo xtask build 또는 cargo xtask stage를 다시 실행하세요.

유용한 실행 모드

CommandPurpose
cargo xtask run -- --no-reboot-- 뒤의 값을 raw QEMU arg로 전달합니다.
cargo xtask run --profile nvmeNVMe QEMU profile로 부팅합니다.
cargo xtask run --accel-profile kvmKVM acceleration과 host CPU profile을 사용합니다.
cargo xtask run --usb-inputHID test용 USB keyboard/tablet device를 붙입니다.
cargo xtask run --qemu-log intQEMU interrupt trace를 logs/qemu_interrupt.log에 기록합니다.
cargo xtask run --debugcon stdiodebugcon을 terminal로 보냅니다.

디버그

cargo xtask debug

QEMU를 -s -S로 시작하고 logs/rustos-debug.gdb를 생성합니다.

Display Probe

cargo xtask probe-display

headless display probe path를 사용합니다. framebuffer, surface, dirty-rect regression을 확인할 때 유용합니다.

Execution Flow

English | 한국어

English

Host Flow

cargo xtask build
  -> validate workspace layering
  -> build Multiboot2 nucleus
  -> sign nucleus.elf
  -> build GRUB EFI boot manager
  -> build userspace services/apps
  -> build modules and compatibility artifacts
  -> stage build/image
  -> write generated registries

cargo xtask run does not rebuild the image. It launches QEMU against the current build/image.

Staged Image Flow

build/artifacts/* + assets/image/* + vendor/*
  -> build/image/EFI/BOOT/BOOTX64.EFI
  -> build/image/nucleus.elf
  -> build/image/nucleus.elf.sig
  -> build/image/services/*
  -> build/image/apps/*
  -> build/image/system/drivers/*
  -> build/image/system/registry/*

Stage uses RUSTOS.package.toml manifests as the deployment source of truth. BOOTX64.EFI is generated by grub-mkstandalone with an embedded public key and check_signatures=enforce; GRUB loads /nucleus.elf only when /nucleus.elf.sig verifies. Microsoft/OEM Secure Boot signing of the generated GRUB EFI binary is a release pipeline step outside the repository build.

Boot Flow

UEFI firmware
  -> EFI/BOOT/BOOTX64.EFI
  -> GRUB signature policy
  -> nucleus.elf
  -> kernel executive early init
  -> scheduler root kernel task
  -> init services
  -> runtime service manager
  -> UI server
  -> desktop/session apps

The kernel and services rely on generated registries for startup policy, desktop entries, runtime launch policy, driver autoload metadata, and Windows system DLL inventory.

Runtime Flow

uiserver -> RuntimeClient -> /run/runtimed.sock -> runtimed
  -> launch desktop id or executable path
  -> create/track console session
  -> snapshot running programs
  -> update launcher/taskbar/window state

The UI server uses runtime snapshots to reconcile visible windows with running programs. Console-hosted programs and Wayland-style windows are presented by the UI server through framebuffer rendering.

Diagnostic Flow

config/rustos.toml
  -> build.rs cfg generation
  -> kernel ring/debugcon and userspace stderr
  -> logs/debugcon.log or --debugcon stdio

Use Logging Guide for logging categories, levels, and output paths.

한국어

Host Flow

cargo xtask build
  -> workspace layering 검사
  -> Multiboot2 nucleus 빌드
  -> nucleus.elf 서명
  -> GRUB EFI boot manager 빌드
  -> userspace services/apps 빌드
  -> modules와 compatibility artifacts 빌드
  -> build/image stage
  -> generated registries 작성

cargo xtask run은 image를 다시 빌드하지 않습니다. 현재 build/image를 QEMU로 실행합니다.

Staged Image Flow

build/artifacts/* + assets/image/* + vendor/*
  -> build/image/EFI/BOOT/BOOTX64.EFI
  -> build/image/nucleus.elf
  -> build/image/nucleus.elf.sig
  -> build/image/services/*
  -> build/image/apps/*
  -> build/image/system/drivers/*
  -> build/image/system/registry/*

stage는 RUSTOS.package.toml manifest를 deployment source of truth로 사용합니다. BOOTX64.EFI는 embedded public key와 check_signatures=enforce가 들어간 grub-mkstandalone 산출물이며, GRUB은 /nucleus.elf.sig/nucleus.elf를 검증할 때만 커널을 로드합니다. generated GRUB EFI binary의 Microsoft/OEM Secure Boot signing은 repository build 밖의 release pipeline 단계입니다.

Boot Flow

UEFI firmware
  -> EFI/BOOT/BOOTX64.EFI
  -> GRUB signature policy
  -> nucleus.elf
  -> kernel executive early init
  -> scheduler root kernel task
  -> init services
  -> runtime service manager
  -> UI server
  -> desktop/session apps

kernel과 service는 startup policy, desktop entry, runtime launch policy, driver autoload metadata, Windows system DLL inventory를 generated registry에서 읽습니다.

Runtime Flow

uiserver -> RuntimeClient -> /run/runtimed.sock -> runtimed
  -> desktop id 또는 executable path launch
  -> console session 생성/추적
  -> running program snapshot
  -> launcher/taskbar/window state 갱신

UI server는 runtime snapshot으로 visible window와 running program을 reconcile합니다. console-hosted program과 Wayland-style window는 framebuffer rendering으로 표시됩니다.

Diagnostic Flow

config/rustos.toml
  -> build.rs cfg generation
  -> kernel ring/debugcon and userspace stderr
  -> logs/debugcon.log or --debugcon stdio

logging category, level, output path는 로깅 가이드를 참고하세요.

Microkernel Overview

English | 한국어

English

RustOS is a hybrid microkernel. The kernel (nucleus.elf) keeps only the mechanisms that require ring0 — trap entry, paging, scheduling, IRQ/MMIO/DMA bridges, user-copy primitives, IPC mailboxes, and a few narrow brokers for policy that still has to mutate kernel state — and pushes everything else into userspace services. The product target is native binary compatibility for both Linux ELF and Windows PE executables, so the kernel exposes both a Linux-style syscall ABI and a PE/Win32 surface through userspace policy.

Kernel Layout

The kernel is split into crates so privileges and policy stay isolated:

  • kernel/nucleus-core: the kernel binary entry plus shared core utilities, panic handling, milestone tracing, and fault-injection runtime.
  • kernel/lowlevel: assembly trap stubs, context save/restore, syscall entry/exit, and CPU-local data.
  • kernel/hal: ACPI, PCI config space, IRQ controller, SMP boot, and CPU feature detection.
  • kernel/mm: physical/virtual memory, address space objects, page tables, MMIO mapping, and DMA helpers.
  • kernel/object: capability-style kernel handles for services and brokers.
  • kernel/ipc-runtime: typed IPC endpoints, shared-region cache, and message routing for ring0 ↔ user broker calls.
  • kernel/ps: scheduler, threads, processes, signals (Linux thread policy is still here pending migration), and per-CPU run queues.
  • kernel/io-manager: USB, AHCI/NVMe, input, display providers, network bridges, and the in-kernel .ko module loader for bridge drivers.
  • kernel/compat: residual Windows PE/Win32 reference notes and a thin Linux ABI bridge that re-exports the canonical implementations from kernel/ps.
  • kernel/executive: boot orchestration, finalize sequence, and the nucleus run loop.

Anything that is not in the list above belongs in userspace.

Boot Sequence

UEFI firmware
  -> EFI/BOOT/BOOTX64.EFI (GRUB, signed, check_signatures=enforce)
  -> nucleus.elf + nucleus.elf.sig
  -> kernel_executive::boot::initialize
       gdt, idt, paging, framebuffer, heap, fault injection
       ACPI, PCI, USB, input, console, RTC, random, syscall
  -> kernel_executive::boot::finalize
       vfs init, display/input/network init, housekeeping task
       init bootstrap task spawns rootd
  -> rootd
       brings up syscalld, vfsd, loaderd, devmgrd, driverd, storaged
  -> initd
       launches runtimed (the runtime service manager)
  -> runtimed
       bootstraps uiserver synchronously (with manifest env applied),
       loads desktop/registry catalogs, then launches autostart apps
  -> uiserver
       opens the display, starts the Wayland compositor and console host,
       notifies runtimed when ready
  -> desktop/session apps (shell, wayclick, windows demos, ...)

rootd is the privilege root of userspace, modeled after an seL4 initial task. Linux-style initd only runs after the foundational service brokers are up, so the Linux runtime never has to fall back through the kernel for bootstrap policy. Adding a Linux syscall fallback in the kernel to "make initd start earlier" is a regression — the right place to add bootstrap policy is rootd, a service manifest, or a narrow broker.

Narrow Brokers

A narrow broker is a gated syscall that performs a privileged primitive on behalf of a userspace policy owner. Brokers exist when:

  • An operation requires kernel-only state (PTE mutation, IRQ unmask, IOMMU attach, MMIO map).
  • The caller is a specific userspace service that owns the corresponding policy.
  • A bounded contract — explicit args struct, ABI version, errno surface — is practical.

Examples that are live today:

  • SYS_RUSTOS_MM_BROKER: address-space mutation owned by syscalld.
  • SYS_RUSTOS_PROC_PREPARE_BROKER / ..._COMMIT_BROKER: process creation owned by loaderd.
  • SYS_RUSTOS_PROC_SET_WINDOWS_RUNTIME_BROKER: Windows runtime metadata attached during PE spawn.
  • SYS_RUSTOS_DRIVER_LOAD_MODULE_BROKER / ..._DRIVER_PROBE_ALIAS_BROKER: kernel-side module load and alias probe owned by driverd.
  • SYS_RUSTOS_IPC_*: capability-based IPC endpoint management.

Add new brokers conservatively. Prefer extending an existing service or adding a manifest field over carving a new syscall.

Compatibility Direction

  • Linux ELF: dynamic ELF main + interpreter loader lives in loaderd. Linux ABI surface lives in kernel/ps/src/user/linux.rs (canonical) and is re-exported from kernel/compat/src/user/linux.rs (do not edit the re-export). syscalld owns Linux MM policy and forwards through the gated MM broker.
  • Windows PE: loaderd maps PE32+ images, resolves imports from the System32 DLL inventory (build/image/compat/windows/System32/*), and registers a Windows runtime broker with the kernel. The PE/Win32 ABI bridge currently lives in kernel/compat, with deeper policy migration tracked as a follow-up.
  • Wayland: uiserver runs a built-in Wayland compositor exposed at /run/user/1000/wayland-0. Native Wayland clients (e.g. wayclick) draw through it; console-style apps go through the runtime's console service.

한국어

RustOS는 hybrid microkernel입니다. ring0가 반드시 필요한 mechanism — trap entry, paging, scheduling, IRQ/MMIO/DMA bridge, user-copy primitive, IPC mailbox, 그리고 kernel state를 mutation해야 하는 narrow broker — 만 커널 (nucleus.elf)에 두고, 나머지는 userspace service로 옮깁니다. 제품 목표는 Linux ELF와 Windows PE 실행 파일을 둘 다 native로 실행하는 것이며, 그래서 커널은 Linux 스타일 syscall ABI와 PE/Win32 surface를 userspace policy를 통해 같이 노출합니다.

커널 구성

ring0 권한과 policy가 섞이지 않도록 커널은 여러 crate로 나뉩니다.

  • kernel/nucleus-core: 커널 binary entry, 공용 core utility, panic 처리, milestone trace, fault-injection runtime.
  • kernel/lowlevel: assembly trap stub, context save/restore, syscall entry/exit, CPU-local data.
  • kernel/hal: ACPI, PCI config space, IRQ controller, SMP boot, CPU feature detection.
  • kernel/mm: physical/virtual memory, address space object, page table, MMIO mapping, DMA helper.
  • kernel/object: service와 broker를 위한 capability-style handle.
  • kernel/ipc-runtime: typed IPC endpoint, shared region cache, ring0 ↔ user broker message routing.
  • kernel/ps: scheduler, thread, process, signal (Linux thread policy는 아직 여기에 남아 있음), per-CPU run queue.
  • kernel/io-manager: USB, AHCI/NVMe, input, display provider, network bridge, 그리고 bridge driver .ko module을 위한 in-kernel module loader.
  • kernel/compat: Windows PE/Win32 reference 주석, 그리고 kernel/ps의 canonical 구현을 re-export하는 thin Linux ABI bridge.
  • kernel/executive: boot orchestration, finalize 시퀀스, nucleus run loop.

위 목록에 없는 것은 모두 userspace에 둡니다.

Boot 순서

UEFI firmware
  -> EFI/BOOT/BOOTX64.EFI (GRUB, 서명됨, check_signatures=enforce)
  -> nucleus.elf + nucleus.elf.sig
  -> kernel_executive::boot::initialize
       gdt, idt, paging, framebuffer, heap, fault injection
       ACPI, PCI, USB, input, console, RTC, random, syscall
  -> kernel_executive::boot::finalize
       vfs init, display/input/network init, housekeeping task
       init bootstrap task가 rootd를 spawn
  -> rootd
       syscalld, vfsd, loaderd, devmgrd, driverd, storaged 를 띄움
  -> initd
       runtimed (runtime service manager)를 실행
  -> runtimed
       uiserver를 동기 부트스트랩 (manifest env 적용),
       desktop/registry catalog 로드 후 autostart app 실행
  -> uiserver
       display open, Wayland compositor + console host 가동,
       runtimed에 ready 통보
  -> desktop/session apps (shell, wayclick, windows demos, ...)

rootd는 userspace의 권한 root이며 seL4 initial task 모델을 따릅니다. foundational broker가 올라온 뒤에야 Linux 스타일 initd가 실행되므로, Linux runtime이 bootstrap을 위해 커널 fallback에 의존할 일이 없습니다. "initd를 빨리 시작하려고 커널에 Linux syscall fallback을 넣는" 변경은 regression 입니다. bootstrap policy를 추가해야 하면 rootd, service manifest, 또는 narrow broker 어딘가에 둡니다.

Narrow Broker

narrow broker는 userspace policy 소유자가 호출하는 gated syscall입니다. 다음 조건이면 narrow broker가 됩니다.

  • kernel-only state(PTE mutation, IRQ unmask, IOMMU attach, MMIO map) 가 필요한 operation.
  • 호출자가 대응되는 policy를 소유한 특정 userspace service.
  • 명시적인 args struct, ABI version, errno surface 등 bounded contract를 유지할 수 있음.

현재 운영 중인 broker 예시:

  • SYS_RUSTOS_MM_BROKER: syscalld가 소유하는 address-space mutation.
  • SYS_RUSTOS_PROC_PREPARE_BROKER / ..._COMMIT_BROKER: loaderd가 소유하는 process 생성.
  • SYS_RUSTOS_PROC_SET_WINDOWS_RUNTIME_BROKER: PE spawn 시 Windows runtime metadata 부착.
  • SYS_RUSTOS_DRIVER_LOAD_MODULE_BROKER / ..._DRIVER_PROBE_ALIAS_BROKER: driverd가 소유하는 module load와 alias probe.
  • SYS_RUSTOS_IPC_*: capability 기반 IPC endpoint 관리.

broker는 보수적으로 추가합니다. 새 syscall을 만들기보다 기존 service를 확장하거나 manifest field를 추가하는 쪽을 우선합니다.

호환성 방향

  • Linux ELF: dynamic ELF main + interpreter loader는 loaderd. Linux ABI surface는 kernel/ps/src/user/linux.rs(canonical), kernel/compat/src/user/linux.rs는 re-export (편집 금지). Linux MM policy는 syscalld가 소유하고 gated MM broker로 forward.
  • Windows PE: loaderd가 PE32+ image를 mapping하고 build/image/compat/windows/System32/*의 DLL inventory에서 import를 해석한 뒤 Windows runtime broker를 커널에 등록합니다. PE/Win32 ABI bridge는 현재 kernel/compat에 있으며 deeper policy migration은 별도 과제로 추적합니다.
  • Wayland: uiserver가 내장 Wayland compositor를 /run/user/1000/wayland-0에 노출합니다. native Wayland client (예: wayclick)는 이를 통해 그리고, console 스타일 app은 runtime의 console service를 사용합니다.

Userspace Services

English | 한국어

English

RustOS keeps the kernel small by pushing policy into userspace services. Every service ships with a RUSTOS.package.toml manifest, an ELF in build/image/services/<id>/..., and a row in the staged registries. The table below names the live services, what they own, and the kernel surfaces or sockets they expose.

ServiceOwnsKey surface
rootdUserspace privilege root. Brings up foundational service brokers and hands off to initd.Direct spawn from kernel finalize.
initdLinux-style init. Starts runtimed, sets per-session env, and reaps strays./proc/1.
runtimedService manager + launch broker. Bootstraps uiserver (synchronously with manifest env), then dispatches autostart and on-demand launches./run/runtimed.sock (RuntimeClient).
sessiondSession policy: focus, console session lifecycle, per-user resources.Pairs with runtimed.
syscalldLinux MM/clock/signal policy. Calls into the gated SYS_RUSTOS_MM_BROKER.IPC_SERVICE_SYSCALLD.
vfsdLinux VFS policy (mount table, openat resolution, FAT boot volume).IPC_SERVICE_VFSD.
loaderdProcess spawn: ELF dynamic main+interpreter, PE32+ main + System32 imports, Windows runtime broker registration.IPC_SERVICE_LOADERD.
driverd.ko autoload, alias probe, provider-group arbitration. Single owner of SYS_RUSTOS_DRIVER_* brokers.Driver registry tsv + brokers.
devmgrdDevice manager / hotplug. Talks to driverd and consumers (inputd, storaged).IPC_SERVICE_DEVMGRD.
inputdInput event routing from kernel HID/serio into Wayland and console clients.Wayland seat + console focus.
storagedBlock device policy and partition mapping over AHCI/NVMe.Block API + driverd.
netdNetwork stack policy (virtio-net today, more to follow).netprobe socket.
procdProcess accounting, signal delivery, kernel ↔ runtime bridges for ps-style listings.Pairs with runtimed.
uiserverDisplay surface, compositor, Wayland server, console renderer. Bootstrap-launched with RUSTOS_UI_PROFILE applied from the manifest./run/user/1000/wayland-0, runtime client.

Bootstrap-launched vs Catalog-launched

The first thing runtimed does is bootstrap_ui_server: it spawns uiserver immediately, before the desktop/runtime-launch registries are finished loading. That bootstrap path now reads the uiserver desktop entry synchronously so manifest env (e.g. RUSTOS_UI_PROFILE=1) is honored on the very first run, not just after the catalog loader finishes on a worker thread.

All other services and apps are launched from the catalog. The catalog is loaded asynchronously to keep boot wall-clock short; the OnceLock cache in runtime-control makes the bootstrap read and the worker read share the same parse.

Driver Modules

Driver modules (.ko) are owned by driverd, but the actual link + init happens inside the kernel module loader because they need ring0 access. driverd reads system/registry/kernel/loadable-drivers.tsv, calls SYS_RUSTOS_DRIVER_LOAD_MODULE_BROKER per record, and walks dependency edges. The on-boot probe loads:

  • hid (HID core) and hid-generic (generic HID input driver) for USB pointers and keyboards.
  • virtio-gpu when present (otherwise bootfb is the active display provider).
  • virtio-net for the default emulated NIC.

A skipped driver shows up as driverd: skipped name=... reason=... and is expected when the alias doesn't match the live hardware or when a higher priority provider in the same provider_group is already active.

한국어

RustOS는 정책을 userspace service로 옮겨 커널을 작게 유지합니다. 모든 service는 RUSTOS.package.toml manifest, build/image/services/<id>/... ELF, 그리고 staged registry에 한 줄을 함께 가집니다. 아래 표는 현재 운영 중인 service와 그 소유 정책, 그리고 노출되는 kernel surface / socket을 요약합니다.

Service소유 정책주요 surface
rootduserspace privilege root. foundational broker를 띄우고 initd에 인계.kernel finalize에서 직접 spawn.
initdLinux 스타일 init. runtimed를 띄우고 session 환경을 set, 좀비 회수./proc/1.
runtimedservice manager + launch broker. manifest env를 적용한 채 uiserver를 동기 부트스트랩한 뒤, autostart와 on-demand launch를 dispatch./run/runtimed.sock (RuntimeClient).
sessiondsession policy: focus, console session lifecycle, per-user resource.runtimed와 쌍.
syscalldLinux MM/clock/signal policy. SYS_RUSTOS_MM_BROKER 호출.IPC_SERVICE_SYSCALLD.
vfsdLinux VFS policy (mount table, openat resolution, FAT boot volume).IPC_SERVICE_VFSD.
loaderdprocess spawn: ELF dynamic main+interpreter, PE32+ main + System32 import, Windows runtime broker 등록.IPC_SERVICE_LOADERD.
driverd.ko autoload, alias probe, provider-group 중재. SYS_RUSTOS_DRIVER_* broker 단일 소유자.driver registry tsv + broker.
devmgrddevice manager / hotplug. driverd 및 consumer(inputd, storaged)와 통신.IPC_SERVICE_DEVMGRD.
inputdkernel HID/serio에서 들어온 input event를 Wayland와 console client로 route.Wayland seat + console focus.
storagedAHCI/NVMe 위 block device policy와 partition mapping.Block API + driverd.
netdnetwork stack policy (현재 virtio-net).netprobe socket.
procdprocess accounting, signal 전달, ps-style listing용 kernel ↔ runtime bridge.runtimed와 쌍.
uiserverdisplay surface, compositor, Wayland server, console renderer. manifest의 RUSTOS_UI_PROFILE 가 적용된 채 부트스트랩 launch./run/user/1000/wayland-0, runtime client.

부트스트랩 launch vs catalog launch

runtimed가 가장 먼저 하는 일은 bootstrap_ui_server 입니다. desktop / runtime-launch registry 로딩이 끝나기 전에 uiserver를 바로 spawn 합니다. 이제 이 bootstrap 경로는 uiserver desktop entry를 동기적으로 읽어서 manifest env (예: RUSTOS_UI_PROFILE=1)를 첫 실행부터 반영합니다. catalog loader worker 완료를 기다리던 이전 동작에서 회귀입니다.

다른 모든 service와 app은 catalog에서 launch 됩니다. catalog는 boot wall-clock을 줄이려고 비동기로 로드되며, runtime-control의 OnceLock cache가 bootstrap 경로와 worker 경로의 parsing을 공유하게 만듭니다.

Driver module

driver module (.ko)은 driverd가 소유 정책이지만, ring0 접근이 필요해 실제 link + init은 kernel module loader 안에서 일어납니다. driverdsystem/registry/kernel/loadable-drivers.tsv를 읽고 각 record에 대해 SYS_RUSTOS_DRIVER_LOAD_MODULE_BROKER를 호출하며 의존 edge를 따라 순서를 정합니다. boot 중 probe되는 module 예:

  • USB pointer/keyboard용 hid (HID core)와 hid-generic (generic HID input driver).
  • 가능하면 virtio-gpu (없으면 bootfb가 display provider).
  • emulated NIC default인 virtio-net.

skip된 driver는 driverd: skipped name=... reason=...로 표시되며, alias가 실제 hardware와 매칭되지 않거나 같은 provider_group 안에 더 높은 우선 순위의 provider가 이미 활성일 때 정상적으로 발생합니다.

Userspace Compatibility

English | 한국어

English

RustOS targets native binary compatibility for both Linux ELF and Windows PE executables. Both paths live in userspace services and reach the kernel only through narrow brokers.

Linux ELF

The ELF path supports static and dynamic 64-bit Linux ELF binaries.

runtimed (or initd autostart)
  -> request_launch_path or spawn_exec
  -> loaderd (IPC_SERVICE_LOADERD)
       open executable, validate ELF, read program headers in one pread64
       SYS_RUSTOS_PROC_PREPARE_BROKER
       map main segments (+ interpreter if PT_INTERP)
       set Linux runtime broker on the prepared process
       commit and return pid
  -> kernel scheduler picks up the new task
  -> Linux libc syscalls trap into kernel
       syscalld owns MM/clock/signal policy via SYS_RUSTOS_MM_BROKER
       vfsd owns VFS policy

Notes:

  • The canonical Linux ABI surface lives in kernel/ps/src/user/linux.rs. kernel/compat/src/user/linux.rs is a re-export shim — never edit it.
  • Adding new Linux syscall routing should happen in syscalld, vfsd, or the appropriate userspace service, not in kernel/compat.

Windows PE

The PE path supports console-class PE32+ amd64 executables. Native Win32 GUI apps are limited until the compositor adds the Win32 GDI bridge.

runtimed
  -> loaderd
       open executable, validate DOS+PE+OPTIONAL_HEADER
       load PE main image at default base
       load_system_dll_registry (system/registry/compat/windows-system-dlls.txt)
       preload system DLLs (ntdll, kernel32, kernelbase, msvcrt, ucrtbase, ...)
       resolve_import_closure (imports + forwarders)
       build_windows_runtime_blob (argv/env, locale, heap, IO)
       SYS_RUSTOS_PROC_SET_WINDOWS_RUNTIME_BROKER
       map main + DLL pages
       commit, return pid
  -> Win32 imports resolve to kernel32 forwarders in kernelbase.dll
  -> CRT calls land in msvcrt.dll / ucrtbase.dll
  -> Selected primitives (Heap*, Tls*, locale, console IO) are serviced by
     RtlMsvcrt* and Rtl* shims that talk to the runtime broker.

PE failures now log a step name and errno (loaderd: pe step failed exec=... step=... errno=...) so a map executable failed errno=8 from the runtime is easy to localize. The supported System32 inventory lives under build/image/compat/windows/System32/. Add the canonical alias to BUILTIN_SYSTEM_DLL_ALIASES in services/loaderd/src/main.rs if you stage a new DLL with API-set names.

Wayland

uiserver runs a built-in Wayland compositor on /run/user/1000/wayland-0. Wayland clients connect, register surfaces, attach buffers, and receive frame callbacks. The compositor enforces the same dirty-rect contract as the rest of the UI so partial damage is honored.

Native Wayland clients in the tree:

  • apps/wayclick: pointer click smoke test.
  • apps/shell: console-hosted shell launching surface.
  • apps/windows/*: PE demos that render through the runtime's console service.

Compatibility Direction

  • Prefer extending a userspace service over carving a new kernel broker.
  • Manifests, registries, and brokers are stable contracts. Wire new policy through them; do not lean on filenames or paths.
  • Hardening fallback providers (bootfb for display, scalar SIMD for blend) must stay behind the real provider so a regression in the real provider is observable, not masked.

한국어

RustOS는 Linux ELF와 Windows PE 실행 파일을 둘 다 native로 실행하는 것을 목표로 합니다. 두 경로 모두 userspace service에 있고, narrow broker로만 커널과 닿습니다.

Linux ELF

ELF 경로는 static / dynamic 64-bit Linux ELF binary를 지원합니다.

runtimed (또는 initd autostart)
  -> request_launch_path 또는 spawn_exec
  -> loaderd (IPC_SERVICE_LOADERD)
       executable open, ELF 검증, program header를 pread64 한 번으로 읽기
       SYS_RUSTOS_PROC_PREPARE_BROKER
       main segment map (필요하면 PT_INTERP interpreter 포함)
       prepared process에 Linux runtime broker set
       commit, pid 반환
  -> kernel scheduler가 새 task를 pickup
  -> Linux libc syscall이 kernel로 trap
       syscalld가 SYS_RUSTOS_MM_BROKER로 MM/clock/signal 정책 소유
       vfsd가 VFS 정책 소유

참고:

  • canonical Linux ABI surface는 kernel/ps/src/user/linux.rs에 있습니다. kernel/compat/src/user/linux.rs는 re-export shim 이므로 절대 편집하지 않습니다.
  • 새 Linux syscall routing은 syscalld, vfsd, 또는 적절한 userspace service에 추가하고 kernel/compat에 넣지 않습니다.

Windows PE

PE 경로는 console-class PE32+ amd64 실행 파일을 지원합니다. native Win32 GUI app은 compositor에 Win32 GDI bridge가 들어오기 전까지 제한적입니다.

runtimed
  -> loaderd
       executable open, DOS+PE+OPTIONAL_HEADER 검증
       PE main image를 default base에 load
       load_system_dll_registry (system/registry/compat/windows-system-dlls.txt)
       system DLL preload (ntdll, kernel32, kernelbase, msvcrt, ucrtbase, ...)
       resolve_import_closure (import + forwarder)
       build_windows_runtime_blob (argv/env, locale, heap, IO)
       SYS_RUSTOS_PROC_SET_WINDOWS_RUNTIME_BROKER
       main + DLL page map
       commit, pid 반환
  -> Win32 import는 kernelbase.dll의 kernel32 forwarder로 해석
  -> CRT 호출은 msvcrt.dll / ucrtbase.dll로 진입
  -> 일부 primitive(Heap*, Tls*, locale, console IO)는 RtlMsvcrt*, Rtl*
     shim에서 runtime broker로 redirect.

PE 실패는 이제 step 이름과 errno를 로그에 남깁니다 (loaderd: pe step failed exec=... step=... errno=...). runtime이 보던 map executable failed errno=8을 어느 단계에서 났는지 바로 식별할 수 있습니다. 지원되는 System32 inventory는 build/image/compat/windows/System32/ 아래에 있습니다. API-set 이름을 가진 새 DLL을 stage하면 services/loaderd/src/main.rsBUILTIN_SYSTEM_DLL_ALIASES에 canonical alias를 추가하세요.

Wayland

uiserver/run/user/1000/wayland-0에서 내장 Wayland compositor를 운영합니다. Wayland client는 surface 등록, buffer attach, frame callback 수신을 사용합니다. compositor는 UI 나머지와 같은 dirty-rect 규약을 강제해서 partial damage가 올바르게 반영됩니다.

저장소 내 native Wayland client:

  • apps/wayclick: pointer click smoke test.
  • apps/shell: console-hosted shell launching surface.
  • apps/windows/*: runtime의 console service를 통해 그리는 PE demo.

호환성 방향

  • 새 kernel broker를 만들기보다 userspace service를 확장하는 쪽을 우선합니다.
  • manifest, registry, broker는 안정적인 contract 입니다. 새 정책은 이들을 통해 연결하고, file name이나 path에 의존하지 않습니다.
  • 강화용 fallback provider (display의 bootfb, blend의 scalar SIMD)는 실제 provider 뒤에 두어 실제 provider regression이 가려지지 않게 합니다.

UI Server & Wayland

English | 한국어

English

uiserver is RustOS's display server. It owns the framebuffer, draws the desktop chrome, hosts a Wayland compositor, and renders console-hosted sessions for Linux and Windows PE programs.

Boot Path

runtimed bootstrap_ui_server
  -> spawn uiserver with manifest args + env (RUSTOS_UI_PROFILE=1)
uiserver run()
  -> AppState::initialize (display_get_info + display_create_surface)
  -> render_boot_frame (single solid fill — no chrome yet)
  -> first present (boot frame stays on screen while runtime/Wayland init runs)
  -> open RuntimeClient (notify_ui_ready socket + sync socket)
  -> WaylandCompositor::initialize (creates /run/user/1000/wayland-0)
  -> notify_ui_ready -> runtimed unblocks autostart launches
  -> main loop:
       drain input, runtime poll, console poll, cursor blink,
       coalesce partial dirty rects, render & present

The synchronous critical path is intentionally short:

  1. The first present uses a solid colour, not the full chrome. Chrome composition is deferred to the first idle frame so the user always sees pixels within a few frames of display_create_surface.
  2. Console window surfaces are no longer "primed" during runtime polling; draw_console_window rebuilds the cached surface on the first draw, matching the same total work to the render budget instead of the runtime refresh budget.
  3. The terminal cell loop in terminal.rs skips redundant per-cell background fills when the bulk render has already painted layout.bounds. Per-cell paint stays for single-cell repaints (cursor blink) only.

Translucent Aero Palette

The chrome palette is a translucent monochrome blue. Glass and inner panels stack via fill_rect_alpha so the desktop band shows through the rails. Highlights and shadows are tuned to suggest frosted glass:

  • Rails draw an upper sheen half + a lower settled half + an inner elevated bloom, with a 1-pixel specular line at the top edge and a faint baseline shadow underneath.
  • Window title bars use the same two-layer technique with an extra accent overlay when focused.
  • Mouse cursor stays at the existing soft blue/white tone; do not change cursor_sprites.rs or the cursor colours in canvas.rs for theme recolours.

Wayland Surfaces

The compositor exposes the standard Wayland sockets via /run/user/1000/wayland-0. Surfaces, buffers, frame callbacks, and damage all use the canonical Wayland protocol — the in-tree Wayland clients (apps/wayclick, console hosts) and the planned external clients should not need special wrappers.

Console Hosting

Console-hosted programs (the shell, the PE demos) get a console session from runtimed and a window from uiserver. The terminal state lives in uiserver's TerminalState, parsing input bytes from the console output ring. Layout uses the terminal monospace atlas; chrome uses the UI atlas.

Profile Trace

Set RUSTOS_UI_PROFILE=1 (now applied automatically on the bootstrap launch) to enable profile::record_* paths. The summary lines tagged uiserver profile: ... get flushed to debugcon and are the primary tool for diagnosing slow refresh / slow present regressions. Use them before adding new diag prints.

한국어

uiserver는 RustOS의 display server입니다. framebuffer 소유, desktop chrome draw, Wayland compositor 운영, 그리고 Linux/Windows PE program의 console-hosted session rendering을 담당합니다.

Boot 경로

runtimed bootstrap_ui_server
  -> manifest args + env (RUSTOS_UI_PROFILE=1)로 uiserver spawn
uiserver run()
  -> AppState::initialize (display_get_info + display_create_surface)
  -> render_boot_frame (chrome 없이 단색 fill)
  -> first present (runtime/Wayland 초기화 동안 boot frame 유지)
  -> RuntimeClient open (notify_ui_ready socket + sync socket)
  -> WaylandCompositor::initialize (/run/user/1000/wayland-0 생성)
  -> notify_ui_ready -> runtimed가 autostart launch 해제
  -> main loop:
       input drain, runtime poll, console poll, cursor blink,
       partial dirty rect coalesce, render & present

동기 임계 경로는 의도적으로 짧습니다.

  1. 첫 present는 full chrome이 아니라 단색을 사용합니다. chrome 합성은 첫 idle frame으로 미뤄지므로, 사용자에게는 display_create_surface 직후 몇 frame 안에 항상 pixel이 보입니다.
  2. console window surface는 runtime polling 중에 "prime" 하지 않습니다. draw_console_window가 첫 draw에서 cached surface를 rebuild하며, 동일한 총 작업량을 runtime refresh budget이 아닌 render budget으로 옮깁니다.
  3. terminal.rs의 cell loop는 bulk render가 이미 layout.bounds를 채웠다면 cell별 background fill을 생략합니다. cell별 paint는 cursor blink 같은 single-cell repaint에서만 유지됩니다.

Translucent Aero Palette

chrome palette는 translucent monochrome blue입니다. glass / inner panel은 fill_rect_alpha로 쌓아서 desktop band가 rail을 통해 비치도록 합니다. hilight / shadow는 frosted glass 느낌을 내도록 tune 했습니다.

  • rail은 상단 sheen 반쪽 + 하단 settled 반쪽 + inner elevated bloom를 그리고, top edge에 1px specular line, base line에 옅은 그림자를 추가합니다.
  • window title bar는 같은 two-layer 기법을 쓰며 focus 상태에서 accent overlay 한 겹이 더 들어갑니다.
  • 마우스 커서는 기존의 soft blue/white tone을 그대로 둡니다. theme recolor 시에 cursor_sprites.rscanvas.rs의 cursor color는 바꾸지 마세요.

Wayland Surface

compositor는 /run/user/1000/wayland-0로 standard Wayland socket을 노출합니다. surface, buffer, frame callback, damage는 canonical Wayland protocol을 사용합니다. tree 내의 Wayland client (apps/wayclick, console host)와 예정된 외부 client에 별도 wrapper가 필요하지 않습니다.

Console hosting

console-hosted program (shell, PE demo)은 runtimed에서 console session 을, uiserver에서 window를 받습니다. terminal state는 uiserverTerminalState 안에 있고 console output ring의 input byte를 parsing 합니다. layout은 terminal monospace atlas를, chrome은 UI atlas를 사용합니다.

Profile Trace

RUSTOS_UI_PROFILE=1 (이제 bootstrap launch에서 자동 적용)을 설정하면 profile::record_* 경로가 활성화됩니다. uiserver profile: ... summary line이 debugcon으로 flush 되며 slow refresh / slow present regression을 진단할 때 주된 도구입니다. 새 diag print를 추가하기 전에 이 경로를 먼저 사용하세요.

Structure Guide

English | 한국어

English

This document defines the repository layout rules for RustOS. These rules are not only documentation: the important dependency and package taxonomy checks are enforced by cargo xtask check.

Directory Roles

  • boot/: boot protocol crate shared by the GRUB-loaded nucleus
  • kernel/: kernel entry crate plus internal kernel subsystem crates
  • services/: userspace system services such as initd, runtimed, and uiserver
  • apps/: demo, smoke, desktop, and compatibility test applications
  • compat/: compatibility layer sources, including Windows userspace support
  • libs/: general-purpose crates shared across product layers
  • tests/: integration and module test crates
  • tools/: host-side build, stage, run, and validation tools
  • assets/image/: static overlay copied directly into the staged boot image
  • assets/ui/: UI fonts and related UI assets
  • build/artifacts/: build artifact cache
  • build/image/: staged boot volume root
  • logs/: QEMU, debugcon, interrupt, and helper logs
  • drivers/bridges/: kernel-address-space bridge drivers and .ko modules
  • drivers/user/: userspace driver/service ELF packages
  • drivers/libs/: driver ABI, runtime, and helper crates
  • vendor/: external binaries, firmware, prebuilt .ko files, and OVMF
  • config/: shared configuration such as logging policy
  • docs/: architecture, workflow, and operator documentation

Placement Rules

  • Deployment policy belongs in each package root's RUSTOS.package.toml.
  • Choose the owning layer first: boot, kernel, services, apps, compat, drivers/bridges, drivers/user, libs, or drivers/libs.
  • Boot-chain shared logic belongs under boot/.
  • Driver ABI/runtime logic or bus/device helpers belong under drivers/libs/.
  • Code that needs hardware IRQ/MMIO/DMA bridge access belongs under drivers/bridges/.
  • Restartable policy-oriented logic belongs under services/ or drivers/user/.
  • Only code that needs hardware, ABI entrypoints, or core kernel privileges belongs under kernel/.
  • Static files that should appear in the boot volume go under assets/image/.
  • External binary inputs that the repository keeps should go under vendor/.
  • Generated outputs must stay under build/ or logs/.

Layering Rules

  • kernel/src is entry-only. Real kernel functionality is split across kernel/nucleus-core, kernel/lowlevel, kernel/hal, kernel/mm, kernel/object, kernel/ipc-runtime, kernel/ps, kernel/io-manager, kernel/compat, and kernel/executive.
  • RustOS is a hybrid kernel, not a pure microkernel. Policy and namespace decisions should move to services such as driverd, syscalld, vfsd, and loaderd, but privileged mechanisms stay in ring0 when native compatibility requires them. This includes syscall entry/trap handling, gated syscall brokers, address-space mutation, scheduler state, user-copy operations, IRQ/MMIO/DMA/IOMMU access, and kernel-address-space .ko module execution.
  • Kernel-internal crate dependencies must not flow from lower layers back into higher layers. cargo xtask check validates these relationships.
  • libs/ may depend only on boot protocol crates and other libs/ crates. It must not depend on implementation crates from kernel/, services/, apps/, or drivers/bridges/.
  • drivers/libs/ may depend on libs/, drivers/libs/, and required boot protocol crates. It must not depend on bridge driver implementations.
  • services/ may depend on libs/, compat/, and drivers/libs/.
  • apps/ may depend on libs/ and compat/.
  • drivers/bridges/ may depend on kernel ABI surfaces, libs/, and drivers/libs/.
  • tests/ may reference product crates, but tests are still included in the layering checks.

Runtime Dependencies

  • A deployable unit that needs another unit to run or be exposed first declares runtime_deps = ["package-id"] in RUSTOS.package.toml.
  • runtime_deps values are package id values, not install paths and not desktop file ids.
  • cargo xtask check validates dependency existence, profile inclusion, self-dependencies, and dependency cycles for the selected profile.
  • Stage writes dependency metadata into the startup/runtime registries as deps= fields. Launcher ordering enforcement is handled separately.

Vendor, Assets, And Build Outputs

  • vendor/: external source inputs preserved by the repository
  • assets/image/: files copied into the staged image
  • build/: reproducible build and stage output
  • logs/: run/debug output

Do not put generated artifacts, QEMU run output, or local debug captures in source directories.

Adding A New Module

  1. If it is a source-based first-party kernel bridge, add a crate under drivers/bridges/....
  2. If it is a userspace driver or service, add it under drivers/user/... or services/....
  3. If shared driver API/helper code is needed, use drivers/libs/....
  4. If it is deployable, add RUSTOS.package.toml at the package root and declare kind, execution_domain, startup, and install.path.
  5. Run cargo xtask check to validate layering and package taxonomy.
  6. Run cargo xtask build, then inspect generated registries under build/image/system/registry/... if startup, desktop, or driver policy changed.
  7. Update this document and Documentation Home when path rules or ownership boundaries change.

한국어

이 문서는 RustOS 저장소 배치 규칙을 정의합니다. 이 규칙은 단순 문서가 아니며, 중요한 dependency와 package taxonomy 검사는 cargo xtask check로 강제됩니다.

디렉터리 역할

  • boot/: GRUB이 로드하는 nucleus와 공유하는 boot protocol crate
  • kernel/: kernel entry crate와 내부 kernel subsystem crate
  • services/: initd, runtimed, uiserver 같은 userspace system service
  • apps/: demo, smoke, desktop, compatibility test application
  • compat/: Windows userspace 지원을 포함한 호환 계층 소스
  • libs/: 여러 제품 계층이 공유하는 일반-purpose crate
  • tests/: integration/module test crate
  • tools/: host-side build, stage, run, validation 도구
  • assets/image/: staged boot image에 그대로 복사되는 정적 overlay
  • assets/ui/: UI font와 관련 UI asset
  • build/artifacts/: build artifact cache
  • build/image/: staged boot volume root
  • logs/: QEMU, debugcon, interrupt, helper log
  • drivers/bridges/: kernel address space에 남는 bridge driver와 .ko module
  • drivers/user/: userspace driver/service ELF package
  • drivers/libs/: driver ABI, runtime, helper crate
  • vendor/: 외부 바이너리, firmware, prebuilt .ko, OVMF
  • config/: logging policy 같은 공유 설정
  • docs/: architecture, workflow, operator 문서

코드 배치 규칙

  • 배포 단위 정책은 각 package root의 RUSTOS.package.toml에 둡니다.
  • 먼저 소유 계층을 결정합니다: boot, kernel, services, apps, compat, drivers/bridges, drivers/user, libs, drivers/libs.
  • boot chain 공용 로직은 boot/ 아래에 둡니다.
  • driver ABI/runtime 로직이나 bus/device helper는 drivers/libs/ 아래에 둡니다.
  • hardware IRQ/MMIO/DMA bridge 접근이 필요한 코드는 drivers/bridges/ 아래에 둡니다.
  • 재시작 가능하고 정책 중심인 로직은 services/ 또는 drivers/user/ 아래에 둡니다.
  • hardware, ABI entrypoint, core kernel 권한이 필요한 코드만 kernel/ 아래에 둡니다.
  • boot volume에 들어갈 정적 파일은 assets/image/ 아래에 둡니다.
  • 저장소가 보관하는 외부 binary input은 vendor/ 아래에 둡니다.
  • 생성 산출물은 build/ 또는 logs/ 아래에만 둡니다.

계층 규칙

  • kernel/src는 entry-only입니다. 실제 kernel 기능은 kernel/nucleus-core, kernel/lowlevel, kernel/hal, kernel/mm, kernel/object, kernel/ipc-runtime, kernel/ps, kernel/io-manager, kernel/compat, kernel/executive로 나눕니다.
  • RustOS는 순수 microkernel이 아니라 hybrid kernel입니다. 정책과 namespace 결정은 driverd, syscalld, vfsd, loaderd 같은 service로 옮기되, native compatibility에 필요한 privileged mechanism은 ring0에 남깁니다. 여기에는 syscall entry/trap 처리, gated syscall broker, address-space mutation, scheduler state, user-copy, IRQ/MMIO/DMA/IOMMU 접근, kernel-address-space .ko module 실행이 포함됩니다.
  • kernel 내부 crate dependency는 낮은 계층에서 높은 계층으로 역류하면 안 됩니다. cargo xtask check가 이 관계를 검사합니다.
  • libs/는 boot protocol crate와 다른 libs/ crate에만 의존할 수 있습니다. kernel/, services/, apps/, drivers/bridges/ 구현 crate를 끌어오면 안 됩니다.
  • drivers/libs/libs/, drivers/libs/, 필요한 boot protocol crate에만 의존할 수 있습니다. bridge driver 구현에 의존하면 안 됩니다.
  • services/libs/, compat/, drivers/libs/에 의존할 수 있습니다.
  • apps/libs/compat/에 의존할 수 있습니다.
  • drivers/bridges/는 kernel ABI surface, libs/, drivers/libs/에 의존할 수 있습니다.
  • tests/는 product crate를 참조할 수 있지만 layering check 대상에 포함됩니다.

런타임 의존성

  • 실행 또는 노출 순서가 필요한 배포 단위는 RUSTOS.package.tomlruntime_deps = ["package-id"]를 선언합니다.
  • runtime_deps 값은 install path나 desktop file id가 아니라 package id입니다.
  • cargo xtask check는 선택된 profile 기준으로 dependency 존재 여부, 같은 profile 포함 여부, 자기 자신 의존, 순환 의존을 검사합니다.
  • stage는 startup/runtime registry에 deps= metadata를 기록합니다. launcher 실행 순서 강제는 별도 단계에서 처리합니다.

Vendor, Assets, Build 구분

  • vendor/: 저장소가 보관하는 외부 source input
  • assets/image/: staged image에 복사되는 파일
  • build/: 재생성 가능한 build/stage output
  • logs/: run/debug output

생성 artifact, QEMU 실행 output, local debug capture를 source directory에 두지 마세요.

새 모듈 추가 절차

  1. source 기반 first-party kernel bridge라면 drivers/bridges/...에 crate를 추가합니다.
  2. userspace driver 또는 service라면 drivers/user/... 또는 services/... 아래에 추가합니다.
  3. 공용 driver API/helper code가 필요하면 drivers/libs/...를 사용합니다.
  4. deployable 단위라면 package root에 RUSTOS.package.toml을 추가하고 kind, execution_domain, startup, install.path를 선언합니다.
  5. cargo xtask check로 layering과 package taxonomy를 검증합니다.
  6. cargo xtask build를 실행한 뒤 startup, desktop, driver 정책이 바뀌었다면 build/image/system/registry/... 아래 generated registry를 확인합니다.
  7. 경로 규칙이나 ownership boundary가 바뀌면 이 문서와 문서 홈을 같이 갱신합니다.

Logging Guide

English | 한국어

English

This guide documents RustOS logging configuration, where logs go, and how to add new log lines without making the boot path noisy.

Configuration File

The shared logging policy lives in config/rustos.toml under [logging]. Most settings are consumed by crate build.rs scripts through tools/build_log_cfg.rs, so changing the file requires rebuilding the affected crates.

[logging]
enabled = true
boot_trace_enabled = true
serial_mirror = true
ring_buffer_bytes = 16384
min_level = "info"

[logging.categories]
boot = "info"
panic = "fatal"
memory = "info"
sched = "info"
syscall = "off"
process = "info"
driver = "info"
storage = "info"
usb = "info"
input = "info"
display = "info"
vfs = "info"
console = "info"
service = "info"
compat = "info"
debug = "info"
heartbeat = "info"

Fields

  • enabled: enables structured category logging. When this is false, the category log cfgs are not emitted.
  • boot_trace_enabled: emits rustos_boot_trace_enabled for early boot trace paths. This is intentionally separate from enabled.
  • serial_mirror: mirrors kernel structured log lines to QEMU debugcon port 0xe9 in addition to keeping them in the kernel text ring.
  • ring_buffer_bytes: byte capacity of the kernel structured log ring.
  • min_level: default threshold for every category before per-category overrides are applied.
  • [logging.categories]: per-category thresholds.

Supported levels are off, trace, debug, info, warn, error, and fatal. The threshold is inclusive. For example, storage = "warn" enables warn, error, and fatal storage logs, but filters out info, debug, and trace.

Categories

The canonical category list is defined in libs/rustos-observability/src/lib.rs and duplicated by the build helper for cfg generation.

  • boot: boot manager and kernel boot sequencing
  • panic: panic and fatal crash reporting
  • memory: physical memory, paging, heap, VM
  • sched: scheduler and task switching
  • syscall: Linux/compat syscall entry and exit paths
  • process: process and thread lifecycle
  • driver: driver loading and driver runtime
  • storage: block devices, boot volume, filesystem paths
  • usb: USB host/controller/device work
  • input: keyboard, pointer, HID input
  • display: framebuffer, DRM, GPU, presentation paths
  • vfs: VFS lookup/open/read/write paths
  • console: console host and terminal sessions
  • service: userspace system services
  • compat: Linux/Windows compatibility layer
  • debug: breadcrumbs, diagnostics, internal debug helpers
  • heartbeat: low-volume liveness markers

Build-Time Behavior

The logging config is compiled into cfg flags such as:

  • rustos_debug_print_enabled
  • rustos_boot_trace_enabled
  • rustos_log_storage_debug
  • rustos_log_service_info

Kernel crates use generated macros from kernel/nucleus-core/src/debug/kdiag_macros.rs. Userspace services use generated helpers from libs/observability-client.

After changing config/rustos.toml, rebuild:

cargo xtask build

For a quicker userspace-only feedback loop:

cargo xtask build-user

For kernel logging changes, prefer the full build because several kernel crates emit the same cfgs from their build.rs files.

Kernel Logging

Kernel-side logging is exposed through crate::debug in kernel crates:

#![allow(unused)]
fn main() {
crate::debug::info!(storage, "mounted boot volume sectors={}", sector_count);
crate::debug::warn!(driver, "driver probe failed name={} err={}", name, err);
crate::debug::error_ratelimited!(usb, "xhci event ring stalled");
}

Useful APIs:

  • crate::debug::enabled!(category, level): check whether a log site is enabled before doing expensive formatting or probing.
  • crate::debug::warn_ratelimited! and crate::debug::error_ratelimited!: one log per site per default interval.
  • crate::debug::snapshot_structured_log_bytes(): snapshot the in-kernel text ring for diagnostics.
  • crate::debug::report_panic(info): panic reporting path.

Kernel structured log lines are rendered like:

seq=17 ts_us=102399 tick=409596 lvl=info cat=storage mod=... line=42 pid=- tid=- msg="..."

When serial_mirror = true, those structured lines are also written to QEMU debugcon. When the ring wraps, snapshots include a synthetic warning line:

msg="oldest logs dropped"

Userspace Service Logging

Userspace Rust services use observability-client:

#![allow(unused)]
fn main() {
observability_client::info!("runtimed", service, "ui ready received");
observability_client::warn!("sessiond", service, "session restart requested");
observability_client::error!("uiserver", display, "present failed errno={}", err);
}

The first argument is the service name string. The second argument is a category identifier, not a string. It must be one of the configured categories.

Userspace log output is written to stderr using os_observatory. In QEMU runs, this normally appears through the guest process stderr path and debug console plumbing.

Boot Trace And Ad-Hoc Lines

There are two related but different paths:

  • Structured logging: category/level controlled by enabled, min_level, and [categories].
  • Boot trace: early bring-up messages controlled by boot_trace_enabled in kernel code, plus a few service-local boot trace helpers.

Kernel boot trace uses rustos_boot_trace_enabled. Some userspace services still have local boot_line helpers for early bootstrap debugging. uiserver also supports:

RUSTOS_UI_BOOT_TRACE=1
RUSTOS_UI_PROFILE=1

These service-local helpers are useful during bring-up, but normal diagnostics should use structured logging so category filtering works.

Reading Logs

Host-side QEMU logs are written under logs/.

  • logs/debugcon.log: default QEMU debugcon output for cargo xtask run
  • logs/qemu_interrupt.log: QEMU interrupt trace when --qemu-log int is used
  • logs/rustos-debug.gdb: helper generated by cargo xtask debug

Common commands:

cargo xtask run
cargo xtask run --debugcon stdio
cargo xtask run --qemu-log int
cargo xtask debug

--debugcon stdio is useful when the debug stream itself is the main thing being investigated. The default file mode is better for normal UI/QEMU runs.

Quiet default:

enabled = true
boot_trace_enabled = true
serial_mirror = true
ring_buffer_bytes = 16384
min_level = "info"

[categories]
syscall = "off"
heartbeat = "info"

Storage debugging:

min_level = "info"

[categories]
storage = "debug"
vfs = "debug"
driver = "info"

Syscall debugging:

min_level = "info"

[categories]
syscall = "trace"
compat = "debug"
process = "debug"

Scheduler debugging:

min_level = "warn"

[categories]
sched = "debug"
process = "debug"
heartbeat = "off"

For very noisy categories such as syscall, sched, and vfs, increase ring_buffer_bytes if you need useful history after a failure.

Adding A New Category

Add a category only when existing categories cannot describe the log source cleanly. A new category must be added in all of these places:

  1. libs/rustos-observability/src/lib.rs
  2. tools/build_log_cfg.rs
  3. config/rustos.toml
  4. this guide

Then run:

cargo fmt --check
cargo test -p module-tests
cargo xtask check

Logging Hygiene

  • Before adding new log sites, first check whether the existing category and level controls can expose the needed signal. Prefer temporarily raising a category such as sched = "debug" over adding one-off output.
  • When new kernel log output is needed, make it a reusable diagnostic path with a stable category, level, and structured fields. Avoid local raw debugcon writes unless the code runs before structured logging is available.
  • Prefer debug or trace for loops, interrupts, syscalls, scheduler ticks, or packet/block paths.
  • Use info for lifecycle events: service start, device ready, mount complete, UI ready.
  • Use warn for recoverable failures or degraded fallback.
  • Use error for failed operations that likely break a user-visible path.
  • Use fatal only for panic/crash class events.
  • Use ratelimited macros for repeated hardware, scheduler, or IO errors.
  • Guard expensive log payloads with enabled!.
  • Do not log raw untrusted buffers, large payloads, secrets, or full memory dumps through normal structured logs.

한국어

이 가이드는 RustOS logging 설정, log가 기록되는 위치, boot path를 과도하게 시끄럽게 만들지 않고 새 log line을 추가하는 방법을 설명합니다.

설정 파일

공유 logging 정책은 config/rustos.toml[logging]에 있습니다. 대부분의 설정은 crate build.rstools/build_log_cfg.rs를 통해 읽습니다. 따라서 이 파일을 바꾸면 영향을 받는 crate를 다시 빌드해야 합니다.

[logging]
enabled = true
boot_trace_enabled = true
serial_mirror = true
ring_buffer_bytes = 16384
min_level = "info"

[logging.categories]
boot = "info"
panic = "fatal"
memory = "info"
sched = "info"
syscall = "off"
process = "info"
driver = "info"
storage = "info"
usb = "info"
input = "info"
display = "info"
vfs = "info"
console = "info"
service = "info"
compat = "info"
debug = "info"
heartbeat = "info"

필드

  • enabled: structured category logging을 켭니다. false이면 category log cfg가 생성되지 않습니다.
  • boot_trace_enabled: early boot trace path에 쓰이는 rustos_boot_trace_enabled를 생성합니다. enabled와 의도적으로 분리되어 있습니다.
  • serial_mirror: kernel structured log line을 kernel text ring에 저장하는 것과 별도로 QEMU debugcon port 0xe9에도 미러링합니다.
  • ring_buffer_bytes: kernel structured log ring의 byte capacity입니다.
  • min_level: category override가 적용되기 전 모든 category의 기본 threshold입니다.
  • [logging.categories]: category별 threshold입니다.

지원 level은 off, trace, debug, info, warn, error, fatal입니다. threshold는 inclusive입니다. 예를 들어 storage = "warn"은 storage의 warn, error, fatal log를 켜고 info, debug, trace는 걸러냅니다.

카테고리

canonical category list는 libs/rustos-observability/src/lib.rs에 정의되어 있고, cfg 생성을 위해 build helper에도 같은 목록이 있습니다.

  • boot: boot manager and kernel boot sequencing
  • panic: panic과 fatal crash reporting
  • memory: physical memory, paging, heap, VM
  • sched: scheduler와 task switching
  • syscall: Linux/compat syscall entry/exit path
  • process: process/thread lifecycle
  • driver: driver loading과 driver runtime
  • storage: block device, boot volume, filesystem path
  • usb: USB host/controller/device 작업
  • input: keyboard, pointer, HID input
  • display: framebuffer, DRM, GPU, presentation path
  • vfs: VFS lookup/open/read/write path
  • console: console host와 terminal session
  • service: userspace system service
  • compat: Linux/Windows compatibility layer
  • debug: breadcrumb, diagnostic, internal debug helper
  • heartbeat: low-volume liveness marker

빌드 타임 동작

logging config는 다음과 같은 cfg flag로 컴파일됩니다.

  • rustos_debug_print_enabled
  • rustos_boot_trace_enabled
  • rustos_log_storage_debug
  • rustos_log_service_info

Kernel crate는 kernel/nucleus-core/src/debug/kdiag_macros.rs에서 생성된 macro를 사용합니다. Userspace service는 libs/observability-client의 생성 helper를 사용합니다.

config/rustos.toml을 바꾼 뒤에는 다시 빌드하세요.

cargo xtask build

userspace만 빠르게 확인하려면:

cargo xtask build-user

kernel logging 변경은 여러 kernel crate의 build.rs가 같은 cfg를 내보내므로 full build를 권장합니다.

Kernel Logging

Kernel-side logging은 kernel crate 안에서 crate::debug로 노출됩니다.

#![allow(unused)]
fn main() {
crate::debug::info!(storage, "mounted boot volume sectors={}", sector_count);
crate::debug::warn!(driver, "driver probe failed name={} err={}", name, err);
crate::debug::error_ratelimited!(usb, "xhci event ring stalled");
}

유용한 API:

  • crate::debug::enabled!(category, level): 비싼 formatting/probing 전에 log site가 켜져 있는지 확인합니다.
  • crate::debug::warn_ratelimited!, crate::debug::error_ratelimited!: site별 default interval당 한 번만 기록합니다.
  • crate::debug::snapshot_structured_log_bytes(): in-kernel text ring을 diagnostic 용도로 snapshot합니다.
  • crate::debug::report_panic(info): panic reporting path입니다.

Kernel structured log line은 다음 형태로 출력됩니다.

seq=17 ts_us=102399 tick=409596 lvl=info cat=storage mod=... line=42 pid=- tid=- msg="..."

serial_mirror = true이면 이 structured line이 QEMU debugcon에도 기록됩니다. ring이 wrap되면 snapshot에 synthetic warning line이 포함됩니다.

msg="oldest logs dropped"

Userspace Service Logging

Rust userspace service는 observability-client를 사용합니다.

#![allow(unused)]
fn main() {
observability_client::info!("runtimed", service, "ui ready received");
observability_client::warn!("sessiond", service, "session restart requested");
observability_client::error!("uiserver", display, "present failed errno={}", err);
}

첫 번째 인자는 service name string입니다. 두 번째 인자는 string이 아니라 category identifier이며, 설정된 category 중 하나여야 합니다.

Userspace log output은 os_observatory를 통해 stderr에 기록됩니다. QEMU 실행에서는 보통 guest process stderr path와 debug console plumbing을 통해 확인됩니다.

Boot Trace와 임시 Line

관련 있지만 다른 path가 두 개 있습니다.

  • Structured logging: enabled, min_level, [categories]가 제어하는 category/level log
  • Boot trace: kernel code의 boot_trace_enabled와 일부 service-local boot trace helper가 제어하는 early bring-up message

Kernel boot trace는 rustos_boot_trace_enabled를 사용합니다. 일부 userspace service에는 early bootstrap debugging용 local boot_line helper가 아직 있습니다. uiserver는 다음 환경변수도 지원합니다.

RUSTOS_UI_BOOT_TRACE=1
RUSTOS_UI_PROFILE=1

이 service-local helper들은 bring-up 때 유용하지만, 일반 diagnostic은 category filtering이 동작하도록 structured logging을 사용하세요.

Log 읽기

Host-side QEMU log는 logs/ 아래에 기록됩니다.

  • logs/debugcon.log: cargo xtask run의 기본 QEMU debugcon output
  • logs/qemu_interrupt.log: --qemu-log int 사용 시 QEMU interrupt trace
  • logs/rustos-debug.gdb: cargo xtask debug가 생성하는 helper

자주 쓰는 명령:

cargo xtask run
cargo xtask run --debugcon stdio
cargo xtask run --qemu-log int
cargo xtask debug

debug stream 자체를 조사할 때는 --debugcon stdio가 유용합니다. 일반적인 UI/QEMU 실행에는 기본 file mode가 더 적합합니다.

추천 Profile

조용한 기본 설정:

enabled = true
boot_trace_enabled = true
serial_mirror = true
ring_buffer_bytes = 16384
min_level = "info"

[categories]
syscall = "off"
heartbeat = "info"

Storage debugging:

min_level = "info"

[categories]
storage = "debug"
vfs = "debug"
driver = "info"

Syscall debugging:

min_level = "info"

[categories]
syscall = "trace"
compat = "debug"
process = "debug"

Scheduler debugging:

min_level = "warn"

[categories]
sched = "debug"
process = "debug"
heartbeat = "off"

syscall, sched, vfs처럼 매우 시끄러운 category를 켠다면 failure 이후 쓸 만한 history가 남도록 ring_buffer_bytes를 늘리세요.

새 Category 추가

기존 category로 log source를 명확히 설명할 수 없을 때만 category를 추가하세요. 새 category는 다음 위치에 모두 추가해야 합니다.

  1. libs/rustos-observability/src/lib.rs
  2. tools/build_log_cfg.rs
  3. config/rustos.toml
  4. 이 가이드

그 뒤 실행합니다.

cargo fmt --check
cargo test -p module-tests
cargo xtask check

Logging Hygiene

  • 새 log site를 추가하기 전에 기존 category와 level 조정만으로 필요한 signal을 볼 수 있는지 먼저 확인하세요. 일회성 출력을 추가하기보다 sched = "debug"처럼 category level을 임시로 올리는 방식을 우선합니다.
  • kernel log output을 새로 넣어야 한다면 안정적인 category, level, structured field를 가진 재사용 가능한 diagnostic path로 만드세요. structured logging이 준비되기 전 경로가 아니라면 local raw debugcon write는 피하세요.
  • loop, interrupt, syscall, scheduler tick, packet/block path에는 debug 또는 trace를 선호하세요.
  • service start, device ready, mount complete, UI ready 같은 lifecycle event에는 info를 사용하세요.
  • recoverable failure나 degraded fallback에는 warn을 사용하세요.
  • user-visible path를 깨뜨릴 가능성이 높은 실패에는 error를 사용하세요.
  • panic/crash class event에만 fatal을 사용하세요.
  • 반복되는 hardware, scheduler, IO error에는 ratelimited macro를 사용하세요.
  • 비싼 log payload는 enabled!로 guard하세요.
  • raw untrusted buffer, 큰 payload, secret, full memory dump는 일반 structured log로 기록하지 마세요.

Fault Injection

English | 한국어

English

RustOS fault injection is a controlled way to make common OS boundaries fail on purpose. It is for hardening recovery paths, not for random breakage.

The current path is:

  1. Rules live in config/rustos.toml under [fault_injection].
  2. cargo xtask run, debug, and probe-display pass the rules to QEMU through fw_cfg as opt/rustos/fault-injection.
  3. The kernel reads that fw_cfg file during boot after the heap is initialized.
  4. Selected kernel boundaries call should_fail("fault.point").
  5. If a rule fires, that boundary returns the same kind of failure it would return for a real device, storage, allocation, or IPC problem.

Configuration

[fault_injection]
enabled = true
rules = ["display.present=off"]

Rule format:

fault.point=action

Actions:

ActionMeaning
offRegister the point but do not fail. Good default.
failFail every call.
drop-every:NFail every Nth call.
fail-after:NLet N calls pass, then fail later calls.
rate:NFail about N out of 1000 calls.
delay-ms:NParsed for future use; delay injection is not wired yet.

Keep the rules = [...] array on one physical line for now. The current logging cfg generator also scans config/rustos.toml, and standalone multiline array closing brackets are not accepted by that parser yet.

Fault Points

PointSimulated failure
alloc.framePhysical frame allocation returns None.
block.readBlock device read returns DeviceFault.
block.writeBlock device write returns DeviceFault.
display.presentDisplay present is dropped.
display.provider.registerDriver framebuffer provider registration fails.
driver.module.loadLoadable driver module load fails.
input.event.enqueuePointer/input event is dropped before enqueue.
pci.config.readLinux compat PCI config read returns an I/O-style error.
process.spawnUser process spawn fails as if no task slot was available.
socket.recvSocket receive returns a retryable error.
socket.sendSocket send returns a retryable error.
virtio-gpu.control.submitVirtIO GPU control command submission fails.

Examples

Drop every tenth display present:

[fault_injection]
enabled = true
rules = ["display.present=drop-every:10"]

Fail storage reads after early boot has made some progress:

[fault_injection]
enabled = true
rules = ["block.read=fail-after:50"]

Inject a low-rate IPC/socket send failure:

[fault_injection]
enabled = true
rules = ["socket.send=rate:5"]

You can also pass a rule for one run without editing the config:

cargo xtask run --fault display.present=drop-every:10 --timeout 35 --summarize-log -- --no-reboot

Adding New Points

Add fault points at real failure boundaries, not inside arbitrary helper functions. Good places are allocator, block I/O, device registration, queue submit, process spawn, socket/IPC send and receive, and driver probe or load boundaries.

Use the existing shared parser in libs/rustos-fault-injection and the kernel runtime in kernel/nucleus-core/src/util/fault_injection.rs. Do not invent a one-off config format for a single subsystem.

한국어

RustOS fault injection은 OS의 중요한 경계가 일부러 실패한 것처럼 만드는 하드닝 장치입니다. 목적은 무작위로 망가뜨리는 것이 아니라, 실제 장애가 났을 때 복구 경로가 제대로 동작하는지 보는 것입니다.

현재 흐름은 이렇습니다.

  1. 규칙은 config/rustos.toml[fault_injection]에 둡니다.
  2. cargo xtask run, debug, probe-display가 규칙을 QEMU fw_cfg의 opt/rustos/fault-injection으로 넘깁니다.
  3. 커널은 heap 초기화 직후 부팅 중 fw_cfg 파일을 읽습니다.
  4. 선택된 커널 경계가 should_fail("fault.point")를 호출합니다.
  5. 규칙이 발동하면 실제 device, storage, allocation, IPC 문제가 난 것처럼 해당 경계가 실패를 반환합니다.

설정

[fault_injection]
enabled = true
rules = ["display.present=off"]

규칙 형식:

fault.point=action

지원 action:

Action의미
off지점은 등록하지만 실패시키지 않음. 기본값으로 적합합니다.
fail매번 실패
drop-every:NN번째 호출마다 실패
fail-after:NN번은 통과시키고 이후 호출 실패
rate:N1000번 중 대략 N번 실패
delay-ms:N현재는 파싱만 됩니다. 실제 delay 주입은 아직 연결되지 않았습니다.

현재는 rules = [...] 배열을 한 줄에 유지하세요. 기존 logging cfg generator가 config/rustos.toml 전체를 같이 스캔하기 때문에, 독립된 줄의 multiline 배열 닫는 대괄호를 아직 받아들이지 못합니다.

Fault Point

Point흉내 내는 실패
alloc.frame물리 frame allocation이 None 반환
block.readblock device read가 DeviceFault 반환
block.writeblock device write가 DeviceFault 반환
display.presentdisplay present drop
display.provider.registerdriver framebuffer provider 등록 실패
driver.module.loadloadable driver module load 실패
input.event.enqueuepointer/input event enqueue 전 drop
pci.config.readLinux compat PCI config read가 I/O성 오류 반환
process.spawntask slot 부족처럼 user process spawn 실패
socket.recvsocket receive가 retry 가능한 오류 반환
socket.sendsocket send가 retry 가능한 오류 반환
virtio-gpu.control.submitVirtIO GPU control command 제출 실패

예시

화면 present를 10번마다 한 번 drop:

[fault_injection]
enabled = true
rules = ["display.present=drop-every:10"]

초기 부팅 이후 storage read 실패:

[fault_injection]
enabled = true
rules = ["block.read=fail-after:50"]

낮은 확률의 IPC/socket send 실패:

[fault_injection]
enabled = true
rules = ["socket.send=rate:5"]

config를 수정하지 않고 한 번만 rule을 넘길 수도 있습니다.

cargo xtask run --fault display.present=drop-every:10 --timeout 35 --summarize-log -- --no-reboot

새 지점 추가

fault point는 아무 helper에나 넣지 말고 실제 실패 경계에 넣으세요. 좋은 위치는 allocator, block I/O, device registration, queue submit, process spawn, socket/IPC send/receive, driver probe/load 경계입니다.

규칙 파싱은 libs/rustos-fault-injection, 커널 런타임은 kernel/nucleus-core/src/util/fault_injection.rs를 사용하세요. 특정 subsystem 전용 임시 config 형식을 만들지 않습니다.

Kernel API

English | 한국어

English

This page documents the internal kernel crate API surfaces under kernel/. Most subsystem APIs are exposed through each crate's src/api.rs. Prefer these API modules over reaching into private subsystem modules.

API Surface Map

CrateAPI modulePurpose
kernel-halkernel/hal/src/api.rsGDT/IDT/ACPI/PIC/RTC/SIMD setup, interrupt hooks, CPU helpers.
kernel-mmkernel/mm/src/api.rsheap, paging, physical frames, higher-half address helpers.
kernel-objectkernel/object/src/api.rstyped object/handle/session rights shared by kernel subsystems.
kernel-ipc-runtimekernel/ipc-runtime/src/api.rskernel shared region creation, mapping, frame export.
kernel-pskernel/ps/src/api.rsscheduler, process/thread state, user task lifecycle, waits, snapshots.
kernel-io-managerkernel/io-manager/src/api.rsblock, boot volume, console, device, tty, input, USB, VFS, drivers.
kernel-compatkernel/compat/src/api.rsLinux/Windows compatibility syscall and console host API.
kernel-executivekernel/executive/src/lib.rsboot orchestration and cross-subsystem hook registration.
nucleus-corekernel/nucleus-core/src/debug/mod.rsstructured logging, panic/debug output, boot trace helpers.

Boot-Time Call Order

The kernel entry path in kernel/src/main.rs uses these APIs in strict order:

hal::disable_interrupts
debug::boot_trace::init
hal::init_gdt
hal::init_idt
mm::init_paging
hal::enter_higher_half
hal::call_with_stack
kernel_executive::boot::kernel_main_bootstrap

Do not reorder boot APIs unless the call site and subsystem invariants are reviewed together.

HAL API

Use kernel_hal::api for architecture and interrupt boundaries.

GroupKey APIsNotes
bootinit_gdt, init_idt, init_acpi, enter_higher_half, call_with_stackBoot-only setup and unsafe control transfer helpers.
cpuinit_simd, simd_mode_name, current_ripCPU feature/runtime helpers.
interruptsdisable_interrupts, init_pic, register_task_hooks, register_interrupt_hooks, register_heartbeat_hooksHook registration connects HAL IRQ paths to scheduler/IO/heartbeat behavior.
timeinit_rtcRTC initialization and dispatch registration.

Memory API

Use kernel_mm::api for allocator, paging, physical memory, and virtual address helpers.

GroupKey APIsNotes
allocKernelAllocator, init_heap, handle_alloc_errorKernel global allocator support.
bootinit_paging, init_phys, paging_smoke_testEarly memory bootstrap.
physusable_bytes, free_bytes, alloc_frame, free_framePhysical frame accounting/allocation.
address_spaceProcessAddressSpace, PageTableFlags, debug_direct_map_flags_for_addrProcess address space and debug helpers.
virthigher_half_addr, kernel_virt_offsetHigher-half address conversion.

Process/Scheduler API

Use kernel_ps::api for task scheduling and user process state.

GroupKey APIsNotes
bootinit, is_initialized, service_deferred_workScheduler lifecycle and deferred work.
faultretire_current_user_task_due_to_fault, halt_current_retired_taskUser fault disposition.
processspawn_user_process, spawn_kernel_processProcess creation.
snapshotcurrent_user_snapshot, current_user_process_id, retain_current_user_process_state, with_current_user_process_state_mutCurrent/process state access.
taskyield_now, interrupt handler addresses, console session setters, runtime hooksScheduling and interrupt integration.
waitwait_for_childWait/child status handling.

IO Manager API

Use kernel_io_manager::api for devices, boot volume state, VFS, console, and driver integration.

GroupKey APIsNotes
bootinit_gui, init_boot_info, boot_volume_identity, enter_kernel_vfs_runtime, enter_userspace_runtimeBoot volume and runtime phase transitions.
blockregister_boot_volume_opener, init_block_devices, block_descriptors, lookup_blockBlock device registration and lookup.
consoleinit_console, init_tty, write_console, service_consoleKernel console and TTY service.
deviceopen, read_to_current_user, read_to_user, ioctl_from_user/dev-style device access from kernel/syscall paths.
ttysession input/output and termios helpersConsole session IO.
driverinitialize_loadable_modules_for_class, Linux runtime hooksDriver load/service integration.
inputinit_input, interrupt handlers, service pending countersKeyboard/mouse/HID input.
usbinit_usb, debug countersUSB host path.
vfsinit_vfs, normalize_kernel_path, mount/open/metadata/access/readlink helpersCurrent-process VFS operations.

Object And IPC APIs

CrateKey APIsNotes
kernel_object::apiDeviceHandle, DeviceId, HandleToken, rights types, ConsoleSessionHandleShared object and handle vocabulary.
kernel_ipc_runtime::apicreate_shared_region, map_shared_region, shared_region_framesKernel shared memory region lifecycle.

Compatibility API

Use kernel_compat::api for Linux/Windows compatibility surfaces.

GroupKey APIsNotes
linuxLinux process/syscall state re-exports and offset helpersLinux ABI support.
windowsWindows compatibility re-exportsWindows userland compatibility.
console_hostconsole host helpersConsole-hosted user programs.
syscallinit_syscalls, service_pending, GS-base helpersSyscall and compat runtime service path.

Usage Rules

  • Import API modules with aliases, for example use kernel_mm::api as mm_api.
  • Do not call private subsystem modules from another kernel crate when an api.rs wrapper exists.
  • Boot APIs often have ordering assumptions; follow the call order in kernel/src/main.rs and kernel/executive.
  • APIs that copy to/from user memory must be called only from syscall or process-context-aware paths.
  • Use crate::debug or nucleus_core::debug for kernel logs; see Logging Guide.

한국어

이 문서는 kernel/ 아래 internal kernel crate API surface를 설명합니다. 대부분의 subsystem API는 각 crate의 src/api.rs를 통해 노출됩니다. 다른 kernel crate에서 private subsystem module을 직접 참조하기보다 이 API module을 우선 사용하세요.

API Surface Map

CrateAPI modulePurpose
kernel-halkernel/hal/src/api.rsGDT/IDT/ACPI/PIC/RTC/SIMD setup, interrupt hook, CPU helper
kernel-mmkernel/mm/src/api.rsheap, paging, physical frame, higher-half address helper
kernel-objectkernel/object/src/api.rskernel subsystem이 공유하는 typed object/handle/session rights
kernel-ipc-runtimekernel/ipc-runtime/src/api.rskernel shared region 생성, mapping, frame export
kernel-pskernel/ps/src/api.rsscheduler, process/thread state, user task lifecycle, wait, snapshot
kernel-io-managerkernel/io-manager/src/api.rsblock, boot volume, console, device, tty, input, USB, VFS, driver
kernel-compatkernel/compat/src/api.rsLinux/Windows compatibility syscall과 console host API
kernel-executivekernel/executive/src/lib.rsboot orchestration과 cross-subsystem hook registration
nucleus-corekernel/nucleus-core/src/debug/mod.rsstructured logging, panic/debug output, boot trace helper

Boot-Time Call Order

kernel/src/main.rs의 kernel entry path는 다음 순서로 API를 사용합니다.

hal::disable_interrupts
debug::boot_trace::init
hal::init_gdt
hal::init_idt
mm::init_paging
hal::enter_higher_half
hal::call_with_stack
kernel_executive::boot::kernel_main_bootstrap

boot API는 call site와 subsystem invariant를 같이 검토하지 않는 한 순서를 바꾸지 마세요.

HAL API

architecture와 interrupt boundary는 kernel_hal::api를 사용합니다.

GroupKey APIsNotes
bootinit_gdt, init_idt, init_acpi, enter_higher_half, call_with_stackboot-only setup과 unsafe control transfer helper
cpuinit_simd, simd_mode_name, current_ripCPU feature/runtime helper
interruptsdisable_interrupts, init_pic, register_task_hooks, register_interrupt_hooks, register_heartbeat_hooksHAL IRQ path를 scheduler/IO/heartbeat 동작에 연결
timeinit_rtcRTC initialization과 dispatch registration

Memory API

allocator, paging, physical memory, virtual address helper는 kernel_mm::api를 사용합니다.

GroupKey APIsNotes
allocKernelAllocator, init_heap, handle_alloc_errorkernel global allocator support
bootinit_paging, init_phys, paging_smoke_testearly memory bootstrap
physusable_bytes, free_bytes, alloc_frame, free_framephysical frame accounting/allocation
address_spaceProcessAddressSpace, PageTableFlags, debug_direct_map_flags_for_addrprocess address space와 debug helper
virthigher_half_addr, kernel_virt_offsethigher-half address conversion

Process/Scheduler API

task scheduling과 user process state는 kernel_ps::api를 사용합니다.

GroupKey APIsNotes
bootinit, is_initialized, service_deferred_workscheduler lifecycle과 deferred work
faultretire_current_user_task_due_to_fault, halt_current_retired_taskuser fault disposition
processspawn_user_process, spawn_kernel_processprocess creation
snapshotcurrent_user_snapshot, current_user_process_id, retain_current_user_process_state, with_current_user_process_state_mutcurrent/process state access
taskyield_now, interrupt handler addresses, console session setters, runtime hooksscheduling과 interrupt integration
waitwait_for_childwait/child status handling

IO Manager API

device, boot volume state, VFS, console, driver integration은 kernel_io_manager::api를 사용합니다.

GroupKey APIsNotes
bootinit_gui, init_boot_info, boot_volume_identity, enter_kernel_vfs_runtime, enter_userspace_runtimeboot volume과 runtime phase transition
blockregister_boot_volume_opener, init_block_devices, block_descriptors, lookup_blockblock device registration과 lookup
consoleinit_console, init_tty, write_console, service_consolekernel console과 TTY service
deviceopen, read_to_current_user, read_to_user, ioctl_from_userkernel/syscall path의 /dev style device access
ttysession input/output and termios helpersconsole session IO
driverinitialize_loadable_modules_for_class, Linux runtime hooksdriver load/service integration
inputinit_input, interrupt handlers, service pending counterskeyboard/mouse/HID input
usbinit_usb, debug countersUSB host path
vfsinit_vfs, normalize_kernel_path, mount/open/metadata/access/readlink helperscurrent-process VFS operation

Object And IPC APIs

CrateKey APIsNotes
kernel_object::apiDeviceHandle, DeviceId, HandleToken, rights types, ConsoleSessionHandleshared object/handle vocabulary
kernel_ipc_runtime::apicreate_shared_region, map_shared_region, shared_region_frameskernel shared memory region lifecycle

Compatibility API

Linux/Windows compatibility surface는 kernel_compat::api를 사용합니다.

GroupKey APIsNotes
linuxLinux process/syscall state re-exports and offset helpersLinux ABI support
windowsWindows compatibility re-exportsWindows userland compatibility
console_hostconsole host helpersconsole-hosted user program
syscallinit_syscalls, service_pending, GS-base helperssyscall과 compat runtime service path

Usage Rules

  • use kernel_mm::api as mm_api처럼 API module을 alias해서 import하세요.
  • api.rs wrapper가 있으면 다른 kernel crate에서 private subsystem module을 직접 호출하지 마세요.
  • boot API는 ordering assumption이 강합니다. kernel/src/main.rskernel/executive의 call order를 따르세요.
  • user memory로 copy하는 API는 syscall 또는 process-context-aware path에서만 호출해야 합니다.
  • kernel log는 crate::debug 또는 nucleus_core::debug를 사용하세요. 자세한 내용은 로깅 가이드를 참고하세요.

xtask API

English | 한국어

English

cargo xtask is the host-side control surface for RustOS. The command enum is defined in tools/xtask/src/cli.rs.

Commands

CommandPurposeMain output
cargo xtask checkValidate layering, package manifests, targets, and workspace checks.No image output.
cargo xtask buildFull OS build and stage.build/artifacts, build/image, registries.
cargo xtask stageCopy built artifacts and overlays into the boot image.build/image.
cargo xtask runRun current staged image in QEMU.QEMU session, logs/debugcon.log.
cargo xtask debugRun QEMU with GDB stub.logs/rustos-debug.gdb.
cargo xtask probe-displayHeadless display probe/stress path.Probe result and debug logs.
cargo xtask qemu-scenariosRun named QEMU regression scenarios.QEMU logs and scenario result.
cargo xtask selftestRun host selftests for contracts and hardening helpers.Cargo test output.
cargo xtask fuzz-hostRun deterministic host parser fuzz smoke tests.logs/fuzz-crash-*.bin on crash.
cargo xtask cleanRemove cargo/build outputs.Cleaned target/build dirs.
cargo xtask targetsInstall required Rust targets.Rust target availability.
cargo xtask build-efiBuild GRUB EFI boot manager only. Uses RUSTOS_GRUB_* when set, otherwise creates a local development key under build/dev-grub-gpg.build/artifacts/EFI/BOOT/BOOTX64.EFI, build/artifacts/nucleus.elf.sig.
cargo xtask build-kernelBuild Multiboot2 nucleus/kernel only.build/artifacts/nucleus.elf.
cargo xtask build-userBuild userspace packages.service/app artifacts.
cargo xtask build-console-demoBuild C demo/smoke programs.app artifacts.
cargo xtask build-driver-modulesBuild bridge driver modules..ko artifacts.

QEMU Options

cargo xtask run, debug, and probe-display accept shared options:

OptionMeaning
`--profile <defaultg14
--accel-profile kvmUse KVM acceleration and host CPU profile.
--usb-inputAttach qemu-xhci, usb-kbd, and usb-tablet.
--no-networkDisable default usernet and virtio-net-pci.
`--debugcon <filestdio
`--qemu-log <intnull>`
--timeout <seconds>Stop QEMU after a bounded run. No timeout is applied by default.
--expect <marker>Stop successfully once all repeated debugcon markers appear.
--fault <location=action>Add one validated fault-injection rule for this run.
--summarize-logPrint high-signal debugcon markers after QEMU stops.
--vfio-pci <BDF>Attach a host vfio-pci device.
--phoenix3-passthroughAuto-detect and attach Phoenix3 GPU functions.
--vfio-forceAllow devices driving active host display.

Raw QEMU args go after --:

cargo xtask run -- --no-reboot

Bounded KVM no-opt debugging uses NVMe storage by default while AHCI boundary issues are isolated separately:

cargo xtask run --profile nvme --accel-profile kvm --usb-input --debugcon file --timeout 35 --summarize-log -- --no-reboot

Fault injection rules can come from config/rustos.toml or repeated --fault arguments:

cargo xtask run --fault display.present=drop-every:10 --timeout 35 --summarize-log -- --no-reboot

Use cargo xtask qemu-scenarios --list to see the built-in scenario names.

When To Use Each Command

  • Use check before commits that change dependencies, manifests, or layer boundaries. It also validates an existing build/artifacts/nucleus.elf with grub-file --is-x86-multiboot2 when present.
  • Use build after changing code or staged image content. The default build requires GRUB public/signing key environment variables.
  • Use stage after changing only assets/image or package install metadata when artifacts are already built.
  • Use run for normal boot testing.
  • Use debug when attaching GDB.
  • Use probe-display for display, framebuffer, surface, or dirty-rect bugs.

한국어

cargo xtask는 RustOS의 host-side control surface입니다. command enum은 tools/xtask/src/cli.rs에 정의되어 있습니다.

Commands

CommandPurposeMain output
cargo xtask checklayering, package manifest, target, workspace check를 검증합니다.image output 없음
cargo xtask build전체 OS build와 stage를 수행합니다.build/artifacts, build/image, registries
cargo xtask stagebuilt artifact와 overlay를 boot image에 복사합니다.build/image
cargo xtask run현재 staged image를 QEMU에서 실행합니다.QEMU session, logs/debugcon.log
cargo xtask debugGDB stub과 함께 QEMU를 실행합니다.logs/rustos-debug.gdb
cargo xtask probe-displayheadless display probe/stress path를 실행합니다.probe result와 debug logs
cargo xtask qemu-scenarios이름이 있는 QEMU regression scenario를 실행합니다.QEMU log와 scenario result
cargo xtask selftestcontract와 hardening helper host selftest를 실행합니다.Cargo test output
cargo xtask fuzz-hostdeterministic host parser fuzz smoke test를 실행합니다.crash 시 logs/fuzz-crash-*.bin
cargo xtask cleancargo/build output을 지웁니다.정리된 target/build dirs
cargo xtask targets필요한 Rust target을 설치합니다.Rust target availability
cargo xtask build-efiGRUB EFI boot manager만 빌드합니다. RUSTOS_GRUB_* 값이 없으면 build/dev-grub-gpg 아래에 로컬 개발 키를 생성합니다.build/artifacts/EFI/BOOT/BOOTX64.EFI, build/artifacts/nucleus.elf.sig
cargo xtask build-kernelMultiboot2 nucleus/kernel만 빌드합니다.build/artifacts/nucleus.elf
cargo xtask build-useruserspace package를 빌드합니다.service/app artifacts
cargo xtask build-console-demoC demo/smoke program을 빌드합니다.app artifacts
cargo xtask build-driver-modulesbridge driver module을 빌드합니다..ko artifacts

QEMU Options

cargo xtask run, debug, probe-display는 같은 option을 받습니다.

OptionMeaning
`--profile <defaultg14
--accel-profile kvmKVM acceleration과 host CPU profile 사용
--usb-inputqemu-xhci, usb-kbd, usb-tablet attach
--no-networkdefault usernet과 virtio-net-pci 비활성화
`--debugcon <filestdio
`--qemu-log <intnull>`
--timeout <seconds>제한 시간 후 QEMU를 종료. 기본값은 timeout 없음
--expect <marker>반복 지정한 debugcon marker가 모두 나오면 성공으로 종료
--fault <location=action>이번 실행에만 validated fault-injection rule 추가
--summarize-logQEMU 종료 후 high-signal debugcon marker 요약 출력
--vfio-pci <BDF>host vfio-pci device attach
--phoenix3-passthroughPhoenix3 GPU function 자동 탐지/attach
--vfio-forceactive host display를 구동 중인 device도 허용

Raw QEMU arg는 -- 뒤에 둡니다.

cargo xtask run -- --no-reboot

KVM no-opt bounded debugging은 AHCI boundary issue를 별도로 격리하기 위해 우선 NVMe storage profile을 사용합니다.

cargo xtask run --profile nvme --accel-profile kvm --usb-input --debugcon file --timeout 35 --summarize-log -- --no-reboot

Fault injection rule은 config/rustos.toml에서 오거나 반복 지정한 --fault argument에서 옵니다.

cargo xtask run --fault display.present=drop-every:10 --timeout 35 --summarize-log -- --no-reboot

내장 scenario 이름은 cargo xtask qemu-scenarios --list로 확인합니다.

언제 어떤 명령을 쓰는가

  • dependency, manifest, layer boundary를 바꿨다면 check를 사용합니다. 기존 build/artifacts/nucleus.elf가 있으면 grub-file --is-x86-multiboot2도 검증합니다.
  • code 또는 staged image content를 바꿨다면 build를 사용합니다. 기본 build는 GRUB public/signing key 환경 변수가 필요합니다.
  • artifact가 이미 있고 assets/image 또는 install metadata만 바꿨다면 stage를 사용합니다.
  • 일반 boot test에는 run을 사용합니다.
  • GDB를 붙일 때는 debug를 사용합니다.
  • display, framebuffer, surface, dirty-rect bug에는 probe-display를 사용합니다.

Package Manifest API

English | 한국어

English

RUSTOS.package.toml is the deployment source of truth. The parser and schema types are in tools/xtask/src/package_manifest.rs.

Minimal Shape

id = "example"
kind = "service"
execution_domain = "user"
profiles = ["default"]
startup = "none"

[build]
builder = "cargo-kernel-binary"
package = "example"

[install]
path = "services/example/example.elf"

[[desktop.entries]]
display_name = "example"
weight_micros = 100
console_hosted = false

Top-Level Fields

FieldValuesMeaning
idstringStable package id used by runtime deps and registries.
kindboot, kernel, bridge-driver, user-driver, service, app, compatPackage taxonomy.
execution_domainkernel, userOptional explicit execution domain.
profilesstring listBuild/profile membership; defaults to ["default"].
startupnone, init, session, desktopStartup policy for generated registries.
runtime_depspackage id listRuntime ordering/exposure dependency metadata.

Build Section

builderPurpose
bootloader-uefiCompatibility alias for GRUB EFI boot manager generation.
kernel-rustcKernel/nucleus artifact build.
cargo-kernel-binaryRust userspace service/app ELF.
mingw-c-exeWindows PE executable demo.
c-demoHost C demo/smoke artifact.
module-imageKernel bridge .ko module image.
winsys-dll-bundleWindows system DLL bundle.
external-copyCopy externally provided artifact.

Install Section

FieldMeaning
pathRelative path inside artifacts and staged image.
layoutfile or directory; defaults to file.

Desktop Entries

[[desktop.entries]] generates desktop/runtime launch metadata.

FieldMeaning
display_nameUI/runtime display name.
imageOptional staged image path override.
execOptional executable path override.
weight_microsScheduling/task weight metadata.
logical_adminMarks privileged/admin-style components.
console_hostedWhether runtime should host it through console.
launchnone, new-session, or all-sessions.
argsCommand argv metadata.
envEnvironment entries.

Autoload Section

Bridge drivers can declare autoload metadata:

[autoload]
name = "amdgpu"
class = "display"
bus = "pci"
enabled = true
priority = 10
when = "vfs-ready"
aliases = ["pci:vendor=0x1002,class=0x03"]
provider_group = "display-primary"
fallback_only = false

Stage writes enabled entries into system/registry/kernel/loadable-drivers.tsv.

한국어

RUSTOS.package.toml은 deployment source of truth입니다. parser와 schema type은 tools/xtask/src/package_manifest.rs에 있습니다.

최소 형태

id = "example"
kind = "service"
execution_domain = "user"
profiles = ["default"]
startup = "none"

[build]
builder = "cargo-kernel-binary"
package = "example"

[install]
path = "services/example/example.elf"

[[desktop.entries]]
display_name = "example"
weight_micros = 100
console_hosted = false

Top-Level Fields

FieldValuesMeaning
idstringruntime deps와 registry에서 쓰는 stable package id
kindboot, kernel, bridge-driver, user-driver, service, app, compatpackage taxonomy
execution_domainkernel, useroptional explicit execution domain
profilesstring listbuild/profile membership, 기본값 ["default"]
startupnone, init, session, desktopgenerated registry startup policy
runtime_depspackage id listruntime ordering/exposure dependency metadata

Build Section

builderPurpose
bootloader-uefiGRUB EFI boot manager 생성용 compatibility alias
kernel-rustckernel/nucleus artifact build
cargo-kernel-binaryRust userspace service/app ELF
mingw-c-exeWindows PE executable demo
c-demohost C demo/smoke artifact
module-imagekernel bridge .ko module image
winsys-dll-bundleWindows system DLL bundle
external-copyexternally provided artifact copy

Install Section

FieldMeaning
pathartifact와 staged image 안의 relative path
layoutfile 또는 directory, 기본값 file

Desktop Entries

[[desktop.entries]]는 desktop/runtime launch metadata를 생성합니다.

FieldMeaning
display_nameUI/runtime display name
imageoptional staged image path override
execoptional executable path override
weight_microsscheduling/task weight metadata
logical_adminprivileged/admin-style component 표시
console_hostedruntime이 console로 host할지 여부
launchnone, new-session, all-sessions
argscommand argv metadata
envenvironment entries

Autoload Section

Bridge driver는 autoload metadata를 선언할 수 있습니다.

[autoload]
name = "amdgpu"
class = "display"
bus = "pci"
enabled = true
priority = 10
when = "vfs-ready"
aliases = ["pci:vendor=0x1002,class=0x03"]
provider_group = "display-primary"
fallback_only = false

stage는 enabled entry만 system/registry/kernel/loadable-drivers.tsv에 기록합니다.

Runtime Control API

English | 한국어

English

Runtime control is the userspace client API used to talk to runtimed. The public API lives in libs/runtime-control/src/lib.rs.

Constants

ConstantValue
DEFAULT_RUNTIME_SOCKET_PATH/run/runtimed.sock
DEFAULT_APPLICATIONS_DIR/usr/share/applications
DEFAULT_AUTOSTART_DIR/etc/xdg/autostart
DEFAULT_STARTUP_REGISTRY_PATH/system/registry/system/startup-programs.tsv
DEFAULT_DESKTOP_REGISTRY_PATH/system/registry/system/desktop-programs.tsv
DEFAULT_RUNTIME_LAUNCH_REGISTRY_PATH/system/registry/system/runtime-launch-programs.tsv

RuntimeClient

#![allow(unused)]
fn main() {
let client = runtime_control::RuntimeClient::open_default()?;
let programs = client.snapshot_running_programs()?;
client.request_launch_program_new_session("shell.desktop")?;
client.request_terminate_session(session_handle)?;
}
MethodPurpose
open_default()Connect through /run/runtimed.sock.
open(path)Connect through a custom socket path.
snapshot_running_programs()Return current RuntimeRunningProgram records.
request_launch_program_new_session(desktop_file_id)Launch by desktop id into a new session.
request_launch_path_new_session(exec_path)Compatibility wrapper for path launch.
request_terminate_session(session_handle)Terminate a session.
request_terminate_pid(pid)Terminate a process id.
notify_ui_ready()Tell runtimed that the UI server is ready.

Data Flow

client -> UnixStream(/run/runtimed.sock) -> RuntimeRequest -> runtimed
      <- RuntimeResponse + optional RuntimeRunningProgram payload

The protocol is fixed-size and C-layout oriented. Keep path-like request text under MAX_REQUEST_PATH_BYTES.

Registry Loading

The same crate also parses generated desktop/startup/runtime registries. Use these helpers when a service needs launch policy instead of scanning staged files manually.

한국어

Runtime control은 runtimed와 통신하는 userspace client API입니다. public API는 libs/runtime-control/src/lib.rs에 있습니다.

Constants

ConstantValue
DEFAULT_RUNTIME_SOCKET_PATH/run/runtimed.sock
DEFAULT_APPLICATIONS_DIR/usr/share/applications
DEFAULT_AUTOSTART_DIR/etc/xdg/autostart
DEFAULT_STARTUP_REGISTRY_PATH/system/registry/system/startup-programs.tsv
DEFAULT_DESKTOP_REGISTRY_PATH/system/registry/system/desktop-programs.tsv
DEFAULT_RUNTIME_LAUNCH_REGISTRY_PATH/system/registry/system/runtime-launch-programs.tsv

RuntimeClient

#![allow(unused)]
fn main() {
let client = runtime_control::RuntimeClient::open_default()?;
let programs = client.snapshot_running_programs()?;
client.request_launch_program_new_session("shell.desktop")?;
client.request_terminate_session(session_handle)?;
}
MethodPurpose
open_default()/run/runtimed.sock으로 연결합니다.
open(path)custom socket path로 연결합니다.
snapshot_running_programs()현재 RuntimeRunningProgram record를 반환합니다.
request_launch_program_new_session(desktop_file_id)desktop id로 새 session에 launch합니다.
request_launch_path_new_session(exec_path)path launch용 compatibility wrapper입니다.
request_terminate_session(session_handle)session을 종료합니다.
request_terminate_pid(pid)process id를 종료합니다.
notify_ui_ready()UI server ready 상태를 runtimed에 알립니다.

Data Flow

client -> UnixStream(/run/runtimed.sock) -> RuntimeRequest -> runtimed
      <- RuntimeResponse + optional RuntimeRunningProgram payload

protocol은 fixed-size C-layout 중심입니다. path-like request text는 MAX_REQUEST_PATH_BYTES보다 짧게 유지해야 합니다.

Registry Loading

이 crate는 generated desktop/startup/runtime registry도 parsing합니다. service가 launch policy를 알아야 할 때 staged file을 직접 scan하지 말고 이 helper를 사용하세요.

Add a Service

English | 한국어

English

Workflow

  1. Create the service crate under services/<name>/.
  2. Add the crate to the workspace in Cargo.toml.
  3. Add services/<name>/RUSTOS.package.toml.
  4. Choose kind = "service" and execution_domain = "user".
  5. Choose startup:
    • init for early system services.
    • session for session-owned services.
    • desktop for UI/desktop services.
    • none for manually launched services.
  6. Use [build] builder = "cargo-kernel-binary" for Rust userspace services.
  7. Use [install] path = "services/<name>/<name>.elf".
  8. Add at least one [[desktop.entries]] entry for registry generation.
  9. Add runtime_deps only when the service requires another package first.
  10. Run cargo xtask check, then cargo xtask build.

Minimal Manifest

id = "exampled"
kind = "service"
execution_domain = "user"
profiles = ["default"]
startup = "init"

[build]
builder = "cargo-kernel-binary"
package = "exampled"

[install]
path = "services/exampled/exampled.elf"

[[desktop.entries]]
display_name = "exampled"
weight_micros = 100
logical_admin = true
console_hosted = false

Acceptance Criteria

  • cargo xtask check passes.
  • cargo xtask build stages the service under build/image/services/<name>/.
  • Generated registries under build/image/system/registry/ include expected startup/desktop metadata.
  • Service logs use observability_client with category service.

한국어

Workflow

  1. services/<name>/ 아래 service crate를 만듭니다.
  2. root Cargo.toml workspace에 crate를 추가합니다.
  3. services/<name>/RUSTOS.package.toml을 추가합니다.
  4. kind = "service", execution_domain = "user"를 선택합니다.
  5. startup을 선택합니다.
    • early system service는 init
    • session-owned service는 session
    • UI/desktop service는 desktop
    • 수동 실행 service는 none
  6. Rust userspace service는 [build] builder = "cargo-kernel-binary"를 사용합니다.
  7. [install] path = "services/<name>/<name>.elf"를 사용합니다.
  8. registry 생성을 위해 [[desktop.entries]]를 최소 하나 추가합니다.
  9. 다른 package가 먼저 필요할 때만 runtime_deps를 추가합니다.
  10. cargo xtask check, 이후 cargo xtask build를 실행합니다.

최소 Manifest

id = "exampled"
kind = "service"
execution_domain = "user"
profiles = ["default"]
startup = "init"

[build]
builder = "cargo-kernel-binary"
package = "exampled"

[install]
path = "services/exampled/exampled.elf"

[[desktop.entries]]
display_name = "exampled"
weight_micros = 100
logical_admin = true
console_hosted = false

Acceptance Criteria

  • cargo xtask check가 통과합니다.
  • cargo xtask build 후 service가 build/image/services/<name>/ 아래에 stage됩니다.
  • build/image/system/registry/의 generated registry에 예상 startup/desktop metadata가 포함됩니다.
  • service log는 observability_clientservice category를 사용합니다.

Add an App

English | 한국어

English

Workflow

  1. Choose app type:
    • Rust app: create apps/<name>/ with Cargo.toml.
    • C smoke/demo app: create source under apps/<name>/.
    • Windows demo: place under apps/windows/<name>/.
  2. Add workspace membership for Rust apps.
  3. Add RUSTOS.package.toml at the app root.
  4. Use kind = "app" and execution_domain = "user".
  5. Use startup = "none" unless the app should auto-launch.
  6. Add [[desktop.entries]] with a clear display_name.
  7. Set console_hosted = true for terminal/console apps.
  8. Set console_hosted = false for UI/Wayland-style apps.
  9. Run cargo xtask check, then cargo xtask build.

Rust App Manifest

id = "example-app"
kind = "app"
execution_domain = "user"
profiles = ["default"]
startup = "none"

[build]
builder = "cargo-kernel-binary"
package = "example-app"

[install]
path = "apps/example-app/example-app.elf"

[[desktop.entries]]
display_name = "Example App"
weight_micros = 100
console_hosted = false

Acceptance Criteria

  • Desktop registry contains the app entry.
  • Runtime can launch the app by desktop id.
  • UI launcher/taskbar displays the expected title.

한국어

Workflow

  1. app type을 선택합니다.
    • Rust app: apps/<name>/Cargo.toml 생성
    • C smoke/demo app: apps/<name>/ 아래 source 생성
    • Windows demo: apps/windows/<name>/ 아래 배치
  2. Rust app은 workspace member에 추가합니다.
  3. app root에 RUSTOS.package.toml을 추가합니다.
  4. kind = "app", execution_domain = "user"를 사용합니다.
  5. 자동 실행이 필요하지 않으면 startup = "none"을 사용합니다.
  6. 명확한 display_name으로 [[desktop.entries]]를 추가합니다.
  7. terminal/console app은 console_hosted = true를 설정합니다.
  8. UI/Wayland-style app은 console_hosted = false를 설정합니다.
  9. cargo xtask check, 이후 cargo xtask build를 실행합니다.

Rust App Manifest

id = "example-app"
kind = "app"
execution_domain = "user"
profiles = ["default"]
startup = "none"

[build]
builder = "cargo-kernel-binary"
package = "example-app"

[install]
path = "apps/example-app/example-app.elf"

[[desktop.entries]]
display_name = "Example App"
weight_micros = 100
console_hosted = false

Acceptance Criteria

  • desktop registry에 app entry가 포함됩니다.
  • runtime이 desktop id로 app을 launch할 수 있습니다.
  • UI launcher/taskbar에 예상 title이 표시됩니다.

Add a Driver

English | 한국어

English

Workflow

  1. Choose driver ownership:
    • First-party kernel bridge: drivers/bridges/<class>/<name>/.
    • Shared driver API/helper: drivers/libs/<name>/.
    • Prebuilt/vendor module: vendor/... plus manifest.
  2. Add workspace membership for source-based Rust drivers.
  3. Add RUSTOS.package.toml.
  4. Use kind = "bridge-driver" and execution_domain = "kernel" for bridge modules.
  5. Use [build] builder = "module-image" for Rust bridge modules.
  6. Use [install] path = "system/drivers/<class>/<name>.ko".
  7. Add [autoload] metadata when the driver should be loaded by device policy.
  8. Put firmware or prebuilt external inputs under vendor/.
  9. Run cargo xtask check, then cargo xtask build-driver-modules, then cargo xtask stage or full cargo xtask build.

Autoload Example

[autoload]
name = "example"
class = "display"
bus = "pci"
priority = 10
when = "vfs-ready"
aliases = ["pci:vendor=0x1234,class=0x03"]
provider_group = "display-primary"
fallback_only = false

Acceptance Criteria

  • Driver artifact is staged under build/image/system/drivers/....
  • system/registry/kernel/loadable-drivers.tsv contains the expected metadata.
  • Driver logs use category driver, or a more specific category such as display, usb, input, or storage.

한국어

Workflow

  1. driver ownership을 선택합니다.
    • first-party kernel bridge: drivers/bridges/<class>/<name>/
    • shared driver API/helper: drivers/libs/<name>/
    • prebuilt/vendor module: vendor/...와 manifest
  2. source 기반 Rust driver는 workspace member에 추가합니다.
  3. RUSTOS.package.toml을 추가합니다.
  4. bridge module에는 kind = "bridge-driver", execution_domain = "kernel"을 사용합니다.
  5. Rust bridge module에는 [build] builder = "module-image"를 사용합니다.
  6. [install] path = "system/drivers/<class>/<name>.ko"를 사용합니다.
  7. device policy로 load되어야 하면 [autoload] metadata를 추가합니다.
  8. firmware나 prebuilt external input은 vendor/ 아래에 둡니다.
  9. cargo xtask check, cargo xtask build-driver-modules, 그 다음 cargo xtask stage 또는 full cargo xtask build를 실행합니다.

Autoload Example

[autoload]
name = "example"
class = "display"
bus = "pci"
priority = 10
when = "vfs-ready"
aliases = ["pci:vendor=0x1234,class=0x03"]
provider_group = "display-primary"
fallback_only = false

Acceptance Criteria

  • driver artifact가 build/image/system/drivers/... 아래에 stage됩니다.
  • system/registry/kernel/loadable-drivers.tsv에 예상 metadata가 포함됩니다.
  • driver log는 driver category 또는 display, usb, input, storage 같은 더 구체적인 category를 사용합니다.

Paths Reference

English | 한국어

English

PathMeaning
Cargo.tomlWorkspace manifest.
config/rustos.tomlShared RustOS operational config, including logging and kernel build knobs.
boot/Boot protocol crate shared by the GRUB-loaded nucleus.
kernel/Kernel entry and subsystem crates.
services/Userspace system services.
apps/User/demo apps.
drivers/bridges/Kernel bridge drivers.
drivers/libs/Driver ABI/runtime/helper crates.
libs/General shared crates.
compat/Compatibility layer sources.
assets/image/Static staged image overlay.
vendor/External firmware/prebuilt/module inputs.
build/artifacts/Build artifacts copied by stage.
build/image/QEMU boot volume root.
build/image/EFI/BOOT/BOOTX64.EFIGRUB-generated default UEFI entry.
build/image/nucleus.elf.sigDetached GPG signature for nucleus.elf.
build/image/system/registry/Generated runtime/driver registries.
logs/debugcon.logDefault debugcon output.
logs/qemu_interrupt.logQEMU interrupt trace when enabled.
logs/rustos-debug.gdbGDB helper generated by cargo xtask debug.

Generated Registries

RegistryPurpose
system/registry/kernel/loadable-drivers.tsvDriver autoload metadata.
system/registry/system/desktop-programs.tsvDesktop app/service metadata.
system/registry/system/runtime-launch-programs.tsvRuntime launch policy.
system/registry/system/startup-programs.tsvStartup ordering/policy.
system/registry/compat/windows-system-dlls.txtWindows DLL inventory.

한국어

PathMeaning
Cargo.tomlworkspace manifest
config/rustos.tomllogging과 kernel build knob을 포함한 RustOS operational config
boot/GRUB이 로드하는 nucleus와 공유하는 boot protocol crate
kernel/kernel entry와 subsystem crate
services/userspace system service
apps/user/demo app
drivers/bridges/kernel bridge driver
drivers/libs/driver ABI/runtime/helper crate
libs/general shared crate
compat/compatibility layer source
assets/image/static staged image overlay
vendor/external firmware/prebuilt/module input
build/artifacts/stage가 복사하는 build artifact
build/image/QEMU boot volume root
build/image/EFI/BOOT/BOOTX64.EFIGRUB이 생성한 기본 UEFI entry
build/image/nucleus.elf.signucleus.elf detached GPG signature
build/image/system/registry/generated runtime/driver registry
logs/debugcon.log기본 debugcon output
logs/qemu_interrupt.log활성화 시 QEMU interrupt trace
logs/rustos-debug.gdbcargo xtask debug가 생성하는 GDB helper

Generated Registries

RegistryPurpose
system/registry/kernel/loadable-drivers.tsvdriver autoload metadata
system/registry/system/desktop-programs.tsvdesktop app/service metadata
system/registry/system/runtime-launch-programs.tsvruntime launch policy
system/registry/system/startup-programs.tsvstartup ordering/policy
system/registry/compat/windows-system-dlls.txtWindows DLL inventory

Environment Variables Reference

English | 한국어

English

VariableDefaultPurpose
ROOT_DIRrepo rootOverride repository root.
WORKSPACE_MANIFESTCargo.tomlOverride workspace manifest path.
CARGO_TARGET_DIRtargetOverride Cargo target dir.
CARGOcargoCargo executable.
RUSTUPrustuprustup executable.
CCgccC compiler.
MINGW_CCx86_64-w64-mingw32-gccWindows PE compiler.
QEMU_BINqemu-system-x86_64QEMU executable.
KERNEL_TARGETx86_64-unknown-linux-gnuKernel/userspace target.
GRUB_MKSTANDALONEgrub-mkstandaloneGRUB standalone EFI builder.
GRUB_FILEgrub-fileMultiboot2 artifact validator.
GPGgpgGPG executable used for detached kernel signatures.
RUSTOS_GRUB_PUBKEYbuild/dev-grub.pubBinary GPG public key file embedded into GRUB, produced with gpg --export.
RUSTOS_GRUB_SIGNING_KEYRustOS Dev GRUB <rustos-dev-grub@example.invalid>GPG key id or fingerprint used to sign nucleus.elf; xtask build creates the default development key when missing.
RUSTOS_GPG_HOMEbuild/dev-grub-gpgOptional GPG home for signing.
RUSTOS_GRUB_SBATemptyOptional SBAT metadata file passed to grub-mkstandalone.
RUSTOS_GRUB_MODULESsecure boot module setOptional GRUB module list override.
BUILD_DIRbuildBuild output root.
IMAGE_DIRbuild/imageStaged image root.
OVMF_PATHvendor/firmware/ovmf/OVMF.fdFirmware image.
RUSTOS_QEMU_PROFILEdefaultQEMU profile default.
RUSTOS_QEMU_ACCELemptyQEMU accelerator profile default.
RUSTOS_QEMU_NETWORKenabledSet 0, false, off, or no to disable default network.
RUSTOS_UI_BOOT_TRACEdisabledEnable uiserver local boot trace.
RUSTOS_UI_PROFILEdisabledEnable uiserver profiling lines.

Most build variables are parsed by tools/xtask/src/config.rs. QEMU run variables are parsed by tools/xtask/src/qemu.rs. For repeated KVM no-opt debugging, use cargo xtask run --profile nvme --accel-profile kvm --usb-input --debugcon file --timeout 35 --summarize-log -- --no-reboot.

한국어

VariableDefaultPurpose
ROOT_DIRrepo rootrepository root override
WORKSPACE_MANIFESTCargo.tomlworkspace manifest path override
CARGO_TARGET_DIRtargetCargo target dir override
CARGOcargoCargo executable
RUSTUPrustuprustup executable
CCgccC compiler
MINGW_CCx86_64-w64-mingw32-gccWindows PE compiler
QEMU_BINqemu-system-x86_64QEMU executable
KERNEL_TARGETx86_64-unknown-linux-gnukernel/userspace target
GRUB_MKSTANDALONEgrub-mkstandaloneGRUB standalone EFI builder
GRUB_FILEgrub-fileMultiboot2 artifact validator
GPGgpgdetached kernel signature 생성용 GPG executable
RUSTOS_GRUB_PUBKEYbuild/dev-grub.pubgpg --export로 만든 GRUB embed용 binary GPG public key file
RUSTOS_GRUB_SIGNING_KEYRustOS Dev GRUB <rustos-dev-grub@example.invalid>nucleus.elf 서명에 사용할 GPG key id/fingerprint. 없으면 xtask build가 기본 개발 키를 생성
RUSTOS_GPG_HOMEbuild/dev-grub-gpgsigning에 사용할 optional GPG home
RUSTOS_GRUB_SBATemptygrub-mkstandalone에 넘길 optional SBAT metadata file
RUSTOS_GRUB_MODULESsecure boot module setoptional GRUB module list override
BUILD_DIRbuildbuild output root
IMAGE_DIRbuild/imagestaged image root
OVMF_PATHvendor/firmware/ovmf/OVMF.fdfirmware image
RUSTOS_QEMU_PROFILEdefaultQEMU profile default
RUSTOS_QEMU_ACCELemptyQEMU accelerator profile default
RUSTOS_QEMU_NETWORKenabled0, false, off, no로 default network 비활성화
RUSTOS_UI_BOOT_TRACEdisableduiserver local boot trace 활성화
RUSTOS_UI_PROFILEdisableduiserver profiling line 활성화

대부분의 build variable은 tools/xtask/src/config.rs에서 읽습니다. QEMU run variable은 tools/xtask/src/qemu.rs에서 읽습니다. 반복 KVM no-opt 디버깅은 cargo xtask run --profile nvme --accel-profile kvm --usb-input --debugcon file --timeout 35 --summarize-log -- --no-reboot를 사용합니다.

AI Map

Compact repo map for AI agents. For detailed routing, read docs/ai/token-policy.md and docs/ai/task-router.md.

First Files

  • AGENTS.md: root operating instructions.
  • docs/ai/token-policy.md: context budget and forbidden paths.
  • docs/ai/task-router.md: smallest context set by task type.
  • docs/ai/repo-map.md: source ownership and canonical entrypoints.
  • docs/ai/commands.md: quiet build/check commands and focused debug commands.
  • docs/ai/contracts.md: stable schemas, generated paths, API boundaries.
  • docs/ai/ring3-evacuation.md: service-first ring0 evacuation boundaries and ring3 migration candidates.
  • docs/ai/commercial-microkernel-closure.md: final hybrid closure criteria, migration marker rules, and ring0/services LOC accounting.

Use these first files as the stable prefix for AI sessions. Keep changing task details, logs, and command output after them so provider prompt/context caches can reuse the prefix.

Source Entrypoints

  • Build/run CLI: tools/xtask/src/cli.rs
  • Build orchestration: tools/xtask/src/build.rs
  • Stage/image/registries: tools/xtask/src/stage.rs
  • QEMU/debug runner: tools/xtask/src/qemu.rs
  • Host env/config: tools/xtask/src/config.rs
  • Package manifest schema: tools/xtask/src/package_manifest.rs
  • Kernel boot order: kernel/src/main.rs
  • Kernel public surfaces: kernel/*/src/api.rs
  • Runtime protocol/client: libs/runtime-control/src/lib.rs
  • Logging cfg generator: tools/build_log_cfg.rs
  • Logging policy: config/rustos.toml [logging]
  • Fault injection policy: config/rustos.toml [fault_injection]
  • Fault injection runtime: kernel/nucleus-core/src/util/fault_injection.rs

Ownership

  • kernel/: kernel entry and subsystem crates.
  • services/: userspace services.
  • apps/: demo/user applications.
  • drivers/bridges/: kernel bridge drivers and modules.
  • drivers/libs/: driver ABI/runtime/helper crates.
  • libs/: shared Rust crates.
  • boot/: boot protocol.
  • compat/: Windows/Linux compatibility support.
  • assets/image/: static boot-image overlay.

Path Policy

Generated paths, logs, vendor inputs, Cargo.lock, and large-file rules live in docs/ai/token-policy.md. Use this map for entrypoints, not path exceptions.

Fast Commands

  • cargo xtask check
  • cargo xtask build-kernel
  • cargo xtask build-user
  • cargo xtask build-driver-modules
  • cargo xtask stage
  • cargo xtask build

These should be quiet on success. Treat failure output as the first debugging context.

Cache Unit

For explicit context caching systems, cache this minimal repo context:

  1. AGENTS.md
  2. docs/ai-map.md
  3. docs/ai/token-policy.md
  4. docs/ai/task-router.md

Then append exactly one focused AI doc from docs/ai/ after classifying the task. Keep generated output, logs, and command output outside the cached unit.

AI Agent Reference

This directory is optimized for AI agents, not human onboarding.

Rules:

  • Follow token-policy.md.
  • Use root AGENTS.md, docs/ai-map.md, and task-router.md as entrypoints.
  • Read the smallest file/range needed before scanning the repo.
  • Treat human docs as explanatory and AI docs as compact contracts.
  • Verify code truth before editing when a contract references a source path.
  • For OS hardening, prioritize high-risk boundaries over broad cleanup.
  • For blocked debugging, stop and report the structural blocker instead of making speculative patches.

Stable cache prefix:

  1. Root AGENTS.md.
  2. docs/ai-map.md.
  3. token-policy.md.
  4. task-router.md.

Then append one focused AI doc selected by task-router.md.

Primary human docs:

  • docs/index.md
  • docs/ai-map.md
  • docs/getting-started.md
  • docs/execution-flow.md
  • docs/structure.md
  • docs/logging.md

Token policy:

  • Canonical policy lives in token-policy.md; do not duplicate it here.

AI Token Policy

This file is mandatory operating policy for AI agents working in this repo.

1. Start With Task Router

Always read docs/ai/task-router.md before broad repo exploration.

Default context set:

  • docs/ai/task-router.md
  • one focused AI doc selected by the router
  • one to three source files named by that focused doc

Do not preload all AI docs or all human docs.

2. Keep Human Docs And AI Docs Separate

Human docs are bilingual and explanatory. AI docs are English-only contracts.

Use human docs only when:

  • writing or revising prose docs
  • checking user-facing wording
  • AI contracts are missing the needed behavior

Use AI docs for implementation routing, source ownership, stable contracts, and verification commands.

3. Search Before Reading Large Files

Use rg before opening broad files.

Preferred pattern:

rg -n "symbol_or_contract" kernel services tools libs drivers apps docs
sed -n 'START,ENDp' path/to/file

Avoid opening files over roughly 500 lines from the top unless the task is a full-file review.

4. AI Docs Store Source-Of-Truth Paths, Not Long Explanations

AI docs should point to canonical source files and stable contracts.

Do:

  • list exact source paths
  • list stable enum/value names
  • list generated output paths
  • list verification commands

Do not:

  • duplicate long bilingual human docs
  • paste large source excerpts
  • explain background architecture unless it changes routing decisions

5. Prefer Fast Implementation Over Extended Reasoning

Default to a short reasoning pass, then make the smallest source change that can satisfy the task. Do not spend time producing broad theory, long option lists, or exhaustive subsystem analysis when the requested scope is already clear.

Do:

  • identify the narrow owner file or contract
  • state the concrete edit target if needed
  • implement promptly
  • validate with the smallest relevant command

Spend extended reasoning time only when the user asks for debugging, failure analysis, structural review, security review, or a design decision. For debugging, reason from symptoms, command output, logs, or probes before editing.

6. OS Debugging Stop Rule

RustOS debugging must not drift into speculative patches. If execution is blocked by a structural inconsistency, missing ownership boundary, missing probe, unavailable runtime evidence, or a fix that would only guess at the cause, stop changing code and report:

  • observed symptom
  • last trustworthy evidence
  • structural blocker
  • exact next evidence or owner needed

Do not fabricate a success path, add broad fallbacks, or keep hardening nearby code just because the original path is unclear.

7. Risk-Weighted Hardening

Harden the highest-risk OS surfaces first:

  • app-visible ABI and Linux ELF / Windows PE compatibility
  • privilege, capability, broker, and namespace boundaries
  • memory mapping, user-copy, handle-transfer, and lifetime checks
  • scheduler, lock ordering, IRQ-off, wait, and timeout behavior
  • boot, launch, service ownership, provider ordering, and driver loading
  • filesystem, network, input, display, and block-device mutation paths

Avoid hardening low-risk helpers, cosmetic paths, or unrelated code unless the user explicitly asks. Every hardening change should name the risk it reduces and use the narrowest source boundary that can enforce it.

8. Update AI Contracts When Behavior Changes

If a change modifies any of these, update docs/ai/contracts.md or the focused AI map in the same change:

  • package manifest schema
  • xtask command behavior
  • generated registry path or field contract
  • logging category/level behavior
  • kernel api.rs boundary
  • runtime socket/protocol behavior
  • docs navigation or AI routing

9. Avoid Ad Hoc And Hardcoded Policy

Prefer manifest fields, registries, protocol state, and existing subsystem APIs over ad hoc branches or hardcoded names, paths, priorities, and ordering. If a temporary hardcoded fallback is unavoidable, keep it narrow, document the source of truth it is standing in for, and route future behavior through the stable contract instead of expanding the special case.

10. Avoid Generated And Vendor Paths By Default

Do not inspect these paths unless the task explicitly involves generated output or external binary inputs:

  • build/
  • target/
  • logs/
  • vendor/
  • perf.data
  • Cargo.lock

Allowed exceptions:

  • QEMU/debug failure investigation may inspect logs/.
  • Stage verification may inspect build/image/system/registry/.
  • Firmware/module packaging may inspect specific vendor/ paths.
  • Dependency resolution work may inspect focused Cargo.lock snippets.

When using an exception, inspect the narrowest file/path possible.

11. Logs And Large Files

Never read whole log files by default.

Preferred patterns:

tail -n 120 logs/debugcon.log
rg -n "panic|error|failed|DisplayUnavailable" logs/debugcon.log
sed -n 'START,ENDp' path/to/large.rs

For files over roughly 500 lines:

  • search with rg -n first
  • open one focused range
  • summarize findings before opening another range

Avoid opening Cargo.lock unless dependency resolution changed. Use rg -n "crate-name" Cargo.lock before reading a range.

12. Prompt Cache Hygiene

Keep stable context stable across requests:

  • put durable repo instructions first
  • keep task-specific details and pasted output at the end
  • avoid rewriting stable instruction text mid-session
  • avoid adding logs or generated output to the reusable prefix

OpenAI-style prompt caching works best when the beginning of the prompt is an exact reusable prefix. Treat this sequence as the stable prefix:

  1. AGENTS.md
  2. docs/ai-map.md
  3. docs/ai/token-policy.md
  4. docs/ai/task-router.md
  5. one focused docs/ai/* file selected by the router

Put user-specific task text, command output, logs, and file snippets after that prefix.

For Gemini-style explicit context caching, cache the same stable prefix for repeated repository analysis or bug-fixing sessions. Do not cache generated output, logs, or broad source dumps; attach those as short task-specific suffixes only when needed.

AI Task Router

Pick the smallest context set. Do not load all docs.

Mandatory first step: read token-policy.md.

Second step: classify the user task into one row below. Read only the Read first files, then use rg -n before opening any file listed under Then read only if needed.

User taskRead firstThen read only if needed
Build/check issuecommands.mdexact failing command output, then tools/xtask/src/build.rs range found by rg
Run/QEMU/debug issuecommands.md, repo-map.mdexact tools/xtask/src/qemu.rs range found by rg; logs only via tail -n 120 or focused rg
Package/stage/registry issuecontracts.mdaffected RUSTOS.package.toml, then exact package_manifest.rs or stage.rs range
Kernel API/changekernel-api-map.mdrelevant kernel/*/src/api.rs, then backing module range found by symbol search
Kernel boot-order changekernel-api-map.md, contracts.mdkernel/src/main.rs, then exact kernel/executive/src/boot.rs range
Logging changecontracts.mdconfig/rustos.toml; open tools/build_log_cfg.rs only after searching category/level name
Fault injection changecontracts.md, commands.mdconfig/rustos.toml; exact libs/rustos-fault-injection, tools/xtask/src/qemu.rs, or kernel/nucleus-core/src/util/fault_injection.rs range found by rg
Runtime launch/session issuecontracts.mdlibs/runtime-control/src/lib.rs, then exact services/runtimed/src/main.rs range
UI/rendering issuerepo-map.mdsearch services/uiserver/src; open only the matching render.rs or app/* range
Hardening requestcontracts.md, kernel-api-map.mdhighest-risk boundary first; exact API, broker, service, lock, memory, or device path found by rg
Ring0/ring3 ownership or microkernel boundarycontracts.md, ring3-evacuation.mdcommercial-microkernel-closure.md for final-shape/LOC questions; kernel-api-map.md, then exact broker, service, driver, input, storage, or compat path found by rg
Add service/app/driverworkflows.mdone closest existing manifest, one closest source file, target manifest/source only
Docs updatedocs/SUMMARY.mdtarget doc only; AI docs only if agent context changes

Stop rules:

  • If task can be answered from one AI doc and one source file, stop searching.
  • If rg returns an exact symbol/function, open only a narrow range around it.
  • If the user asks for implementation and the target owner is clear, stop reasoning and patch the smallest viable slice.
  • Reserve extended reasoning for debugging, failure analysis, structural review, security review, or explicit design-choice requests.
  • For hardening, rank the OS risk first; do not spend time hardening unrelated low-risk helpers after the high-risk boundary is identified.
  • If debugging hits a structural blocker or lacks runtime evidence, stop and report the blocker instead of making speculative patches.
  • Do not open a backing module until the relevant api.rs or manifest contract shows the needed boundary.
  • Do not inspect logs/ for build/check failures; use the failing command output first.
  • Do not inspect logs/ for run/debug failures until the QEMU command line and failing symptom are known.
  • Follow token-policy.md for generated paths, logs, and Cargo.lock.
  • If a human doc duplicates an AI contract, use the AI contract unless writing prose.
  • If source contradicts AI docs, source wins; update AI docs if task includes docs.
  • If a contract change is discovered, update the focused AI doc before finishing.

Context budget defaults:

  • Simple answer: this file plus one focused AI doc.
  • Small code change: one focused AI doc plus 1-3 source ranges.
  • Debugging: one command doc plus failing output or one focused log snippet.
  • Cross-subsystem work: add contracts.md and the relevant API map only when the boundary crosses crates or services.

Escalation rule:

  • Before opening a fourth source file or second large range, summarize the current hypothesis and name the exact missing fact.

AI Repo Map

Goal: minimize repo scan tokens.

Read token-policy.md and task-router.md before using this map.

For a one-screen map usable from any tool, see docs/ai-map.md.

Core entrypoints:

  • Workspace: Cargo.toml
  • Build/run CLI: tools/xtask/src/cli.rs
  • Build orchestration: tools/xtask/src/build.rs
  • Stage/registries: tools/xtask/src/stage.rs
  • QEMU runner: tools/xtask/src/qemu.rs
  • Host config/env: tools/xtask/src/config.rs
  • Package schema: tools/xtask/src/package_manifest.rs
  • Runtime client/protocol: libs/runtime-control/src/lib.rs
  • Logging config parser/cfg: tools/build_log_cfg.rs
  • Logging policy: config/rustos.toml [logging]
  • Fault injection policy: config/rustos.toml [fault_injection]
  • Fault injection runtime: kernel/nucleus-core/src/util/fault_injection.rs
  • Kernel API surfaces: kernel/*/src/api.rs
  • Kernel boot entry: kernel/src/main.rs
  • Kernel orchestration: kernel/executive/src/lib.rs, kernel/executive/src/boot.rs

Ownership map:

  • boot/: boot protocol crate shared by the GRUB-loaded nucleus.
  • kernel/: kernel entry and subsystem crates.
  • services/: userspace services (initd, runtimed, uiserver, etc.).
  • apps/: user/demo applications.
  • drivers/bridges/: kernel bridge drivers and .ko modules.
  • drivers/libs/: driver ABI/runtime/helper crates.
  • libs/: general shared crates.
  • compat/: compatibility layer and Windows userspace support.
  • assets/image/: static files copied into boot image.
  • vendor/: external binary inputs.
  • build/: generated output; do not edit as source.
  • logs/: run/debug output; do not edit as source.

Docs:

  • Human landing: docs/index.md
  • mdBook nav: docs/SUMMARY.md
  • Structure rules: docs/structure.md
  • Logging: docs/logging.md
  • OS dev APIs: docs/api/*.md
  • Task guides: docs/guides/*.md
  • Stable paths/env: docs/reference/*.md

Before editing:

  • For package/stage behavior, inspect tools/xtask/src/package_manifest.rs and tools/xtask/src/stage.rs.
  • For QEMU behavior, inspect tools/xtask/src/qemu.rs.
  • For runtime launch behavior, inspect services/runtimed/src/main.rs and libs/runtime-control/src/lib.rs.
  • For UI behavior, inspect services/uiserver/src/app/* and services/uiserver/src/render.rs.
  • For kernel subsystem integration, inspect the relevant kernel/*/src/api.rs first, then the backing module.
  • For documentation navigation, inspect docs/SUMMARY.md first.

Avoid by default:

  • target/, build/, logs/: generated or run output.
  • vendor/: external binary inputs.
  • Cargo.lock: only inspect if dependency resolution changed.
  • perf.data: binary profiling output; never inspect as text.
  • Full docs/logging.md or docs/api/kernel.md: use AI contracts first.

Allowed generated-path exceptions are defined in token-policy.md.

AI Commands

Use from repo root.

CommandUseWritesCommon failure meaning
cargo xtask checkvalidate layering/manifests/workspacetarget/dependency layer violation, bad manifest, missing target
cargo xtask buildfull OS build + stagetarget/, build/compile error, missing firmware/artifact, manifest staging error
cargo xtask stagerestage built artifactsbuild/imagemissing required artifact, bad install path
cargo xtask runboot current image in QEMUlogs/, temp dirsmissing build/image, missing OVMF, QEMU failure
cargo xtask debugQEMU with GDB stublogs/rustos-debug.gdbsame as run plus debug setup
cargo xtask probe-displayheadless display probe with screendump geometry and non-black frame validationlogs/display/surface/present regression
cargo xtask qemu-scenarios --listlist predefined QEMU regression scenariosnoneunknown local xtask binary
cargo xtask qemu-scenarios --scenario display-proberun one QEMU regression scenariologs/boot/display/input regression
cargo xtask selftesthost selftests for fault parsing, ABI/layout, runtime contracts, and module teststarget/contract/layout regression
cargo xtask fuzz-host --target alldeterministic host fuzz smoke for fault rules, project config, and package manifest parsinglogs/ on crashparser panic or invariant bug
cargo xtask build-useruserspace packages onlytarget/, build/artifactsservice/app compile error
cargo xtask build-driver-modulesbridge modules onlytarget/, build/artifactsdriver/module build error
cargo test -p module-testsmodule teststarget/unit/module regression
git diff --checkwhitespace sanitynonetrailing whitespace/conflict marker

QEMU args:

  • xtask args before --.
  • raw QEMU args after --.
  • Example: cargo xtask run --profile nvme -- --no-reboot.
  • Short KVM no-opt debug runs should use the built-in timeout and summary: cargo xtask run --profile nvme --accel-profile kvm --usb-input --debugcon file --timeout 35 --summarize-log -- --no-reboot.
  • Use repeated --expect <marker> when a run should stop as soon as specific debugcon markers appear. Without --expect, --timeout is a controlled stop.
  • Use repeated --fault <location=action> to pass a validated fault-injection rule to the guest through QEMU fw_cfg (opt/rustos/fault-injection).
  • Fault rule examples: display.present=drop-every:10, block.read=fail-after:50, socket.send=rate:5.
  • Prefer --summarize-log and focused rg over opening whole log files.
  • Do not add ad hoc QEMU or kernel debug branches for one driver. Route durable debug state through logging, milestones, registries, and common subsystem APIs.

Do not run:

  • destructive git commands unless explicitly requested.
  • formatters that rewrite files unless the task is implementation, not planning/review.

Docs verification:

  • mdbook build if mdbook exists.
  • rg -n "\[[^]]+\]\(([^)#]+\.md)" docs README.md to inspect md links.
  • top-level human docs should include [English](#english) | [한국어](#korean).

Fast context commands:

  • rg -n "symbol_or_path" kernel services tools libs drivers apps
  • find kernel -maxdepth 4 -name api.rs | sort
  • find . -name RUSTOS.package.toml | sort
  • rg -n "enum XtaskCommand|struct Config|enum PackageKind" tools/xtask/src
  • sed -n 'START,ENDp' path/to/file after rg finds the relevant line range.

GRUB Secure Boot debug environment:

  • cargo xtask build creates a local development GRUB signing key under build/dev-grub-gpg when RUSTOS_GRUB_* is unset.
  • grub-file --is-x86-multiboot2 build/image/nucleus.elf
  • gpg --homedir build/dev-grub-gpg --verify build/image/nucleus.elf.sig build/image/nucleus.elf

KVM display boot loop:

  • cargo xtask build
  • cargo xtask run --profile nvme --accel-profile kvm --usb-input --debugcon file
  • rg -n "error: no suitable video mode|boot framebuffer|bootfb|virtio-gpu|virtio register|DisplayUnavailable|uiserver|panic|scheduler invalid" logs/debugcon.log logs/qemu*.log

Use rg --files instead of recursive ls or broad find when searching many files.

Generated path exceptions:

  • Inspect logs/ only for run/debug failures.
  • Inspect build/image/system/registry/ only for stage/registry verification.
  • Inspect vendor/ only for firmware/module packaging tasks.

AI Contracts

Package manifest:

  • File name: RUSTOS.package.toml.
  • Parser: tools/xtask/src/package_manifest.rs.
  • Package ids are stable dependency keys.
  • runtime_deps references package id, not path or desktop id.
  • Valid kind: boot, kernel, bridge-driver, user-driver, service, app, compat.
  • Valid execution_domain: kernel, user.
  • Valid startup: none, init, session, desktop.
  • Valid install.layout: file, directory.
  • Valid desktop.entries.launch: none, new-session, all-sessions.
  • Driver [autoload] supports deps for required module preloads and softdeps for best-effort preloads, matching Linux modules.dep and modprobe.d softdep pre: roles.
  • Driver autoload list fields are staged as comma-separated registry values; individual list items must not contain tab, newline, carriage return, or comma.
  • Driver [autoload].linux_driver_names lists Linux in-module driver names allowed to register from that package. If omitted, staging defaults it to the autoload name. Linux driver compat registration must use this registry field rather than hardcoded driver names.
  • Driver [autoload].provider_group is a mutually exclusive provider contract. Once a loadable or native provider marks the group active, later candidates in the same group are skipped. fallback_only candidates are ordered after normal candidates and should be used only as lower-priority substitutes.
  • In the display-primary provider group, real hardware/virtio display providers must be ordered ahead of firmware framebuffer fallbacks. bootfb is a last-resort fallback, not the default primary for QEMU or hardware GPUs.
  • driverd owns driver autoload policy. Kernel driver brokers may expose narrow hardware-presence primitives for staged aliases such as platform:bootfb, pci:*, and virtio:*, but they must not pick provider order or bypass registry provider_group policy.

Stage outputs:

  • Boot image root: build/image.
  • Artifact root: build/artifacts.
  • Static overlay: assets/image.
  • UEFI entry: GRUB-generated build/image/EFI/BOOT/BOOTX64.EFI.
  • Kernel payload signature: build/image/nucleus.elf.sig.
  • Registries:
    • system/registry/kernel/loadable-drivers.tsv
    • system/registry/system/desktop-programs.tsv
    • system/registry/system/runtime-launch-programs.tsv
    • system/registry/system/startup-programs.tsv
    • system/registry/system/linux-runtime-access.tsv
    • system/registry/system/runtime-env.tsv
    • system/registry/compat/windows-system-dlls.txt
  • Linux runtime filesystem access is staged into system/registry/system/linux-runtime-access.tsv as kind=dir|file and path=/absolute/path fields. Kernel VFS should consume that registry instead of carrying hardcoded default runtime path allowlists.
  • Userspace default environment policy is staged into system/registry/system/runtime-env.tsv as scope=init|runtime, key=NAME, and value=VALUE fields. initd and runtimed should consume this registry instead of hardcoding default PATH, HOME, XDG_*, or display env values.

Runtime control:

  • Client crate: libs/runtime-control.
  • Default socket: /run/runtimed.sock.
  • Main methods: snapshot_running_programs, request_launch_program_new_session, request_terminate_session, request_terminate_pid, notify_ui_ready.
  • Request text max: MAX_REQUEST_PATH_BYTES.

Kernel/userspace ABI:

  • Shared ABI crate: libs/rustos-user-abi.
  • Kernel re-export surfaces: kernel/ps/src/user/abi.rs and kernel/compat/src/user/abi.rs.
  • The kernel launches services/rootd/rootd.elf as the first user process. rootd is the bootstrap initial task: it must avoid Linux libc/std dynamic runtime dependencies, start syscalld, vfsd, loaderd, and procd, then hand off normal service orchestration to services/initd/initd.elf. Kernel boot code should not grow generic POSIX compatibility exceptions for initd; any unavoidable early service bootstrap surface must stay narrow, explicit, and tied to rootd bringing up foundational policy services.
  • Current refactor phase is service-first ring0 evacuation. The old line-commented Linux compat reference files have been consumed and removed from the kernel tree. Linux MM ABI policy for brk, mmap, mprotect, and munmap belongs to syscalld; kernel MM keeps only the gated SYS_RUSTOS_MM_BROKER primitive for target address-space PTE mutation, fd backing revalidation, shared-frame lifetime holds, and display-surface mapping. Linux thread/fork/exec/signal policy and Windows PE/Win32 policy now have live service-first implementations through loaderd, procd, syscalld, and narrow kernel brokers; process and signal policy belongs to procd, executable image policy belongs to loaderd, clock policy belongs to syscalld except hot read-only clock_gettime/nanosleep fast paths that may stay in the kernel to avoid per-call IPC latency, and io-manager VFS/network/USB/input/provider policy belongs to the user services. Do not restore deleted or commented ring0 policy modules for quick compatibility fixes. Extend service implementations and keep kernel code to deliberate privileged primitives such as syscall entry, address-space mutation, scheduler state, user-memory copy, interrupt/MMIO access, DMA, or module-load substrate. Compile and QEMU verification can be deferred for tasks whose explicit goal is structural evacuation rather than bootability.
  • The target architecture is a hybrid kernel. Services own routing and policy, but ring0 intentionally retains compatibility-critical mechanisms: syscall/trap entry, gated syscall brokers, address-space mutation, scheduler/task mutation, user-copy, IRQ/MMIO/DMA/IOMMU access, and kernel-address-space .ko module execution. Linux .ko modules must remain ring0 for commercial driver compatibility: the kernel module ABI assumes direct access to kernel symbols, IRQ state, DMA/MMIO mappings, Linux-style callback context, and shared in-kernel driver data structures. Do not describe the system as a pure microkernel, and do not move .ko execution or syscall broker primitives out of the kernel without a replacement that preserves native Linux ELF, Windows PE, and commercial driver behavior. Move the policy around those mechanisms to services instead; see docs/ai/ring3-evacuation.md.
  • Device, console, and UI repr(C) structs and ioctl numbers must be defined in rustos-user-abi; services such as uiserver and runtimed should use that crate rather than duplicating request structs or ioctl encoding logic.
  • RustOS IPC and Linux syscall-offload ABI lives in rustos-user-abi::syscall. Service endpoints are registered through SYS_RUSTOS_IPC_REGISTER_SERVICE_ENDPOINT and looked up by stable IPC_SERVICE_* ids. Registering endpoint 0 revokes the service endpoint and later lookups fail closed. syscalld is service id 1, vfsd is service id 2, netd is service id 3, devmgrd is service id 4, driverd is service id 5, loaderd is service id 6, storaged is service id 7, inputd is service id 8, and procd is service id 9. File/path Linux syscall policy should route to vfsd; AF_UNIX and socket control policy should route to netd; device open/ioctl policy should route to devmgrd; module autoload/provider policy belongs in driverd; executable format and launch policy belongs in loaderd; storage inventory policy belongs in storaged; input observability/control policy belongs in inputd; process/fork/wait and signal policy belongs in procd. Kernel FD/socket/module/process/storage/input data paths remain as gated narrow broker primitives for privileged DMA/MMIO/IRQ/module-load/socket/user-copy/ address-space mutation compatibility; moving drivers to isolated ring-3 domains is intentionally excluded for Linux/Windows commercial compatibility.
  • Registered service endpoints also carry kernel-tracked broker capability bits derived from their IPC_SERVICE_* id. Broker authorization must check the current process' registered service capability, not its executable path. Current capability constants are IPC_SERVICE_CAP_LINUX_SYSCALL_POLICY, IPC_SERVICE_CAP_VFS_POLICY, IPC_SERVICE_CAP_NET_POLICY, IPC_SERVICE_CAP_DEVICE_POLICY, IPC_SERVICE_CAP_DRIVER_POLICY, IPC_SERVICE_CAP_PROCESS_LOADER, IPC_SERVICE_CAP_STORAGE_POLICY, IPC_SERVICE_CAP_INPUT_POLICY, and IPC_SERVICE_CAP_PROCESS_POLICY. procd owns process/thread namespace policy for Linux execve, process-copy fork/clone, wait4, rt_sigaction, rt_sigprocmask, sigaltstack, tgkill, and signal selection. Kernel code must keep only user-copy, address-space replacement, scheduler mutation, pending-signal wakeup, and Linux x86_64 rt_sigframe/rt_sigreturn primitives.
  • Kernel IPC endpoint calls support bounded cap-transfer slots through kernel_ipc_runtime::api::KernelTransferredHandle and the *_with_handles endpoint APIs. Byte-only recv/take wrappers must keep failing with BufferTooSmall when a queued message or reply contains transferred handles, so older paths do not silently drop capabilities. Transferred handles require an explicit nonzero transfer ticket and rights whose HandleRights::allows_transfer() is true.
  • Process FD tables expose transfer only through kernel_ps::api::TransferredHandleEntry and HandleTable::{duplicate_for_transfer, install_transferred}. Export requires the source handle class and rights to permit descriptor transfer; directory FDs are file capabilities and are transferable for VFS service migration.
  • Userspace handle-aware IPC uses SYS_RUSTOS_IPC_{CALL,RECV,REPLY}_WITH_HANDLES with the shared Ipc*WithHandlesArgs structs. Send handles are Linux fd arrays; received handles are installed into the receiver fd table and returned as i32 fd arrays plus a u16 count. recv_fd_count_ptr is mandatory for the handle-aware ABI, even when no handles are returned. Counts are bounded by IPC_MAX_TRANSFER_HANDLES, and byte-only IPC syscalls must not silently carry or discard transferred handles.
  • VFS ownership uses VfsIpcRequest / VfsIpcResponse, separate from LinuxSyscallOffloadRequest, for service-owned file handles and chunked I/O. vfsd owns the Linux-visible namespace, cwd, directory cursors, regular file cursors, remote file ids, and root FAT parsing. Kernel fd tables mirror these service-owned objects as KernelHandle::RemoteVfs; kernel code may still own bootstrapping, process/MM, user-memory copying at syscall entry, and explicit broker primitives.
  • SYS_RUSTOS_BLOCK_BROKER is the narrow boot-volume read broker for vfsd. It is gated by IPC_SERVICE_CAP_VFS_POLICY, accepts RustosBlockBrokerArgs, and exposes only boot-volume info plus bounded read-only block reads. This migration does not depend on storaged.
  • storaged owns block-device inventory policy after it registers IPC_SERVICE_STORAGED. It calls the gated SYS_RUSTOS_STORAGE_LIST_BROKER primitive, which is authorized only by IPC_SERVICE_CAP_STORAGE_POLICY, to enumerate kernel-discovered storage descriptors without exposing direct generic-app storage probing.
  • inputd owns input queue observability and input-read authorization policy after it registers IPC_SERVICE_INPUTD. Kernel Linux input reads call InputdIpcRequest / InputdIpcResponse with INPUTD_IPC_OP_AUTHORIZE_READ; inputd approves the access class and maximum read size, then ring0 performs only the current-process user-copy/device data path. inputd also calls the gated SYS_RUSTOS_INPUT_STATS_BROKER primitive, authorized only by IPC_SERVICE_CAP_INPUT_POLICY, to inspect kernel input queue counters while the remaining event queue is being evacuated.
  • Linux openat installs KernelHandle::RemoteVfs for regular files and directories after vfsd registration. Device paths remain kernel device handles through the device broker path until devmgrd device-open transfer is complete. Policy services may still use the bootstrap VFS path to avoid recursive self-IPC during service startup. Before vfsd registers its endpoint, the gated bootstrap VFS broker remains available for service dynamic-loader bootstrap; after registration, generic Linux app VFS syscalls must route to vfsd or fail closed if vfsd is unavailable.
  • Linux close, dup/dup2/dup3, and fcntl route through vfsd before mutating the app fd table. vfsd is the only intended caller of the gated narrow SYS_RUSTOS_FD_*_BROKER broker primitives; generic apps must not use them directly. LinuxSyscallOffloadRequest.arg0..arg3 are the 64-bit extension slots for fd control arguments such as target fd, command, argument, and flags. Do not pack pointer or flag values into the 32-bit mask field.
  • Linux getdents64 also routes through vfsd; the gated narrow SYS_RUSTOS_FD_GETDENTS64_BROKER broker primitive writes directory records into the target process address space selected by pid. FD broker syscalls must remain gated to the registered IPC_SERVICE_CAP_VFS_POLICY owner, not broad policy-service callers.
  • Linux mount and umount2 must preserve Linux ELF compatibility while keeping namespace policy in vfsd: generic app syscalls route to vfsd, then vfsd calls the gated narrow SYS_RUSTOS_VFS_*_BROKER broker primitives for the narrow kernel mount-table mutation. Do not reintroduce direct generic-app linux_ops::mount or linux_ops::umount2 paths.
  • Legacy RustOS metadata syscall numbers SYS_RUSTOS_{STATX,STAT,READLINK,ACCESS,GETCWD,CHDIR}_METADATA must not perform direct generic-app VFS policy in ring0 after vfsd registers. They route through vfsd for generic callers and retain direct kernel metadata access only for pre-vfsd bootstrap and registered policy-service callers.
  • Runtime launches must route through loaderd, not direct generic SYS_RUSTOS_SPAWN_EXEC calls. loaderd registers IPC_SERVICE_LOADERD, validates executable format policy, and uses the gated narrow SYS_RUSTOS_PROC_*_BROKER broker primitives for kernel-owned process commit work. SYS_RUSTOS_PROC_*_BROKER calls must fail with EACCES unless the caller owns IPC_SERVICE_CAP_PROCESS_LOADER. SYS_RUSTOS_SPAWN_EXEC is restricted to rootd spawning the fixed bootstrap service allowlist (syscalld, vfsd, loaderd, procd, initd) and must fail closed for initd, generic apps, and service restarts. Core-service supervision after bootstrap needs an explicit rootd/supervisor contract, not a broader kernel spawn fallback.
  • Process broker sessions start with SYS_RUSTOS_PROC_PREPARE_BROKER using PROC_BROKER_ABI_VERSION and an explicit executable format (PROC_BROKER_FORMAT_ELF64 or PROC_BROKER_FORMAT_PE64). The returned prepare_handle is owned by the loader service process and must be supplied to SYS_RUSTOS_PROC_COMMIT_BROKER or SYS_RUSTOS_PROC_ABORT_BROKER. SYS_RUSTOS_PROC_MAP_ZEROED_BROKER, SYS_RUSTOS_PROC_MAP_DATA_BROKER, and SYS_RUSTOS_PROC_MAP_FILE_BROKER use PROC_BROKER_MAP_{READ,WRITE,EXEC,PRIVATE} flags and record non-overlapping page-aligned mappings in the prepare session. SYS_RUSTOS_PROC_MAP_FILE_BROKER and its batch variant SYS_RUSTOS_PROC_MAP_FILE_BATCH_BROKER are fd/cap-backed only: the kernel resolves the caller's fd to a pinned KernelHandle at registration time; no path re-open occurs at commit. Backing must be a file-kind handle (VfsFile, RemoteVfs(File), or Memfd); directory, device, and socket descriptors are rejected with EINVAL/EACCES. loaderd must emit ELF PT_LOAD mappings for both the main image and its PT_INTERP interpreter via SYS_RUSTOS_PROC_MAP_FILE_BROKER, using the static-PIE load biases (PROC_BROKER_USER_SPACE_BASE + 0x0040_0000 for the main image and PROC_BROKER_USER_SPACE_BASE + 0x0200_0000 for the interpreter). The kernel prepare session stores loader-materialized data pages for mappings that need service-side fixups. Linux ELF sessions must use SYS_RUSTOS_PROC_SET_LINUX_RUNTIME_BROKER to supply minimal launch metadata (entry, phdr, phnum, phent, brk_start, interpreter_base) instead of streaming the raw binary with SYS_RUSTOS_PROC_SET_IMAGE_BLOB_BROKER; the kernel derives process launch state from this metadata and the pre-built address space. Commit builds the child address space from the recorded mappings. Windows PE64 policy belongs to loaderd: PE validation, section materialization, base relocation, import/export resolution, staged system-DLL registry lookup, and PEB/TEB/runtime blob construction happen before commit. PE64 commit must include SYS_RUSTOS_PROC_SET_WINDOWS_RUNTIME_BROKER metadata after all SYS_RUSTOS_PROC_MAP_DATA_BROKER mappings and before SYS_RUSTOS_PROC_COMMIT_BROKER; the kernel validates the metadata and spawns the already-materialized address space, but must not reintroduce PE import/export/system-DLL policy. Linux app execve goes through procd for target authorization and then loaderd for executable image materialization; if loader materialization fails, procd must cancel the exec ticket with SYS_RUSTOS_PROC_CANCEL_EXEC_BROKER before replying. Do not move executable-format, import/export, or DLL namespace policy back into the kernel.
  • Policy-sensitive Linux ioctl requests route through devmgrd after bootstrap. devmgrd owns request authorization and calls SYS_RUSTOS_DEVICE_IOCTL_BROKER, which is gated by IPC_SERVICE_CAP_DEVICE_POLICY and performs the kernel-owned user memory/device operation against the target process id and fd. The kernel may use a direct ioctl fallback before IPC_SERVICE_DEVMGRD is registered, and hot data-path ioctls such as display present may remain direct broker calls to avoid per-frame policy IPC.
  • Windows syscall policy routes through syscalld using Win32SyscallOffloadRequest/Win32SyscallOffloadResponse and the SYSCALL_OFFLOAD_OP_WIN32_* operation range. The kernel Windows dispatcher calls this service policy first, then performs only the narrow privileged action that still requires current-process user memory, handle, scheduler, or address-space access.
  • Linux wait4 routes process ownership validation through procd; the kernel still performs the narrow process-table wait and status/rusage copyout. Linux memfd_create route policy validation remains in syscalld, while the kernel performs handle installation and memfd read/write/truncate/seal actions because those operate on current process handles and user memory.
  • Linux socket namespace and socket I/O operations route through netd after bootstrap. socket, socketpair, bind, listen, accept/accept4, connect, sendto, recvfrom, sendmsg, recvmsg, getsockname, getpeername, setsockopt, getsockopt, and shutdown call netd, and netd invokes the gated SYS_RUSTOS_NET_BROKER primitive with the target process id. Kernel code still performs handle installation, target user-memory validation/copy, and the current in-kernel socket/inet substrate; policy routing and namespace sequencing belong to netd. The net broker argument struct carries six 64-bit syscall argument slots for this migration surface.
  • driverd owns registry parsing and provider/autoload ordering after it registers IPC_SERVICE_DRIVERD. The gated driver broker surface is SYS_RUSTOS_DRIVER_LOAD_MODULE_BROKER, SYS_RUSTOS_DRIVER_PROBE_ALIAS_BROKER, and SYS_RUSTOS_DRIVER_PROVIDER_ACTIVE_BROKER; the kernel side only loads an explicit module image, probes hardware aliases, or reports active provider groups for final safety checks. Early boot may still use the legacy kernel registry path until driver service bootstrap owns display/input/network bring-up.
  • devmgrd owns the visible /dev registry protocol exposed to vfsd through DevmgrdIpcRequest/DevmgrdIpcResponse with DEVMGRD_IPC_OP_LOOKUP and DEVMGRD_IPC_OP_READDIR. vfsd may mirror explicit nodes (console0, display0, input0, input/event0, dri/card0) only as a pre-devmgrd bootstrap fallback; do not reintroduce a wildcard /dev/* success path.
  • syscalld keeps the service-side Linux policy DB for per-process credentials and RLIMIT_STACK. Linux-visible get*id, set*id, and prlimit64 policy must be sourced from syscalld; kernel process credentials are a gated bootstrap/security primitive and must not be mutated by Linux set*id.
  • device::DisplayInfo.flags distinguishes boot firmware framebuffers from a real primary display provider. Userspace display surfaces must require DISPLAY_INFO_FLAG_PRIMARY_PROVIDER; GRUB/firmware boot framebuffers are for early console and panic output by default. The bootfb driver is the only last-resort exception; if it exposes a firmware framebuffer as a primary provider, it must stay behind hardware/virtio providers and preserve DISPLAY_INFO_FLAG_BOOT_FRAMEBUFFER.
  • Driver framebuffer registration also carries explicit source flags in drivers/libs/driver-abi::DisplayFramebufferRegistration; do not infer primary display ownership from framebuffer geometry or from display_info() being present.
  • Display surface present is a kernel fast path: it copies validated shared surface contents into the active framebuffer and queues virtio-gpu flush work for the bounded housekeeping lower half. Do not reintroduce synchronous virtio-gpu command waits into app syscall context for normal uiserver presents.
  • Native virtio-gpu scanout backing is DMA memory and must be mapped write-combining on the CPU side. Present latency regressions often show up as slow present_ms in uiserver, so check the cache mode before changing UI drawing code. The direct-map cache flag is level-specific: 2 MiB PDEs use PAT bit 12, but split 4 KiB PTEs must use the PTE PAT selector bit instead of carrying bit 12 into the physical address field.
  • uiserver partial dirty rects should stay split unless the merged union is nearly as small as the separate areas. Over-coalescing disjoint topbar, taskbar, and window updates turns small changes into large framebuffer copies and delays input feedback.
  • User task weights are scheduler budgets in microseconds, not priorities. The default runtime budget is 100 us; do not stage services/apps with 50 us defaults unless a benchmark proves the interrupt/context-switch cost is acceptable. Input/display responsiveness should come from bounded lower-half work and explicit service readiness, not from 20 kHz user-task quanta.
  • CPU-bound display owners may have explicit larger budgets: uiserver gets a longer render/present slice so large framebuffer copies are not preempted every 100 us, and runtimed must pass manifest weight_micros through loaderd instead of replacing it with the default. Do not raise early broker/driver service budgets without a boot-time probe, because startup concurrency can regress perceived boot time.
  • Scheduler changes must follow Linux scheduler invariants rather than ad hoc interactivity heuristics. Timer interrupts that hit a user task while it is executing a kernel frame should set a deferred reschedule request, and long lock-free kernel paths must call the RustOS cond_resched equivalent at safe points. Do not preempt arbitrary kernel frames from the interrupt handler unless the path has explicit preemption-count/lock-state safety.
  • Ring0 Linux .ko module init runs inside the calling user service's kernel frame. Linux compat exports such as schedule, schedule_timeout, cond_resched/_cond_resched/__cond_resched, and long callback bridges (driver_register/HID bind/probe/open/report parse, USB register/URB/control callbacks, virtio probe loops, and similar lock-free callback chains) must provide explicit RustOS cond_resched safe points so driverd module init cannot starve uiserver, wayclick, or other ready user tasks until module init returns.
  • The default RustOS fair scheduler should stay Linux CFS-like: fixed periodic scheduler tick, per-task nanosecond vruntime accounting, weighted CPU share, smallest-vruntime pick, bounded sleeper credit, and an idle/root class that is excluded from fair competition once bootstrap finalize has ended. Per-task weights must not reprogram the hardware timer; weights affect vruntime only.
  • Borrow seL4/Windows scheduler rules only for the roles they prove well: seL4-style IPC handoff may donate a bounded next-pick vruntime credit to the receiver/replier, and Windows-style time-critical priority must be brief and mostly blocked. Do not turn these into broad permanent real-time boosts for normal services or apps.
  • Kernel code must not hold KernelSpinLock across disk, filesystem, IPC, or framebuffer-sized copy loops. Use KernelWaitLock or split the critical section, then add safe cond_resched points in long loops. This mirrors the Linux rule that spinlocked/atomic regions are not sleeping preemption points.
  • Init-time user services are ordered for perceived boot readiness: driver and input policy services should start before runtime UI launchers. runtimed depends on netd for its runtime control socket and waits for the devmgrd endpoint before UI bootstrap because display ioctl policy routes there. After runtimed is launched, defer secondary storage policy briefly so it does not contend with display bring-up.

Kernel API:

  • Prefer kernel/*/src/api.rs public wrappers over private subsystem modules.
  • Main API surfaces:
    • kernel/hal/src/api.rs
    • kernel/mm/src/api.rs
    • kernel/object/src/api.rs
    • kernel/ipc-runtime/src/api.rs
    • kernel/ps/src/api.rs
    • kernel/io-manager/src/api.rs
    • kernel/compat/src/api.rs
  • Kernel entry boot ordering lives in kernel/src/main.rs.
  • Human reference: docs/api/kernel.md.
  • Boot order: disable interrupts -> boot trace init -> GDT -> IDT -> paging -> higher-half jump -> stack switch -> executive bootstrap.
  • Cross-crate rule: import kernel_x::api as x_api; do not reach into another crate's private modules when api.rs exposes a wrapper.
  • User-memory IO APIs belong in syscall/process-context-aware paths only.
  • Scheduler-aware wait users should use kernel_ps::api::{current_task_id, block_current_task, wake_task}. The current_user_id, block_current_user_task, and wake_user_task wrappers remain userspace-task helpers, not general kernel wait primitives.

Kernel build:

  • Kernel-target Cargo invocations route through tools/xtask/src/build/cargo.rs::kernel_rustflags_env.
  • RustOS operational config lives in config/rustos.toml.
  • Kernel build-shape defaults live under [kernel.build]; set KERNEL_BUILD_CONFIG to test an alternate TOML file.
  • Default kernel RUSTFLAGS: --cfg rustos_boot_image, -C no-redzone, -C codegen-units=1, -C opt-level=2, -C overflow-checks=true, -C debug-assertions=false, -C debuginfo=0, -C panic=abort.
  • RUSTOS_KERNEL_CODEGEN_UNITS overrides the kernel codegen unit count for experiments without changing userspace builds. KERNEL_CODEGEN_UNITS remains a deprecated alias. The supported sweep range is 1..=256.
  • Kernel build-shape knobs also include lto, force_frame_pointers, incremental, debuginfo, embed_bitcode, panic, relocation_model, strip, and extra_rustflags. incremental is applied as CARGO_INCREMENTAL on kernel Cargo invocations.
  • Kernel Cargo invocations disable a configured sccache rustc wrapper because kernel build-std/LTO flag probes are not accepted by sccache.
  • embed_bitcode=true is required whenever lto is thin or fat.
  • cargo xtask config check validates effective config; cargo xtask config show prints the effective kernel build config.
  • Driver module loading must be stable across the supported codegen_units=1..=256 and opt_level=0..=3 sweep. Loader policy may ignore relocation sections that target non-loaded or non-ALLOC debug sections, but loaded text/data relocations must still resolve through explicit ABI surfaces.
  • Linux compat load failures should write the first disallowed or unresolved external symbol to debugcon directly. Do not rely only on category-filtered logs for module ABI diagnostics.

Fault injection:

  • Human guide: docs/fault-injection.md.
  • Shared parser crate: libs/rustos-fault-injection.
  • Host config parser: tools/xtask/src/config/project.rs [fault_injection].
  • QEMU handoff: tools/xtask/src/qemu/mod.rs passes rules through fw_cfg opt/rustos/fault-injection.
  • Kernel runtime: kernel/nucleus-core/src/util/fault_injection.rs.
  • Kernel init: kernel/executive/src/boot.rs calls fault_injection::init_from_qemu_fw_cfg() after heap init.
  • Rule format: location=action.
  • Valid actions: off, fail, drop-every:N, fail-after:N, rate:N, delay-ms:N. delay-ms is parsed but not wired to sleep/delay yet.
  • Current fault points: alloc.frame, block.read, block.write, display.present, display.provider.register, driver.module.load, input.event.enqueue, pci.config.read, process.spawn, socket.recv, socket.send, virtio-gpu.control.submit.
  • Add new points only at realistic failure boundaries such as allocation, block IO, device registration, queue submit, process spawn, IPC/socket send/recv, and driver probe/load. Do not scatter fault checks through arbitrary helper functions.
  • config/rustos.toml may use normal TOML formatting for fault rules, including multiline arrays; logging extraction must ignore non-logging sections.

Linux network and driver compat:

  • During the service-first evacuation, network namespace and socket policy live in netd, module/provider policy lives in driverd, and the kernel kernel/io-manager/src/driver/mod.rs surface is limited to privileged DMA, IRQ, IOMMU, and MMIO primitives plus explicit module-load substrate hooks.
  • driverd selects autoload/provider policy from staged registries and calls the gated driver broker. The kernel broker owns only the privileged module loader and driver ABI substrate: validating .ko images, relocating them, exposing DriverKernelApiV1, mapping MMIO, and executing module init in the kernel address space when the module ABI requires it. Do not move Linux .ko execution to ring3 as a generic goal; ring3 work should remove surrounding policy, namespace, queue, and provider decisions from the kernel while leaving commercial-driver ABI execution in ring0.
  • Deleted io-manager VFS/network/USB/input/provider policy files are not source of truth. Do not restore them to make .ko loading or Linux socket behavior appear to work; add service-owned policy and narrow privileged brokers.
  • Linux compat symbols must be explicitly implemented. Do not add broad prefix-based 0, NULL, or no-op fallbacks to make a module load; unresolved required externals should fail module load.
  • Optional Linux net features such as XDP, BPF, AF_XDP, failover, ethtool offloads, DIM, and trace/static-call hooks may be represented by explicit per-symbol disabled/no-op shims only when RustOS does not advertise that capability. These shims must fail closed or return disabled state; they must not fabricate packets, carrier, queue progress, or successful offload.

Logging:

  • Policy file: config/rustos.toml [logging].
  • Parser/cfg emitter: tools/build_log_cfg.rs.
  • Canonical categories: libs/rustos-observability/src/lib.rs.
  • Config is mostly build-time cfg; rebuild after changes.
  • Kernel macros: crate::debug::{trace,debug,info,warn,error}.
  • Userspace macros: observability_client::{trace,debug,info,warn,error}.

Docs:

  • Human docs are bilingual; English first.
  • Human docs must have language jump links.
  • AI docs are English-only and compact.
  • mdBook nav source: docs/SUMMARY.md.
  • mdBook config: book.toml; output under build/mdbook.
  • Mandatory token policy: docs/ai/token-policy.md.

Token-saving context rules:

  • Mandatory policy first; see docs/ai/token-policy.md.
  • Task classification second; see docs/ai/task-router.md.
  • Prefer source files named in contracts over human docs.
  • For broad docs updates, inspect docs/SUMMARY.md and the specific target doc only.
  • For code changes, inspect docs only if behavior touches a documented contract.
  • If behavior changes a stable contract, update the relevant AI doc in the same change.

AI Kernel API Map

Use this before docs/api/kernel.md.

Rule: cross-crate kernel calls should go through kernel_*::api.

NeedImportRead
GDT/IDT/ACPI/PIC/RTC/SIMD/hookskernel_hal::api as hal_apikernel/hal/src/api.rs
Heap/paging/frames/higher-halfkernel_mm::api as mm_apikernel/mm/src/api.rs
Handles/rights/session idskernel_object::api as object_apikernel/object/src/api.rs
Shared memory regionskernel_ipc_runtime::api as ipc_apikernel/ipc-runtime/src/api.rs
Scheduler/process/user statekernel_ps::api as ps_apikernel/ps/src/api.rs
VFS/devices/console/drivers/input/USBkernel_io_manager::api as io_apikernel/io-manager/src/api.rs
Linux/Windows compat/syscallskernel_compat::api as compat_apikernel/compat/src/api.rs
Boot orchestration/hookskernel_executive::bootkernel/executive/src/boot.rs, kernel/executive/src/lib.rs
Logging/panic/boot tracenucleus_core::debugkernel/nucleus-core/src/debug/mod.rs

Boot order from kernel/src/main.rs:

  1. hal_api::disable_interrupts
  2. debug::boot_trace::init
  3. hal_api::init_gdt
  4. hal_api::init_idt
  5. mm_api::init_paging
  6. hal_api::enter_higher_half
  7. hal_api::call_with_stack
  8. boot::kernel_main_bootstrap

Do not reorder without reading kernel/src/main.rs and kernel/executive/src/boot.rs.

High-risk APIs:

  • unsafe boot transfer helpers: enter_higher_half, call_with_stack.
  • user-memory IO: read_to_current_user, read_to_user, ioctl_from_user.
  • process state mutation: with_current_user_process_state_mut, with_process_state_by_pid_mut.
  • scheduler wait primitives: use current_task_id, block_current_task, and wake_task for kernel-capable wait queues; use *_user_* wrappers only for userspace-task waits.
  • scheduler preemption: use cond_resched/reschedule_if_requested only at Linux-style safe points outside spinlocked or IRQ-off regions; timer IRQs should request reschedule for user-task kernel frames, not blindly switch away from arbitrary kernel code.
  • Linux .ko init preemption: module init executes as a user-service syscall kernel frame, so long lock-free Linux compat callbacks must call cond_resched at safe points. Do not hold RustOS spinlocks or IRQ-off sections across those calls.
  • scheduler fairness: keep the hardware timer tick fixed and route service weights into scheduler vruntime/load accounting only. Root slot 0 is a fair task during bootstrap finalize, then becomes the idle fallback after mark_root_idle().
  • VFS mount/unmount/open path helpers: require current process context.

Docs:

  • Human reference: docs/api/kernel.md.
  • AI contract: docs/ai/contracts.md.

AI Workflows

Before any workflow: read token-policy.md, then task-router.md.

Add service:

  1. Read docs/guides/add-service.md.
  2. Inspect similar service manifest under services/*/RUSTOS.package.toml.
  3. Add crate under services/<name>.
  4. Add workspace member.
  5. Add manifest with kind = "service", execution_domain = "user".
  6. Run cargo xtask check.
  7. Update docs only if manifest/runtime behavior changes.

Add app:

  1. Read docs/guides/add-app.md.
  2. Inspect apps/wayclick/RUSTOS.package.toml or apps/shell/RUSTOS.package.toml.
  3. Choose Rust/C/Windows app path.
  4. Add manifest and desktop entry.
  5. Run cargo xtask check.
  6. Update docs only if launch policy or app workflow changes.

Add bridge driver:

  1. Read docs/guides/add-driver.md.
  2. Inspect drivers/bridges/display/bootfb/RUSTOS.package.toml.
  3. Add source under drivers/bridges/<class>/<name>.
  4. Add manifest with kind = "bridge-driver".
  5. Add [autoload] only if policy-loaded.
  6. Run cargo xtask build-driver-modules.
  7. If autoload policy changes, inspect generated driver registry after stage.

Modify kernel API:

  1. Read docs/ai/task-router.md, docs/ai/contracts.md, and relevant kernel/*/src/api.rs.
  2. Preserve api.rs as the cross-crate boundary.
  3. Update docs/api/kernel.md only for public API surface or boot/order changes.
  4. Run focused cargo check where possible; otherwise cargo xtask check.

Modify logging:

  1. Read docs/logging.md and docs/ai/contracts.md.
  2. Update config/rustos.toml [logging].
  3. If adding category, update libs/rustos-observability/src/lib.rs, tools/build_log_cfg.rs, human logging docs, and AI contracts.
  4. Rebuild affected crates; prefer cargo xtask build for kernel logging.

Update docs:

  1. Human docs: bilingual, English first, language anchors.
  2. AI docs: English only, dense, no repeated bilingual prose.
  3. Update docs/SUMMARY.md for new human or AI pages.
  4. If behavior contracts changed, update docs/ai/contracts.md or the focused AI map.
  5. Run mdBook/link sanity checks.

Debug QEMU boot:

  1. Ensure cargo xtask build completed.
  2. Run cargo xtask run --debugcon stdio for immediate logs.
  3. Use cargo xtask debug for GDB attach.
  4. Inspect logs/debugcon.log, logs/qemu_interrupt.log if interrupt trace enabled.
  5. If display issue, run cargo xtask probe-display.

Debug GRUB display boot:

  1. Check tools/xtask/src/build.rs embedded GRUB config before changing QEMU flags.
  2. Keep GRUB video setup conservative: load_video, gfxmode=auto, gfxpayload=keep.
  3. Check kernel/nucleus-core/src/multiboot2_entry.S for the Multiboot2 framebuffer request tag.
  4. Confirm the kernel log prints a nonzero boot framebuffer addr.
  5. Confirm platform:bootfb can match from storage::boot_volume::boot_framebuffer_info(), not from an already-installed GUI backend.
  6. Confirm display-primary fallback decisions use active display state, not just a loaded module record.
  7. For QEMU virtio-gpu, confirm virtio-gpu native: display registered appears after virtio register driver.

Reduce context mid-task:

  1. Summarize findings into the current response before opening more files.
  2. Prefer one subsystem at a time.
  3. Close questions by pointing at source path + line/symbol, not by pasting long code.