RustOS Documentation
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, theRUSTOS.package.tomlmanifest, 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:
- Getting Started
- Execution Flow
- Microkernel Overview
- Userspace Services
- Userspace Compatibility
- UI Server & Wayland
- Structure Guide
- Kernel API
- xtask API
- Package Manifest API
- Logging Guide
- 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.tomlmanifest, runtime control. - Guides: service / app / driver를 추가하는 끝-끝 절차.
- Reference: 안정적인 path와 environment variable.
- AI Agent Reference:
docs/ai/아래의 짧은 machine-oriented context.
추천 읽기 순서:
- 시작하기
- 실행 흐름
- Microkernel Overview
- Userspace Services
- Userspace Compatibility
- UI Server & Wayland
- Structure Guide
- Kernel API
- xtask API
- Package Manifest API
- 로깅 가이드
- Fault Injection
Getting Started
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
| Command | Purpose |
|---|---|
cargo xtask run -- --no-reboot | Pass raw QEMU args after --. |
cargo xtask run --profile nvme | Boot using the NVMe QEMU profile. |
cargo xtask run --accel-profile kvm | Use KVM acceleration and host CPU profile. |
cargo xtask run --usb-input | Attach USB keyboard/tablet devices for HID testing. |
cargo xtask run --qemu-log int | Write QEMU interrupt trace to logs/qemu_interrupt.log. |
cargo xtask run --debugcon stdio | Route 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를 다시 실행하세요.
유용한 실행 모드
| Command | Purpose |
|---|---|
cargo xtask run -- --no-reboot | -- 뒤의 값을 raw QEMU arg로 전달합니다. |
cargo xtask run --profile nvme | NVMe QEMU profile로 부팅합니다. |
cargo xtask run --accel-profile kvm | KVM acceleration과 host CPU profile을 사용합니다. |
cargo xtask run --usb-input | HID test용 USB keyboard/tablet device를 붙입니다. |
cargo xtask run --qemu-log int | QEMU interrupt trace를 logs/qemu_interrupt.log에 기록합니다. |
cargo xtask run --debugcon stdio | debugcon을 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
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
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.komodule loader for bridge drivers.kernel/compat: residual Windows PE/Win32 reference notes and a thin Linux ABI bridge that re-exports the canonical implementations fromkernel/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 bysyscalld.SYS_RUSTOS_PROC_PREPARE_BROKER/..._COMMIT_BROKER: process creation owned byloaderd.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 bydriverd.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 inkernel/ps/src/user/linux.rs(canonical) and is re-exported fromkernel/compat/src/user/linux.rs(do not edit the re-export).syscalldowns Linux MM policy and forwards through the gated MM broker. - Windows PE:
loaderdmaps 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 inkernel/compat, with deeper policy migration tracked as a follow-up. - Wayland:
uiserverruns 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.komodule을 위한 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
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.
| Service | Owns | Key surface |
|---|---|---|
rootd | Userspace privilege root. Brings up foundational service brokers and hands off to initd. | Direct spawn from kernel finalize. |
initd | Linux-style init. Starts runtimed, sets per-session env, and reaps strays. | /proc/1. |
runtimed | Service manager + launch broker. Bootstraps uiserver (synchronously with manifest env), then dispatches autostart and on-demand launches. | /run/runtimed.sock (RuntimeClient). |
sessiond | Session policy: focus, console session lifecycle, per-user resources. | Pairs with runtimed. |
syscalld | Linux MM/clock/signal policy. Calls into the gated SYS_RUSTOS_MM_BROKER. | IPC_SERVICE_SYSCALLD. |
vfsd | Linux VFS policy (mount table, openat resolution, FAT boot volume). | IPC_SERVICE_VFSD. |
loaderd | Process 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. |
devmgrd | Device manager / hotplug. Talks to driverd and consumers (inputd, storaged). | IPC_SERVICE_DEVMGRD. |
inputd | Input event routing from kernel HID/serio into Wayland and console clients. | Wayland seat + console focus. |
storaged | Block device policy and partition mapping over AHCI/NVMe. | Block API + driverd. |
netd | Network stack policy (virtio-net today, more to follow). | netprobe socket. |
procd | Process accounting, signal delivery, kernel ↔ runtime bridges for ps-style listings. | Pairs with runtimed. |
uiserver | Display 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) andhid-generic(generic HID input driver) for USB pointers and keyboards.virtio-gpuwhen present (otherwisebootfbis the active display provider).virtio-netfor 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 |
|---|---|---|
rootd | userspace privilege root. foundational broker를 띄우고 initd에 인계. | kernel finalize에서 직접 spawn. |
initd | Linux 스타일 init. runtimed를 띄우고 session 환경을 set, 좀비 회수. | /proc/1. |
runtimed | service manager + launch broker. manifest env를 적용한 채 uiserver를 동기 부트스트랩한 뒤, autostart와 on-demand launch를 dispatch. | /run/runtimed.sock (RuntimeClient). |
sessiond | session policy: focus, console session lifecycle, per-user resource. | runtimed와 쌍. |
syscalld | Linux MM/clock/signal policy. SYS_RUSTOS_MM_BROKER 호출. | IPC_SERVICE_SYSCALLD. |
vfsd | Linux VFS policy (mount table, openat resolution, FAT boot volume). | IPC_SERVICE_VFSD. |
loaderd | process 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. |
devmgrd | device manager / hotplug. driverd 및 consumer(inputd, storaged)와 통신. | IPC_SERVICE_DEVMGRD. |
inputd | kernel HID/serio에서 들어온 input event를 Wayland와 console client로 route. | Wayland seat + console focus. |
storaged | AHCI/NVMe 위 block device policy와 partition mapping. | Block API + driverd. |
netd | network stack policy (현재 virtio-net). | netprobe socket. |
procd | process accounting, signal 전달, ps-style listing용 kernel ↔ runtime bridge. | runtimed와 쌍. |
uiserver | display 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 안에서 일어납니다. driverd는
system/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
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.rsis a re-export shim — never edit it. - Adding new Linux syscall routing should happen in
syscalld,vfsd, or the appropriate userspace service, not inkernel/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 (
bootfbfor 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.rs의 BUILTIN_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
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:
- 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. - Console window surfaces are no longer "primed" during runtime polling;
draw_console_windowrebuilds the cached surface on the first draw, matching the same total work to the render budget instead of the runtime refresh budget. - The terminal cell loop in
terminal.rsskips redundant per-cell background fills when the bulk render has already paintedlayout.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.rsor the cursor colours incanvas.rsfor 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
동기 임계 경로는 의도적으로 짧습니다.
- 첫 present는 full chrome이 아니라 단색을 사용합니다. chrome 합성은 첫
idle frame으로 미뤄지므로, 사용자에게는
display_create_surface직후 몇 frame 안에 항상 pixel이 보입니다. - console window surface는 runtime polling 중에 "prime" 하지 않습니다.
draw_console_window가 첫 draw에서 cached surface를 rebuild하며, 동일한 총 작업량을 runtime refresh budget이 아닌 render budget으로 옮깁니다. 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.rs나canvas.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는 uiserver의
TerminalState 안에 있고 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
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 nucleuskernel/: kernel entry crate plus internal kernel subsystem cratesservices/: userspace system services such asinitd,runtimed, anduiserverapps/: demo, smoke, desktop, and compatibility test applicationscompat/: compatibility layer sources, including Windows userspace supportlibs/: general-purpose crates shared across product layerstests/: integration and module test cratestools/: host-side build, stage, run, and validation toolsassets/image/: static overlay copied directly into the staged boot imageassets/ui/: UI fonts and related UI assetsbuild/artifacts/: build artifact cachebuild/image/: staged boot volume rootlogs/: QEMU, debugcon, interrupt, and helper logsdrivers/bridges/: kernel-address-space bridge drivers and.komodulesdrivers/user/: userspace driver/service ELF packagesdrivers/libs/: driver ABI, runtime, and helper cratesvendor/: external binaries, firmware, prebuilt.kofiles, and OVMFconfig/: shared configuration such as logging policydocs/: 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, ordrivers/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/ordrivers/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/orlogs/.
Layering Rules
kernel/srcis entry-only. Real kernel functionality is split acrosskernel/nucleus-core,kernel/lowlevel,kernel/hal,kernel/mm,kernel/object,kernel/ipc-runtime,kernel/ps,kernel/io-manager,kernel/compat, andkernel/executive.- RustOS is a hybrid kernel, not a pure microkernel. Policy and namespace
decisions should move to services such as
driverd,syscalld,vfsd, andloaderd, 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.komodule execution. - Kernel-internal crate dependencies must not flow from lower layers back into
higher layers.
cargo xtask checkvalidates these relationships. libs/may depend only on boot protocol crates and otherlibs/crates. It must not depend on implementation crates fromkernel/,services/,apps/, ordrivers/bridges/.drivers/libs/may depend onlibs/,drivers/libs/, and required boot protocol crates. It must not depend on bridge driver implementations.services/may depend onlibs/,compat/, anddrivers/libs/.apps/may depend onlibs/andcompat/.drivers/bridges/may depend on kernel ABI surfaces,libs/, anddrivers/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"]inRUSTOS.package.toml. runtime_depsvalues are packageidvalues, not install paths and not desktop file ids.cargo xtask checkvalidates 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 repositoryassets/image/: files copied into the staged imagebuild/: reproducible build and stage outputlogs/: run/debug output
Do not put generated artifacts, QEMU run output, or local debug captures in source directories.
Adding A New Module
- If it is a source-based first-party kernel bridge, add a crate under
drivers/bridges/.... - If it is a userspace driver or service, add it under
drivers/user/...orservices/.... - If shared driver API/helper code is needed, use
drivers/libs/.... - If it is deployable, add
RUSTOS.package.tomlat the package root and declarekind,execution_domain,startup, andinstall.path. - Run
cargo xtask checkto validate layering and package taxonomy. - Run
cargo xtask build, then inspect generated registries underbuild/image/system/registry/...if startup, desktop, or driver policy changed. - 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 cratekernel/: kernel entry crate와 내부 kernel subsystem crateservices/:initd,runtimed,uiserver같은 userspace system serviceapps/: demo, smoke, desktop, compatibility test applicationcompat/: Windows userspace 지원을 포함한 호환 계층 소스libs/: 여러 제품 계층이 공유하는 일반-purpose cratetests/: integration/module test cratetools/: host-side build, stage, run, validation 도구assets/image/: staged boot image에 그대로 복사되는 정적 overlayassets/ui/: UI font와 관련 UI assetbuild/artifacts/: build artifact cachebuild/image/: staged boot volume rootlogs/: QEMU, debugcon, interrupt, helper logdrivers/bridges/: kernel address space에 남는 bridge driver와.komoduledrivers/user/: userspace driver/service ELF packagedrivers/libs/: driver ABI, runtime, helper cratevendor/: 외부 바이너리, firmware, prebuilt.ko, OVMFconfig/: 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.komodule 실행이 포함됩니다. - 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.toml에runtime_deps = ["package-id"]를 선언합니다. runtime_deps값은 install path나 desktop file id가 아니라 packageid입니다.cargo xtask check는 선택된 profile 기준으로 dependency 존재 여부, 같은 profile 포함 여부, 자기 자신 의존, 순환 의존을 검사합니다.- stage는 startup/runtime registry에
deps=metadata를 기록합니다. launcher 실행 순서 강제는 별도 단계에서 처리합니다.
Vendor, Assets, Build 구분
vendor/: 저장소가 보관하는 외부 source inputassets/image/: staged image에 복사되는 파일build/: 재생성 가능한 build/stage outputlogs/: run/debug output
생성 artifact, QEMU 실행 output, local debug capture를 source directory에 두지 마세요.
새 모듈 추가 절차
- source 기반 first-party kernel bridge라면
drivers/bridges/...에 crate를 추가합니다. - userspace driver 또는 service라면
drivers/user/...또는services/...아래에 추가합니다. - 공용 driver API/helper code가 필요하면
drivers/libs/...를 사용합니다. - deployable 단위라면 package root에
RUSTOS.package.toml을 추가하고kind,execution_domain,startup,install.path를 선언합니다. cargo xtask check로 layering과 package taxonomy를 검증합니다.cargo xtask build를 실행한 뒤 startup, desktop, driver 정책이 바뀌었다면build/image/system/registry/...아래 generated registry를 확인합니다.- 경로 규칙이나 ownership boundary가 바뀌면 이 문서와 문서 홈을 같이 갱신합니다.
Logging Guide
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 isfalse, the category log cfgs are not emitted.boot_trace_enabled: emitsrustos_boot_trace_enabledfor early boot trace paths. This is intentionally separate fromenabled.serial_mirror: mirrors kernel structured log lines to QEMU debugcon port0xe9in 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 sequencingpanic: panic and fatal crash reportingmemory: physical memory, paging, heap, VMsched: scheduler and task switchingsyscall: Linux/compat syscall entry and exit pathsprocess: process and thread lifecycledriver: driver loading and driver runtimestorage: block devices, boot volume, filesystem pathsusb: USB host/controller/device workinput: keyboard, pointer, HID inputdisplay: framebuffer, DRM, GPU, presentation pathsvfs: VFS lookup/open/read/write pathsconsole: console host and terminal sessionsservice: userspace system servicescompat: Linux/Windows compatibility layerdebug: breadcrumbs, diagnostics, internal debug helpersheartbeat: low-volume liveness markers
Build-Time Behavior
The logging config is compiled into cfg flags such as:
rustos_debug_print_enabledrustos_boot_trace_enabledrustos_log_storage_debugrustos_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!andcrate::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_enabledin 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 forcargo xtask runlogs/qemu_interrupt.log: QEMU interrupt trace when--qemu-log intis usedlogs/rustos-debug.gdb: helper generated bycargo 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.
Recommended Profiles
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:
libs/rustos-observability/src/lib.rstools/build_log_cfg.rsconfig/rustos.toml- 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
debugortracefor loops, interrupts, syscalls, scheduler ticks, or packet/block paths. - Use
infofor lifecycle events: service start, device ready, mount complete, UI ready. - Use
warnfor recoverable failures or degraded fallback. - Use
errorfor failed operations that likely break a user-visible path. - Use
fatalonly 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.rs가 tools/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 port0xe9에도 미러링합니다.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 sequencingpanic: panic과 fatal crash reportingmemory: physical memory, paging, heap, VMsched: scheduler와 task switchingsyscall: Linux/compat syscall entry/exit pathprocess: process/thread lifecycledriver: driver loading과 driver runtimestorage: block device, boot volume, filesystem pathusb: USB host/controller/device 작업input: keyboard, pointer, HID inputdisplay: framebuffer, DRM, GPU, presentation pathvfs: VFS lookup/open/read/write pathconsole: console host와 terminal sessionservice: userspace system servicecompat: Linux/Windows compatibility layerdebug: breadcrumb, diagnostic, internal debug helperheartbeat: low-volume liveness marker
빌드 타임 동작
logging config는 다음과 같은 cfg flag로 컴파일됩니다.
rustos_debug_print_enabledrustos_boot_trace_enabledrustos_log_storage_debugrustos_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 outputlogs/qemu_interrupt.log:--qemu-log int사용 시 QEMU interrupt tracelogs/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는 다음 위치에 모두 추가해야 합니다.
libs/rustos-observability/src/lib.rstools/build_log_cfg.rsconfig/rustos.toml- 이 가이드
그 뒤 실행합니다.
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
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:
- Rules live in
config/rustos.tomlunder[fault_injection]. cargo xtask run,debug, andprobe-displaypass the rules to QEMU through fw_cfg asopt/rustos/fault-injection.- The kernel reads that fw_cfg file during boot after the heap is initialized.
- Selected kernel boundaries call
should_fail("fault.point"). - 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:
| Action | Meaning |
|---|---|
off | Register the point but do not fail. Good default. |
fail | Fail every call. |
drop-every:N | Fail every Nth call. |
fail-after:N | Let N calls pass, then fail later calls. |
rate:N | Fail about N out of 1000 calls. |
delay-ms:N | Parsed 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
| Point | Simulated failure |
|---|---|
alloc.frame | Physical frame allocation returns None. |
block.read | Block device read returns DeviceFault. |
block.write | Block device write returns DeviceFault. |
display.present | Display present is dropped. |
display.provider.register | Driver framebuffer provider registration fails. |
driver.module.load | Loadable driver module load fails. |
input.event.enqueue | Pointer/input event is dropped before enqueue. |
pci.config.read | Linux compat PCI config read returns an I/O-style error. |
process.spawn | User process spawn fails as if no task slot was available. |
socket.recv | Socket receive returns a retryable error. |
socket.send | Socket send returns a retryable error. |
virtio-gpu.control.submit | VirtIO 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의 중요한 경계가 일부러 실패한 것처럼 만드는 하드닝 장치입니다. 목적은 무작위로 망가뜨리는 것이 아니라, 실제 장애가 났을 때 복구 경로가 제대로 동작하는지 보는 것입니다.
현재 흐름은 이렇습니다.
- 규칙은
config/rustos.toml의[fault_injection]에 둡니다. cargo xtask run,debug,probe-display가 규칙을 QEMU fw_cfg의opt/rustos/fault-injection으로 넘깁니다.- 커널은 heap 초기화 직후 부팅 중 fw_cfg 파일을 읽습니다.
- 선택된 커널 경계가
should_fail("fault.point")를 호출합니다. - 규칙이 발동하면 실제 device, storage, allocation, IPC 문제가 난 것처럼 해당 경계가 실패를 반환합니다.
설정
[fault_injection]
enabled = true
rules = ["display.present=off"]
규칙 형식:
fault.point=action
지원 action:
| Action | 의미 |
|---|---|
off | 지점은 등록하지만 실패시키지 않음. 기본값으로 적합합니다. |
fail | 매번 실패 |
drop-every:N | N번째 호출마다 실패 |
fail-after:N | N번은 통과시키고 이후 호출 실패 |
rate:N | 1000번 중 대략 N번 실패 |
delay-ms:N | 현재는 파싱만 됩니다. 실제 delay 주입은 아직 연결되지 않았습니다. |
현재는 rules = [...] 배열을 한 줄에 유지하세요. 기존 logging cfg generator가
config/rustos.toml 전체를 같이 스캔하기 때문에, 독립된 줄의 multiline 배열
닫는 대괄호를 아직 받아들이지 못합니다.
Fault Point
| Point | 흉내 내는 실패 |
|---|---|
alloc.frame | 물리 frame allocation이 None 반환 |
block.read | block device read가 DeviceFault 반환 |
block.write | block device write가 DeviceFault 반환 |
display.present | display present drop |
display.provider.register | driver framebuffer provider 등록 실패 |
driver.module.load | loadable driver module load 실패 |
input.event.enqueue | pointer/input event enqueue 전 drop |
pci.config.read | Linux compat PCI config read가 I/O성 오류 반환 |
process.spawn | task slot 부족처럼 user process spawn 실패 |
socket.recv | socket receive가 retry 가능한 오류 반환 |
socket.send | socket send가 retry 가능한 오류 반환 |
virtio-gpu.control.submit | VirtIO 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
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
| Crate | API module | Purpose |
|---|---|---|
kernel-hal | kernel/hal/src/api.rs | GDT/IDT/ACPI/PIC/RTC/SIMD setup, interrupt hooks, CPU helpers. |
kernel-mm | kernel/mm/src/api.rs | heap, paging, physical frames, higher-half address helpers. |
kernel-object | kernel/object/src/api.rs | typed object/handle/session rights shared by kernel subsystems. |
kernel-ipc-runtime | kernel/ipc-runtime/src/api.rs | kernel shared region creation, mapping, frame export. |
kernel-ps | kernel/ps/src/api.rs | scheduler, process/thread state, user task lifecycle, waits, snapshots. |
kernel-io-manager | kernel/io-manager/src/api.rs | block, boot volume, console, device, tty, input, USB, VFS, drivers. |
kernel-compat | kernel/compat/src/api.rs | Linux/Windows compatibility syscall and console host API. |
kernel-executive | kernel/executive/src/lib.rs | boot orchestration and cross-subsystem hook registration. |
nucleus-core | kernel/nucleus-core/src/debug/mod.rs | structured 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.
| Group | Key APIs | Notes |
|---|---|---|
boot | init_gdt, init_idt, init_acpi, enter_higher_half, call_with_stack | Boot-only setup and unsafe control transfer helpers. |
cpu | init_simd, simd_mode_name, current_rip | CPU feature/runtime helpers. |
interrupts | disable_interrupts, init_pic, register_task_hooks, register_interrupt_hooks, register_heartbeat_hooks | Hook registration connects HAL IRQ paths to scheduler/IO/heartbeat behavior. |
time | init_rtc | RTC initialization and dispatch registration. |
Memory API
Use kernel_mm::api for allocator, paging, physical memory, and virtual address
helpers.
| Group | Key APIs | Notes |
|---|---|---|
alloc | KernelAllocator, init_heap, handle_alloc_error | Kernel global allocator support. |
boot | init_paging, init_phys, paging_smoke_test | Early memory bootstrap. |
phys | usable_bytes, free_bytes, alloc_frame, free_frame | Physical frame accounting/allocation. |
address_space | ProcessAddressSpace, PageTableFlags, debug_direct_map_flags_for_addr | Process address space and debug helpers. |
virt | higher_half_addr, kernel_virt_offset | Higher-half address conversion. |
Process/Scheduler API
Use kernel_ps::api for task scheduling and user process state.
| Group | Key APIs | Notes |
|---|---|---|
boot | init, is_initialized, service_deferred_work | Scheduler lifecycle and deferred work. |
fault | retire_current_user_task_due_to_fault, halt_current_retired_task | User fault disposition. |
process | spawn_user_process, spawn_kernel_process | Process creation. |
snapshot | current_user_snapshot, current_user_process_id, retain_current_user_process_state, with_current_user_process_state_mut | Current/process state access. |
task | yield_now, interrupt handler addresses, console session setters, runtime hooks | Scheduling and interrupt integration. |
wait | wait_for_child | Wait/child status handling. |
IO Manager API
Use kernel_io_manager::api for devices, boot volume state, VFS, console, and
driver integration.
| Group | Key APIs | Notes |
|---|---|---|
boot | init_gui, init_boot_info, boot_volume_identity, enter_kernel_vfs_runtime, enter_userspace_runtime | Boot volume and runtime phase transitions. |
block | register_boot_volume_opener, init_block_devices, block_descriptors, lookup_block | Block device registration and lookup. |
console | init_console, init_tty, write_console, service_console | Kernel console and TTY service. |
device | open, read_to_current_user, read_to_user, ioctl_from_user | /dev-style device access from kernel/syscall paths. |
tty | session input/output and termios helpers | Console session IO. |
driver | initialize_loadable_modules_for_class, Linux runtime hooks | Driver load/service integration. |
input | init_input, interrupt handlers, service pending counters | Keyboard/mouse/HID input. |
usb | init_usb, debug counters | USB host path. |
vfs | init_vfs, normalize_kernel_path, mount/open/metadata/access/readlink helpers | Current-process VFS operations. |
Object And IPC APIs
| Crate | Key APIs | Notes |
|---|---|---|
kernel_object::api | DeviceHandle, DeviceId, HandleToken, rights types, ConsoleSessionHandle | Shared object and handle vocabulary. |
kernel_ipc_runtime::api | create_shared_region, map_shared_region, shared_region_frames | Kernel shared memory region lifecycle. |
Compatibility API
Use kernel_compat::api for Linux/Windows compatibility surfaces.
| Group | Key APIs | Notes |
|---|---|---|
linux | Linux process/syscall state re-exports and offset helpers | Linux ABI support. |
windows | Windows compatibility re-exports | Windows userland compatibility. |
console_host | console host helpers | Console-hosted user programs. |
syscall | init_syscalls, service_pending, GS-base helpers | Syscall 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.rswrapper exists. - Boot APIs often have ordering assumptions; follow the call order in
kernel/src/main.rsandkernel/executive. - APIs that copy to/from user memory must be called only from syscall or process-context-aware paths.
- Use
crate::debugornucleus_core::debugfor 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
| Crate | API module | Purpose |
|---|---|---|
kernel-hal | kernel/hal/src/api.rs | GDT/IDT/ACPI/PIC/RTC/SIMD setup, interrupt hook, CPU helper |
kernel-mm | kernel/mm/src/api.rs | heap, paging, physical frame, higher-half address helper |
kernel-object | kernel/object/src/api.rs | kernel subsystem이 공유하는 typed object/handle/session rights |
kernel-ipc-runtime | kernel/ipc-runtime/src/api.rs | kernel shared region 생성, mapping, frame export |
kernel-ps | kernel/ps/src/api.rs | scheduler, process/thread state, user task lifecycle, wait, snapshot |
kernel-io-manager | kernel/io-manager/src/api.rs | block, boot volume, console, device, tty, input, USB, VFS, driver |
kernel-compat | kernel/compat/src/api.rs | Linux/Windows compatibility syscall과 console host API |
kernel-executive | kernel/executive/src/lib.rs | boot orchestration과 cross-subsystem hook registration |
nucleus-core | kernel/nucleus-core/src/debug/mod.rs | structured 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를 사용합니다.
| Group | Key APIs | Notes |
|---|---|---|
boot | init_gdt, init_idt, init_acpi, enter_higher_half, call_with_stack | boot-only setup과 unsafe control transfer helper |
cpu | init_simd, simd_mode_name, current_rip | CPU feature/runtime helper |
interrupts | disable_interrupts, init_pic, register_task_hooks, register_interrupt_hooks, register_heartbeat_hooks | HAL IRQ path를 scheduler/IO/heartbeat 동작에 연결 |
time | init_rtc | RTC initialization과 dispatch registration |
Memory API
allocator, paging, physical memory, virtual address helper는 kernel_mm::api를
사용합니다.
| Group | Key APIs | Notes |
|---|---|---|
alloc | KernelAllocator, init_heap, handle_alloc_error | kernel global allocator support |
boot | init_paging, init_phys, paging_smoke_test | early memory bootstrap |
phys | usable_bytes, free_bytes, alloc_frame, free_frame | physical frame accounting/allocation |
address_space | ProcessAddressSpace, PageTableFlags, debug_direct_map_flags_for_addr | process address space와 debug helper |
virt | higher_half_addr, kernel_virt_offset | higher-half address conversion |
Process/Scheduler API
task scheduling과 user process state는 kernel_ps::api를 사용합니다.
| Group | Key APIs | Notes |
|---|---|---|
boot | init, is_initialized, service_deferred_work | scheduler lifecycle과 deferred work |
fault | retire_current_user_task_due_to_fault, halt_current_retired_task | user fault disposition |
process | spawn_user_process, spawn_kernel_process | process creation |
snapshot | current_user_snapshot, current_user_process_id, retain_current_user_process_state, with_current_user_process_state_mut | current/process state access |
task | yield_now, interrupt handler addresses, console session setters, runtime hooks | scheduling과 interrupt integration |
wait | wait_for_child | wait/child status handling |
IO Manager API
device, boot volume state, VFS, console, driver integration은
kernel_io_manager::api를 사용합니다.
| Group | Key APIs | Notes |
|---|---|---|
boot | init_gui, init_boot_info, boot_volume_identity, enter_kernel_vfs_runtime, enter_userspace_runtime | boot volume과 runtime phase transition |
block | register_boot_volume_opener, init_block_devices, block_descriptors, lookup_block | block device registration과 lookup |
console | init_console, init_tty, write_console, service_console | kernel console과 TTY service |
device | open, read_to_current_user, read_to_user, ioctl_from_user | kernel/syscall path의 /dev style device access |
tty | session input/output and termios helpers | console session IO |
driver | initialize_loadable_modules_for_class, Linux runtime hooks | driver load/service integration |
input | init_input, interrupt handlers, service pending counters | keyboard/mouse/HID input |
usb | init_usb, debug counters | USB host path |
vfs | init_vfs, normalize_kernel_path, mount/open/metadata/access/readlink helpers | current-process VFS operation |
Object And IPC APIs
| Crate | Key APIs | Notes |
|---|---|---|
kernel_object::api | DeviceHandle, DeviceId, HandleToken, rights types, ConsoleSessionHandle | shared object/handle vocabulary |
kernel_ipc_runtime::api | create_shared_region, map_shared_region, shared_region_frames | kernel shared memory region lifecycle |
Compatibility API
Linux/Windows compatibility surface는 kernel_compat::api를 사용합니다.
| Group | Key APIs | Notes |
|---|---|---|
linux | Linux process/syscall state re-exports and offset helpers | Linux ABI support |
windows | Windows compatibility re-exports | Windows userland compatibility |
console_host | console host helpers | console-hosted user program |
syscall | init_syscalls, service_pending, GS-base helpers | syscall과 compat runtime service path |
Usage Rules
use kernel_mm::api as mm_api처럼 API module을 alias해서 import하세요.api.rswrapper가 있으면 다른 kernel crate에서 private subsystem module을 직접 호출하지 마세요.- boot API는 ordering assumption이 강합니다.
kernel/src/main.rs와kernel/executive의 call order를 따르세요. - user memory로 copy하는 API는 syscall 또는 process-context-aware path에서만 호출해야 합니다.
- kernel log는
crate::debug또는nucleus_core::debug를 사용하세요. 자세한 내용은 로깅 가이드를 참고하세요.
xtask API
English
cargo xtask is the host-side control surface for RustOS. The command enum is
defined in tools/xtask/src/cli.rs.
Commands
| Command | Purpose | Main output |
|---|---|---|
cargo xtask check | Validate layering, package manifests, targets, and workspace checks. | No image output. |
cargo xtask build | Full OS build and stage. | build/artifacts, build/image, registries. |
cargo xtask stage | Copy built artifacts and overlays into the boot image. | build/image. |
cargo xtask run | Run current staged image in QEMU. | QEMU session, logs/debugcon.log. |
cargo xtask debug | Run QEMU with GDB stub. | logs/rustos-debug.gdb. |
cargo xtask probe-display | Headless display probe/stress path. | Probe result and debug logs. |
cargo xtask qemu-scenarios | Run named QEMU regression scenarios. | QEMU logs and scenario result. |
cargo xtask selftest | Run host selftests for contracts and hardening helpers. | Cargo test output. |
cargo xtask fuzz-host | Run deterministic host parser fuzz smoke tests. | logs/fuzz-crash-*.bin on crash. |
cargo xtask clean | Remove cargo/build outputs. | Cleaned target/build dirs. |
cargo xtask targets | Install required Rust targets. | Rust target availability. |
cargo xtask build-efi | Build 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-kernel | Build Multiboot2 nucleus/kernel only. | build/artifacts/nucleus.elf. |
cargo xtask build-user | Build userspace packages. | service/app artifacts. |
cargo xtask build-console-demo | Build C demo/smoke programs. | app artifacts. |
cargo xtask build-driver-modules | Build bridge driver modules. | .ko artifacts. |
QEMU Options
cargo xtask run, debug, and probe-display accept shared options:
| Option | Meaning |
|---|---|
| `--profile <default | g14 |
--accel-profile kvm | Use KVM acceleration and host CPU profile. |
--usb-input | Attach qemu-xhci, usb-kbd, and usb-tablet. |
--no-network | Disable default usernet and virtio-net-pci. |
| `--debugcon <file | stdio |
| `--qemu-log <int | null>` |
--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-log | Print high-signal debugcon markers after QEMU stops. |
--vfio-pci <BDF> | Attach a host vfio-pci device. |
--phoenix3-passthrough | Auto-detect and attach Phoenix3 GPU functions. |
--vfio-force | Allow 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
checkbefore commits that change dependencies, manifests, or layer boundaries. It also validates an existingbuild/artifacts/nucleus.elfwithgrub-file --is-x86-multiboot2when present. - Use
buildafter changing code or staged image content. The default build requires GRUB public/signing key environment variables. - Use
stageafter changing onlyassets/imageor package install metadata when artifacts are already built. - Use
runfor normal boot testing. - Use
debugwhen attaching GDB. - Use
probe-displayfor display, framebuffer, surface, or dirty-rect bugs.
한국어
cargo xtask는 RustOS의 host-side control surface입니다. command enum은
tools/xtask/src/cli.rs에 정의되어 있습니다.
Commands
| Command | Purpose | Main output |
|---|---|---|
cargo xtask check | layering, package manifest, target, workspace check를 검증합니다. | image output 없음 |
cargo xtask build | 전체 OS build와 stage를 수행합니다. | build/artifacts, build/image, registries |
cargo xtask stage | built artifact와 overlay를 boot image에 복사합니다. | build/image |
cargo xtask run | 현재 staged image를 QEMU에서 실행합니다. | QEMU session, logs/debugcon.log |
cargo xtask debug | GDB stub과 함께 QEMU를 실행합니다. | logs/rustos-debug.gdb |
cargo xtask probe-display | headless display probe/stress path를 실행합니다. | probe result와 debug logs |
cargo xtask qemu-scenarios | 이름이 있는 QEMU regression scenario를 실행합니다. | QEMU log와 scenario result |
cargo xtask selftest | contract와 hardening helper host selftest를 실행합니다. | Cargo test output |
cargo xtask fuzz-host | deterministic host parser fuzz smoke test를 실행합니다. | crash 시 logs/fuzz-crash-*.bin |
cargo xtask clean | cargo/build output을 지웁니다. | 정리된 target/build dirs |
cargo xtask targets | 필요한 Rust target을 설치합니다. | Rust target availability |
cargo xtask build-efi | GRUB EFI boot manager만 빌드합니다. RUSTOS_GRUB_* 값이 없으면 build/dev-grub-gpg 아래에 로컬 개발 키를 생성합니다. | build/artifacts/EFI/BOOT/BOOTX64.EFI, build/artifacts/nucleus.elf.sig |
cargo xtask build-kernel | Multiboot2 nucleus/kernel만 빌드합니다. | build/artifacts/nucleus.elf |
cargo xtask build-user | userspace package를 빌드합니다. | service/app artifacts |
cargo xtask build-console-demo | C demo/smoke program을 빌드합니다. | app artifacts |
cargo xtask build-driver-modules | bridge driver module을 빌드합니다. | .ko artifacts |
QEMU Options
cargo xtask run, debug, probe-display는 같은 option을 받습니다.
| Option | Meaning |
|---|---|
| `--profile <default | g14 |
--accel-profile kvm | KVM acceleration과 host CPU profile 사용 |
--usb-input | qemu-xhci, usb-kbd, usb-tablet attach |
--no-network | default usernet과 virtio-net-pci 비활성화 |
| `--debugcon <file | stdio |
| `--qemu-log <int | null>` |
--timeout <seconds> | 제한 시간 후 QEMU를 종료. 기본값은 timeout 없음 |
--expect <marker> | 반복 지정한 debugcon marker가 모두 나오면 성공으로 종료 |
--fault <location=action> | 이번 실행에만 validated fault-injection rule 추가 |
--summarize-log | QEMU 종료 후 high-signal debugcon marker 요약 출력 |
--vfio-pci <BDF> | host vfio-pci device attach |
--phoenix3-passthrough | Phoenix3 GPU function 자동 탐지/attach |
--vfio-force | active 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
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
| Field | Values | Meaning |
|---|---|---|
id | string | Stable package id used by runtime deps and registries. |
kind | boot, kernel, bridge-driver, user-driver, service, app, compat | Package taxonomy. |
execution_domain | kernel, user | Optional explicit execution domain. |
profiles | string list | Build/profile membership; defaults to ["default"]. |
startup | none, init, session, desktop | Startup policy for generated registries. |
runtime_deps | package id list | Runtime ordering/exposure dependency metadata. |
Build Section
builder | Purpose |
|---|---|
bootloader-uefi | Compatibility alias for GRUB EFI boot manager generation. |
kernel-rustc | Kernel/nucleus artifact build. |
cargo-kernel-binary | Rust userspace service/app ELF. |
mingw-c-exe | Windows PE executable demo. |
c-demo | Host C demo/smoke artifact. |
module-image | Kernel bridge .ko module image. |
winsys-dll-bundle | Windows system DLL bundle. |
external-copy | Copy externally provided artifact. |
Install Section
| Field | Meaning |
|---|---|
path | Relative path inside artifacts and staged image. |
layout | file or directory; defaults to file. |
Desktop Entries
[[desktop.entries]] generates desktop/runtime launch metadata.
| Field | Meaning |
|---|---|
display_name | UI/runtime display name. |
image | Optional staged image path override. |
exec | Optional executable path override. |
weight_micros | Scheduling/task weight metadata. |
logical_admin | Marks privileged/admin-style components. |
console_hosted | Whether runtime should host it through console. |
launch | none, new-session, or all-sessions. |
args | Command argv metadata. |
env | Environment 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
| Field | Values | Meaning |
|---|---|---|
id | string | runtime deps와 registry에서 쓰는 stable package id |
kind | boot, kernel, bridge-driver, user-driver, service, app, compat | package taxonomy |
execution_domain | kernel, user | optional explicit execution domain |
profiles | string list | build/profile membership, 기본값 ["default"] |
startup | none, init, session, desktop | generated registry startup policy |
runtime_deps | package id list | runtime ordering/exposure dependency metadata |
Build Section
builder | Purpose |
|---|---|
bootloader-uefi | GRUB EFI boot manager 생성용 compatibility alias |
kernel-rustc | kernel/nucleus artifact build |
cargo-kernel-binary | Rust userspace service/app ELF |
mingw-c-exe | Windows PE executable demo |
c-demo | host C demo/smoke artifact |
module-image | kernel bridge .ko module image |
winsys-dll-bundle | Windows system DLL bundle |
external-copy | externally provided artifact copy |
Install Section
| Field | Meaning |
|---|---|
path | artifact와 staged image 안의 relative path |
layout | file 또는 directory, 기본값 file |
Desktop Entries
[[desktop.entries]]는 desktop/runtime launch metadata를 생성합니다.
| Field | Meaning |
|---|---|
display_name | UI/runtime display name |
image | optional staged image path override |
exec | optional executable path override |
weight_micros | scheduling/task weight metadata |
logical_admin | privileged/admin-style component 표시 |
console_hosted | runtime이 console로 host할지 여부 |
launch | none, new-session, all-sessions |
args | command argv metadata |
env | environment 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
Runtime control is the userspace client API used to talk to runtimed. The
public API lives in libs/runtime-control/src/lib.rs.
Constants
| Constant | Value |
|---|---|
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)?; }
| Method | Purpose |
|---|---|
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
| Constant | Value |
|---|---|
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)?; }
| Method | Purpose |
|---|---|
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
Workflow
- Create the service crate under
services/<name>/. - Add the crate to the workspace in
Cargo.toml. - Add
services/<name>/RUSTOS.package.toml. - Choose
kind = "service"andexecution_domain = "user". - Choose
startup:initfor early system services.sessionfor session-owned services.desktopfor UI/desktop services.nonefor manually launched services.
- Use
[build] builder = "cargo-kernel-binary"for Rust userspace services. - Use
[install] path = "services/<name>/<name>.elf". - Add at least one
[[desktop.entries]]entry for registry generation. - Add
runtime_depsonly when the service requires another package first. - Run
cargo xtask check, thencargo 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 checkpasses.cargo xtask buildstages the service underbuild/image/services/<name>/.- Generated registries under
build/image/system/registry/include expected startup/desktop metadata. - Service logs use
observability_clientwith categoryservice.
한국어
Workflow
services/<name>/아래 service crate를 만듭니다.- root
Cargo.tomlworkspace에 crate를 추가합니다. services/<name>/RUSTOS.package.toml을 추가합니다.kind = "service",execution_domain = "user"를 선택합니다.startup을 선택합니다.- early system service는
init - session-owned service는
session - UI/desktop service는
desktop - 수동 실행 service는
none
- early system service는
- Rust userspace service는
[build] builder = "cargo-kernel-binary"를 사용합니다. [install] path = "services/<name>/<name>.elf"를 사용합니다.- registry 생성을 위해
[[desktop.entries]]를 최소 하나 추가합니다. - 다른 package가 먼저 필요할 때만
runtime_deps를 추가합니다. 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_client와servicecategory를 사용합니다.
Add an App
English
Workflow
- Choose app type:
- Rust app: create
apps/<name>/withCargo.toml. - C smoke/demo app: create source under
apps/<name>/. - Windows demo: place under
apps/windows/<name>/.
- Rust app: create
- Add workspace membership for Rust apps.
- Add
RUSTOS.package.tomlat the app root. - Use
kind = "app"andexecution_domain = "user". - Use
startup = "none"unless the app should auto-launch. - Add
[[desktop.entries]]with a cleardisplay_name. - Set
console_hosted = truefor terminal/console apps. - Set
console_hosted = falsefor UI/Wayland-style apps. - Run
cargo xtask check, thencargo 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
- app type을 선택합니다.
- Rust app:
apps/<name>/에Cargo.toml생성 - C smoke/demo app:
apps/<name>/아래 source 생성 - Windows demo:
apps/windows/<name>/아래 배치
- Rust app:
- Rust app은 workspace member에 추가합니다.
- app root에
RUSTOS.package.toml을 추가합니다. kind = "app",execution_domain = "user"를 사용합니다.- 자동 실행이 필요하지 않으면
startup = "none"을 사용합니다. - 명확한
display_name으로[[desktop.entries]]를 추가합니다. - terminal/console app은
console_hosted = true를 설정합니다. - UI/Wayland-style app은
console_hosted = false를 설정합니다. 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
Workflow
- Choose driver ownership:
- First-party kernel bridge:
drivers/bridges/<class>/<name>/. - Shared driver API/helper:
drivers/libs/<name>/. - Prebuilt/vendor module:
vendor/...plus manifest.
- First-party kernel bridge:
- Add workspace membership for source-based Rust drivers.
- Add
RUSTOS.package.toml. - Use
kind = "bridge-driver"andexecution_domain = "kernel"for bridge modules. - Use
[build] builder = "module-image"for Rust bridge modules. - Use
[install] path = "system/drivers/<class>/<name>.ko". - Add
[autoload]metadata when the driver should be loaded by device policy. - Put firmware or prebuilt external inputs under
vendor/. - Run
cargo xtask check, thencargo xtask build-driver-modules, thencargo xtask stageor fullcargo 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.tsvcontains the expected metadata.- Driver logs use category
driver, or a more specific category such asdisplay,usb,input, orstorage.
한국어
Workflow
- driver ownership을 선택합니다.
- first-party kernel bridge:
drivers/bridges/<class>/<name>/ - shared driver API/helper:
drivers/libs/<name>/ - prebuilt/vendor module:
vendor/...와 manifest
- first-party kernel bridge:
- source 기반 Rust driver는 workspace member에 추가합니다.
RUSTOS.package.toml을 추가합니다.- bridge module에는
kind = "bridge-driver",execution_domain = "kernel"을 사용합니다. - Rust bridge module에는
[build] builder = "module-image"를 사용합니다. [install] path = "system/drivers/<class>/<name>.ko"를 사용합니다.- device policy로 load되어야 하면
[autoload]metadata를 추가합니다. - firmware나 prebuilt external input은
vendor/아래에 둡니다. cargo xtask check,cargo xtask build-driver-modules, 그 다음cargo xtask stage또는 fullcargo 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는
drivercategory 또는display,usb,input,storage같은 더 구체적인 category를 사용합니다.
Paths Reference
English
| Path | Meaning |
|---|---|
Cargo.toml | Workspace manifest. |
config/rustos.toml | Shared 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.EFI | GRUB-generated default UEFI entry. |
build/image/nucleus.elf.sig | Detached GPG signature for nucleus.elf. |
build/image/system/registry/ | Generated runtime/driver registries. |
logs/debugcon.log | Default debugcon output. |
logs/qemu_interrupt.log | QEMU interrupt trace when enabled. |
logs/rustos-debug.gdb | GDB helper generated by cargo xtask debug. |
Generated Registries
| Registry | Purpose |
|---|---|
system/registry/kernel/loadable-drivers.tsv | Driver autoload metadata. |
system/registry/system/desktop-programs.tsv | Desktop app/service metadata. |
system/registry/system/runtime-launch-programs.tsv | Runtime launch policy. |
system/registry/system/startup-programs.tsv | Startup ordering/policy. |
system/registry/compat/windows-system-dlls.txt | Windows DLL inventory. |
한국어
| Path | Meaning |
|---|---|
Cargo.toml | workspace manifest |
config/rustos.toml | logging과 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.EFI | GRUB이 생성한 기본 UEFI entry |
build/image/nucleus.elf.sig | nucleus.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.gdb | cargo xtask debug가 생성하는 GDB helper |
Generated Registries
| Registry | Purpose |
|---|---|
system/registry/kernel/loadable-drivers.tsv | driver autoload metadata |
system/registry/system/desktop-programs.tsv | desktop app/service metadata |
system/registry/system/runtime-launch-programs.tsv | runtime launch policy |
system/registry/system/startup-programs.tsv | startup ordering/policy |
system/registry/compat/windows-system-dlls.txt | Windows DLL inventory |
Environment Variables Reference
English
| Variable | Default | Purpose |
|---|---|---|
ROOT_DIR | repo root | Override repository root. |
WORKSPACE_MANIFEST | Cargo.toml | Override workspace manifest path. |
CARGO_TARGET_DIR | target | Override Cargo target dir. |
CARGO | cargo | Cargo executable. |
RUSTUP | rustup | rustup executable. |
CC | gcc | C compiler. |
MINGW_CC | x86_64-w64-mingw32-gcc | Windows PE compiler. |
QEMU_BIN | qemu-system-x86_64 | QEMU executable. |
KERNEL_TARGET | x86_64-unknown-linux-gnu | Kernel/userspace target. |
GRUB_MKSTANDALONE | grub-mkstandalone | GRUB standalone EFI builder. |
GRUB_FILE | grub-file | Multiboot2 artifact validator. |
GPG | gpg | GPG executable used for detached kernel signatures. |
RUSTOS_GRUB_PUBKEY | build/dev-grub.pub | Binary GPG public key file embedded into GRUB, produced with gpg --export. |
RUSTOS_GRUB_SIGNING_KEY | RustOS 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_HOME | build/dev-grub-gpg | Optional GPG home for signing. |
RUSTOS_GRUB_SBAT | empty | Optional SBAT metadata file passed to grub-mkstandalone. |
RUSTOS_GRUB_MODULES | secure boot module set | Optional GRUB module list override. |
BUILD_DIR | build | Build output root. |
IMAGE_DIR | build/image | Staged image root. |
OVMF_PATH | vendor/firmware/ovmf/OVMF.fd | Firmware image. |
RUSTOS_QEMU_PROFILE | default | QEMU profile default. |
RUSTOS_QEMU_ACCEL | empty | QEMU accelerator profile default. |
RUSTOS_QEMU_NETWORK | enabled | Set 0, false, off, or no to disable default network. |
RUSTOS_UI_BOOT_TRACE | disabled | Enable uiserver local boot trace. |
RUSTOS_UI_PROFILE | disabled | Enable 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.
한국어
| Variable | Default | Purpose |
|---|---|---|
ROOT_DIR | repo root | repository root override |
WORKSPACE_MANIFEST | Cargo.toml | workspace manifest path override |
CARGO_TARGET_DIR | target | Cargo target dir override |
CARGO | cargo | Cargo executable |
RUSTUP | rustup | rustup executable |
CC | gcc | C compiler |
MINGW_CC | x86_64-w64-mingw32-gcc | Windows PE compiler |
QEMU_BIN | qemu-system-x86_64 | QEMU executable |
KERNEL_TARGET | x86_64-unknown-linux-gnu | kernel/userspace target |
GRUB_MKSTANDALONE | grub-mkstandalone | GRUB standalone EFI builder |
GRUB_FILE | grub-file | Multiboot2 artifact validator |
GPG | gpg | detached kernel signature 생성용 GPG executable |
RUSTOS_GRUB_PUBKEY | build/dev-grub.pub | gpg --export로 만든 GRUB embed용 binary GPG public key file |
RUSTOS_GRUB_SIGNING_KEY | RustOS Dev GRUB <rustos-dev-grub@example.invalid> | nucleus.elf 서명에 사용할 GPG key id/fingerprint. 없으면 xtask build가 기본 개발 키를 생성 |
RUSTOS_GPG_HOME | build/dev-grub-gpg | signing에 사용할 optional GPG home |
RUSTOS_GRUB_SBAT | empty | grub-mkstandalone에 넘길 optional SBAT metadata file |
RUSTOS_GRUB_MODULES | secure boot module set | optional GRUB module list override |
BUILD_DIR | build | build output root |
IMAGE_DIR | build/image | staged image root |
OVMF_PATH | vendor/firmware/ovmf/OVMF.fd | firmware image |
RUSTOS_QEMU_PROFILE | default | QEMU profile default |
RUSTOS_QEMU_ACCEL | empty | QEMU accelerator profile default |
RUSTOS_QEMU_NETWORK | enabled | 0, false, off, no로 default network 비활성화 |
RUSTOS_UI_BOOT_TRACE | disabled | uiserver local boot trace 활성화 |
RUSTOS_UI_PROFILE | disabled | uiserver 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 checkcargo xtask build-kernelcargo xtask build-usercargo xtask build-driver-modulescargo xtask stagecargo 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:
AGENTS.mddocs/ai-map.mddocs/ai/token-policy.mddocs/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, andtask-router.mdas 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:
- Root
AGENTS.md. docs/ai-map.md.token-policy.md.task-router.md.
Then append one focused AI doc selected by task-router.md.
Primary human docs:
docs/index.mddocs/ai-map.mddocs/getting-started.mddocs/execution-flow.mddocs/structure.mddocs/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.rsboundary - 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.dataCargo.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.locksnippets.
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 -nfirst - 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:
AGENTS.mddocs/ai-map.mddocs/ai/token-policy.mddocs/ai/task-router.md- 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 task | Read first | Then read only if needed |
|---|---|---|
| Build/check issue | commands.md | exact failing command output, then tools/xtask/src/build.rs range found by rg |
| Run/QEMU/debug issue | commands.md, repo-map.md | exact tools/xtask/src/qemu.rs range found by rg; logs only via tail -n 120 or focused rg |
| Package/stage/registry issue | contracts.md | affected RUSTOS.package.toml, then exact package_manifest.rs or stage.rs range |
| Kernel API/change | kernel-api-map.md | relevant kernel/*/src/api.rs, then backing module range found by symbol search |
| Kernel boot-order change | kernel-api-map.md, contracts.md | kernel/src/main.rs, then exact kernel/executive/src/boot.rs range |
| Logging change | contracts.md | config/rustos.toml; open tools/build_log_cfg.rs only after searching category/level name |
| Fault injection change | contracts.md, commands.md | config/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 issue | contracts.md | libs/runtime-control/src/lib.rs, then exact services/runtimed/src/main.rs range |
| UI/rendering issue | repo-map.md | search services/uiserver/src; open only the matching render.rs or app/* range |
| Hardening request | contracts.md, kernel-api-map.md | highest-risk boundary first; exact API, broker, service, lock, memory, or device path found by rg |
| Ring0/ring3 ownership or microkernel boundary | contracts.md, ring3-evacuation.md | commercial-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/driver | workflows.md | one closest existing manifest, one closest source file, target manifest/source only |
| Docs update | docs/SUMMARY.md | target 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
rgreturns 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.rsor 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.mdfor generated paths, logs, andCargo.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.mdand 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.komodules.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.rsandtools/xtask/src/stage.rs. - For QEMU behavior, inspect
tools/xtask/src/qemu.rs. - For runtime launch behavior, inspect
services/runtimed/src/main.rsandlibs/runtime-control/src/lib.rs. - For UI behavior, inspect
services/uiserver/src/app/*andservices/uiserver/src/render.rs. - For kernel subsystem integration, inspect the relevant
kernel/*/src/api.rsfirst, then the backing module. - For documentation navigation, inspect
docs/SUMMARY.mdfirst.
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.mdordocs/api/kernel.md: use AI contracts first.
Allowed generated-path exceptions are defined in token-policy.md.
AI Commands
Use from repo root.
| Command | Use | Writes | Common failure meaning |
|---|---|---|---|
cargo xtask check | validate layering/manifests/workspace | target/ | dependency layer violation, bad manifest, missing target |
cargo xtask build | full OS build + stage | target/, build/ | compile error, missing firmware/artifact, manifest staging error |
cargo xtask stage | restage built artifacts | build/image | missing required artifact, bad install path |
cargo xtask run | boot current image in QEMU | logs/, temp dirs | missing build/image, missing OVMF, QEMU failure |
cargo xtask debug | QEMU with GDB stub | logs/rustos-debug.gdb | same as run plus debug setup |
cargo xtask probe-display | headless display probe with screendump geometry and non-black frame validation | logs/ | display/surface/present regression |
cargo xtask qemu-scenarios --list | list predefined QEMU regression scenarios | none | unknown local xtask binary |
cargo xtask qemu-scenarios --scenario display-probe | run one QEMU regression scenario | logs/ | boot/display/input regression |
cargo xtask selftest | host selftests for fault parsing, ABI/layout, runtime contracts, and module tests | target/ | contract/layout regression |
cargo xtask fuzz-host --target all | deterministic host fuzz smoke for fault rules, project config, and package manifest parsing | logs/ on crash | parser panic or invariant bug |
cargo xtask build-user | userspace packages only | target/, build/artifacts | service/app compile error |
cargo xtask build-driver-modules | bridge modules only | target/, build/artifacts | driver/module build error |
cargo test -p module-tests | module tests | target/ | unit/module regression |
git diff --check | whitespace sanity | none | trailing 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,--timeoutis 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-logand focusedrgover 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 buildifmdbookexists.rg -n "\[[^]]+\]\(([^)#]+\.md)" docs README.mdto 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 appsfind kernel -maxdepth 4 -name api.rs | sortfind . -name RUSTOS.package.toml | sortrg -n "enum XtaskCommand|struct Config|enum PackageKind" tools/xtask/srcsed -n 'START,ENDp' path/to/fileafterrgfinds the relevant line range.
GRUB Secure Boot debug environment:
cargo xtask buildcreates a local development GRUB signing key underbuild/dev-grub-gpgwhenRUSTOS_GRUB_*is unset.grub-file --is-x86-multiboot2 build/image/nucleus.elfgpg --homedir build/dev-grub-gpg --verify build/image/nucleus.elf.sig build/image/nucleus.elf
KVM display boot loop:
cargo xtask buildcargo xtask run --profile nvme --accel-profile kvm --usb-input --debugcon filerg -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_depsreferences packageid, 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]supportsdepsfor required module preloads andsoftdepsfor best-effort preloads, matching Linuxmodules.depandmodprobe.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_nameslists Linux in-module driver names allowed to register from that package. If omitted, staging defaults it to the autoloadname. Linux driver compat registration must use this registry field rather than hardcoded driver names. - Driver
[autoload].provider_groupis a mutually exclusive provider contract. Once a loadable or native provider marks the group active, later candidates in the same group are skipped.fallback_onlycandidates are ordered after normal candidates and should be used only as lower-priority substitutes. - In the
display-primaryprovider group, real hardware/virtio display providers must be ordered ahead of firmware framebuffer fallbacks.bootfbis a last-resort fallback, not the default primary for QEMU or hardware GPUs. driverdowns driver autoload policy. Kernel driver brokers may expose narrow hardware-presence primitives for staged aliases such asplatform:bootfb,pci:*, andvirtio:*, but they must not pick provider order or bypass registryprovider_grouppolicy.
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.tsvsystem/registry/system/desktop-programs.tsvsystem/registry/system/runtime-launch-programs.tsvsystem/registry/system/startup-programs.tsvsystem/registry/system/linux-runtime-access.tsvsystem/registry/system/runtime-env.tsvsystem/registry/compat/windows-system-dlls.txt
- Linux runtime filesystem access is staged into
system/registry/system/linux-runtime-access.tsvaskind=dir|fileandpath=/absolute/pathfields. 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.tsvasscope=init|runtime,key=NAME, andvalue=VALUEfields.initdandruntimedshould consume this registry instead of hardcoding defaultPATH,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.rsandkernel/compat/src/user/abi.rs. - The kernel launches
services/rootd/rootd.elfas the first user process.rootdis the bootstrap initial task: it must avoid Linux libc/std dynamic runtime dependencies, startsyscalld,vfsd,loaderd, andprocd, then hand off normal service orchestration toservices/initd/initd.elf. Kernel boot code should not grow generic POSIX compatibility exceptions forinitd; any unavoidable early service bootstrap surface must stay narrow, explicit, and tied torootdbringing 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, andmunmapbelongs tosyscalld; kernel MM keeps only the gatedSYS_RUSTOS_MM_BROKERprimitive 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 throughloaderd,procd,syscalld, and narrow kernel brokers; process and signal policy belongs toprocd, executable image policy belongs toloaderd, clock policy belongs tosyscalldexcept hot read-onlyclock_gettime/nanosleepfast 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
.komodule execution. Linux.komodules 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.koexecution 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; seedocs/ai/ring3-evacuation.md. - Device, console, and UI
repr(C)structs and ioctl numbers must be defined inrustos-user-abi; services such asuiserverandruntimedshould 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 throughSYS_RUSTOS_IPC_REGISTER_SERVICE_ENDPOINTand looked up by stableIPC_SERVICE_*ids. Registering endpoint0revokes the service endpoint and later lookups fail closed.syscalldis service id 1,vfsdis service id 2,netdis service id 3,devmgrdis service id 4,driverdis service id 5,loaderdis service id 6,storagedis service id 7,inputdis service id 8, andprocdis service id 9. File/path Linux syscall policy should route tovfsd; AF_UNIX and socket control policy should route tonetd; device open/ioctl policy should route todevmgrd; module autoload/provider policy belongs indriverd; executable format and launch policy belongs inloaderd; storage inventory policy belongs instoraged; input observability/control policy belongs ininputd; process/fork/wait and signal policy belongs inprocd. 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 areIPC_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, andIPC_SERVICE_CAP_PROCESS_POLICY.procdowns process/thread namespace policy for Linuxexecve, process-copyfork/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_64rt_sigframe/rt_sigreturnprimitives. - Kernel IPC endpoint calls support bounded cap-transfer slots through
kernel_ipc_runtime::api::KernelTransferredHandleand the*_with_handlesendpoint APIs. Byte-only recv/take wrappers must keep failing withBufferTooSmallwhen 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 whoseHandleRights::allows_transfer()is true. - Process FD tables expose transfer only through
kernel_ps::api::TransferredHandleEntryandHandleTable::{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_HANDLESwith the sharedIpc*WithHandlesArgsstructs. Send handles are Linux fd arrays; received handles are installed into the receiver fd table and returned asi32fd arrays plus au16count.recv_fd_count_ptris mandatory for the handle-aware ABI, even when no handles are returned. Counts are bounded byIPC_MAX_TRANSFER_HANDLES, and byte-only IPC syscalls must not silently carry or discard transferred handles. - VFS ownership uses
VfsIpcRequest/VfsIpcResponse, separate fromLinuxSyscallOffloadRequest, for service-owned file handles and chunked I/O.vfsdowns 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 asKernelHandle::RemoteVfs; kernel code may still own bootstrapping, process/MM, user-memory copying at syscall entry, and explicit broker primitives. SYS_RUSTOS_BLOCK_BROKERis the narrow boot-volume read broker forvfsd. It is gated byIPC_SERVICE_CAP_VFS_POLICY, acceptsRustosBlockBrokerArgs, and exposes only boot-volume info plus bounded read-only block reads. This migration does not depend onstoraged.storagedowns block-device inventory policy after it registersIPC_SERVICE_STORAGED. It calls the gatedSYS_RUSTOS_STORAGE_LIST_BROKERprimitive, which is authorized only byIPC_SERVICE_CAP_STORAGE_POLICY, to enumerate kernel-discovered storage descriptors without exposing direct generic-app storage probing.inputdowns input queue observability and input-read authorization policy after it registersIPC_SERVICE_INPUTD. Kernel Linux input reads callInputdIpcRequest/InputdIpcResponsewithINPUTD_IPC_OP_AUTHORIZE_READ;inputdapproves the access class and maximum read size, then ring0 performs only the current-process user-copy/device data path.inputdalso calls the gatedSYS_RUSTOS_INPUT_STATS_BROKERprimitive, authorized only byIPC_SERVICE_CAP_INPUT_POLICY, to inspect kernel input queue counters while the remaining event queue is being evacuated.- Linux
openatinstallsKernelHandle::RemoteVfsfor regular files and directories aftervfsdregistration. Device paths remain kernel device handles through the device broker path untildevmgrddevice-open transfer is complete. Policy services may still use the bootstrap VFS path to avoid recursive self-IPC during service startup. Beforevfsdregisters its endpoint, the gated bootstrap VFS broker remains available for service dynamic-loader bootstrap; after registration, generic Linux app VFS syscalls must route tovfsdor fail closed ifvfsdis unavailable. - Linux
close,dup/dup2/dup3, andfcntlroute throughvfsdbefore mutating the app fd table.vfsdis the only intended caller of the gated narrowSYS_RUSTOS_FD_*_BROKERbroker primitives; generic apps must not use them directly.LinuxSyscallOffloadRequest.arg0..arg3are 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-bitmaskfield. - Linux
getdents64also routes throughvfsd; the gated narrowSYS_RUSTOS_FD_GETDENTS64_BROKERbroker primitive writes directory records into the target process address space selected by pid. FD broker syscalls must remain gated to the registeredIPC_SERVICE_CAP_VFS_POLICYowner, not broad policy-service callers. - Linux
mountandumount2must preserve Linux ELF compatibility while keeping namespace policy invfsd: generic app syscalls route tovfsd, thenvfsdcalls the gated narrowSYS_RUSTOS_VFS_*_BROKERbroker primitives for the narrow kernel mount-table mutation. Do not reintroduce direct generic-applinux_ops::mountorlinux_ops::umount2paths. - Legacy RustOS metadata syscall numbers
SYS_RUSTOS_{STATX,STAT,READLINK,ACCESS,GETCWD,CHDIR}_METADATAmust not perform direct generic-app VFS policy in ring0 aftervfsdregisters. They route throughvfsdfor generic callers and retain direct kernel metadata access only for pre-vfsdbootstrap and registered policy-service callers. - Runtime launches must route through
loaderd, not direct genericSYS_RUSTOS_SPAWN_EXECcalls.loaderdregistersIPC_SERVICE_LOADERD, validates executable format policy, and uses the gated narrowSYS_RUSTOS_PROC_*_BROKERbroker primitives for kernel-owned process commit work.SYS_RUSTOS_PROC_*_BROKERcalls must fail withEACCESunless the caller ownsIPC_SERVICE_CAP_PROCESS_LOADER.SYS_RUSTOS_SPAWN_EXECis restricted torootdspawning the fixed bootstrap service allowlist (syscalld,vfsd,loaderd,procd,initd) and must fail closed forinitd, generic apps, and service restarts. Core-service supervision after bootstrap needs an explicitrootd/supervisor contract, not a broader kernel spawn fallback. - Process broker sessions start with
SYS_RUSTOS_PROC_PREPARE_BROKERusingPROC_BROKER_ABI_VERSIONand an explicit executable format (PROC_BROKER_FORMAT_ELF64orPROC_BROKER_FORMAT_PE64). The returnedprepare_handleis owned by the loader service process and must be supplied toSYS_RUSTOS_PROC_COMMIT_BROKERorSYS_RUSTOS_PROC_ABORT_BROKER.SYS_RUSTOS_PROC_MAP_ZEROED_BROKER,SYS_RUSTOS_PROC_MAP_DATA_BROKER, andSYS_RUSTOS_PROC_MAP_FILE_BROKERusePROC_BROKER_MAP_{READ,WRITE,EXEC,PRIVATE}flags and record non-overlapping page-aligned mappings in the prepare session.SYS_RUSTOS_PROC_MAP_FILE_BROKERand its batch variantSYS_RUSTOS_PROC_MAP_FILE_BATCH_BROKERare fd/cap-backed only: the kernel resolves the caller's fd to a pinnedKernelHandleat registration time; no path re-open occurs at commit. Backing must be a file-kind handle (VfsFile,RemoteVfs(File), orMemfd); directory, device, and socket descriptors are rejected withEINVAL/EACCES.loaderdmust emit ELFPT_LOADmappings for both the main image and itsPT_INTERPinterpreter viaSYS_RUSTOS_PROC_MAP_FILE_BROKER, using the static-PIE load biases (PROC_BROKER_USER_SPACE_BASE + 0x0040_0000for the main image andPROC_BROKER_USER_SPACE_BASE + 0x0200_0000for the interpreter). The kernel prepare session stores loader-materialized data pages for mappings that need service-side fixups. Linux ELF sessions must useSYS_RUSTOS_PROC_SET_LINUX_RUNTIME_BROKERto supply minimal launch metadata (entry, phdr, phnum, phent, brk_start, interpreter_base) instead of streaming the raw binary withSYS_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 toloaderd: 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 includeSYS_RUSTOS_PROC_SET_WINDOWS_RUNTIME_BROKERmetadata after allSYS_RUSTOS_PROC_MAP_DATA_BROKERmappings and beforeSYS_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 appexecvegoes throughprocdfor target authorization and thenloaderdfor executable image materialization; if loader materialization fails,procdmust cancel the exec ticket withSYS_RUSTOS_PROC_CANCEL_EXEC_BROKERbefore replying. Do not move executable-format, import/export, or DLL namespace policy back into the kernel. - Policy-sensitive Linux
ioctlrequests route throughdevmgrdafter bootstrap.devmgrdowns request authorization and callsSYS_RUSTOS_DEVICE_IOCTL_BROKER, which is gated byIPC_SERVICE_CAP_DEVICE_POLICYand performs the kernel-owned user memory/device operation against the target process id and fd. The kernel may use a direct ioctl fallback beforeIPC_SERVICE_DEVMGRDis 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
syscalldusingWin32SyscallOffloadRequest/Win32SyscallOffloadResponseand theSYSCALL_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
wait4routes process ownership validation throughprocd; the kernel still performs the narrow process-table wait and status/rusage copyout. Linuxmemfd_createroute policy validation remains insyscalld, 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
netdafter bootstrap.socket,socketpair,bind,listen,accept/accept4,connect,sendto,recvfrom,sendmsg,recvmsg,getsockname,getpeername,setsockopt,getsockopt, andshutdowncallnetd, andnetdinvokes the gatedSYS_RUSTOS_NET_BROKERprimitive 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 tonetd. The net broker argument struct carries six 64-bit syscall argument slots for this migration surface. driverdowns registry parsing and provider/autoload ordering after it registersIPC_SERVICE_DRIVERD. The gated driver broker surface isSYS_RUSTOS_DRIVER_LOAD_MODULE_BROKER,SYS_RUSTOS_DRIVER_PROBE_ALIAS_BROKER, andSYS_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.devmgrdowns the visible/devregistry protocol exposed tovfsdthroughDevmgrdIpcRequest/DevmgrdIpcResponsewithDEVMGRD_IPC_OP_LOOKUPandDEVMGRD_IPC_OP_READDIR.vfsdmay 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.syscalldkeeps the service-side Linux policy DB for per-process credentials andRLIMIT_STACK. Linux-visibleget*id,set*id, andprlimit64policy must be sourced fromsyscalld; kernel process credentials are a gated bootstrap/security primitive and must not be mutated by Linuxset*id.device::DisplayInfo.flagsdistinguishes boot firmware framebuffers from a real primary display provider. Userspace display surfaces must requireDISPLAY_INFO_FLAG_PRIMARY_PROVIDER; GRUB/firmware boot framebuffers are for early console and panic output by default. Thebootfbdriver is the only last-resort exception; if it exposes a firmware framebuffer as a primary provider, it must stay behind hardware/virtio providers and preserveDISPLAY_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 fromdisplay_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_msinuiserver, 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. uiserverpartial 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:
uiservergets a longer render/present slice so large framebuffer copies are not preempted every 100 us, andruntimedmust pass manifestweight_microsthroughloaderdinstead 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_reschedequivalent 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
.komodule init runs inside the calling user service's kernel frame. Linux compat exports such asschedule,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 RustOScond_reschedsafe points sodriverdmodule init cannot starveuiserver,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
KernelSpinLockacross disk, filesystem, IPC, or framebuffer-sized copy loops. UseKernelWaitLockor split the critical section, then add safecond_reschedpoints 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.
runtimeddepends onnetdfor its runtime control socket and waits for thedevmgrdendpoint before UI bootstrap because display ioctl policy routes there. Afterruntimedis launched, defer secondary storage policy briefly so it does not contend with display bring-up.
Kernel API:
- Prefer
kernel/*/src/api.rspublic wrappers over private subsystem modules. - Main API surfaces:
kernel/hal/src/api.rskernel/mm/src/api.rskernel/object/src/api.rskernel/ipc-runtime/src/api.rskernel/ps/src/api.rskernel/io-manager/src/api.rskernel/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 whenapi.rsexposes 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}. Thecurrent_user_id,block_current_user_task, andwake_user_taskwrappers 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]; setKERNEL_BUILD_CONFIGto 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_UNITSoverrides the kernel codegen unit count for experiments without changing userspace builds.KERNEL_CODEGEN_UNITSremains a deprecated alias. The supported sweep range is1..=256.- Kernel build-shape knobs also include
lto,force_frame_pointers,incremental,debuginfo,embed_bitcode,panic,relocation_model,strip, andextra_rustflags.incrementalis applied asCARGO_INCREMENTALon kernel Cargo invocations. - Kernel Cargo invocations disable a configured
sccacherustc wrapper because kernel build-std/LTO flag probes are not accepted by sccache. embed_bitcode=trueis required wheneverltoisthinorfat.cargo xtask config checkvalidates effective config;cargo xtask config showprints the effective kernel build config.- Driver module loading must be stable across the supported
codegen_units=1..=256andopt_level=0..=3sweep. 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.rspasses rules through fw_cfgopt/rustos/fault-injection. - Kernel runtime:
kernel/nucleus-core/src/util/fault_injection.rs. - Kernel init:
kernel/executive/src/boot.rscallsfault_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-msis 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.tomlmay 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 indriverd, and the kernelkernel/io-manager/src/driver/mod.rssurface is limited to privileged DMA, IRQ, IOMMU, and MMIO primitives plus explicit module-load substrate hooks. driverdselects 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.koimages, relocating them, exposingDriverKernelApiV1, mapping MMIO, and executing module init in the kernel address space when the module ABI requires it. Do not move Linux.koexecution 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
.koloading 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 underbuild/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.mdand 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.
| Need | Import | Read |
|---|---|---|
| GDT/IDT/ACPI/PIC/RTC/SIMD/hooks | kernel_hal::api as hal_api | kernel/hal/src/api.rs |
| Heap/paging/frames/higher-half | kernel_mm::api as mm_api | kernel/mm/src/api.rs |
| Handles/rights/session ids | kernel_object::api as object_api | kernel/object/src/api.rs |
| Shared memory regions | kernel_ipc_runtime::api as ipc_api | kernel/ipc-runtime/src/api.rs |
| Scheduler/process/user state | kernel_ps::api as ps_api | kernel/ps/src/api.rs |
| VFS/devices/console/drivers/input/USB | kernel_io_manager::api as io_api | kernel/io-manager/src/api.rs |
| Linux/Windows compat/syscalls | kernel_compat::api as compat_api | kernel/compat/src/api.rs |
| Boot orchestration/hooks | kernel_executive::boot | kernel/executive/src/boot.rs, kernel/executive/src/lib.rs |
| Logging/panic/boot trace | nucleus_core::debug | kernel/nucleus-core/src/debug/mod.rs |
Boot order from kernel/src/main.rs:
hal_api::disable_interruptsdebug::boot_trace::inithal_api::init_gdthal_api::init_idtmm_api::init_paginghal_api::enter_higher_halfhal_api::call_with_stackboot::kernel_main_bootstrap
Do not reorder without reading kernel/src/main.rs and kernel/executive/src/boot.rs.
High-risk APIs:
unsafeboot 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, andwake_taskfor kernel-capable wait queues; use*_user_*wrappers only for userspace-task waits. - scheduler preemption: use
cond_resched/reschedule_if_requestedonly 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
.koinit preemption: module init executes as a user-service syscall kernel frame, so long lock-free Linux compat callbacks must callcond_reschedat 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:
- Read
docs/guides/add-service.md. - Inspect similar service manifest under
services/*/RUSTOS.package.toml. - Add crate under
services/<name>. - Add workspace member.
- Add manifest with
kind = "service",execution_domain = "user". - Run
cargo xtask check. - Update docs only if manifest/runtime behavior changes.
Add app:
- Read
docs/guides/add-app.md. - Inspect
apps/wayclick/RUSTOS.package.tomlorapps/shell/RUSTOS.package.toml. - Choose Rust/C/Windows app path.
- Add manifest and desktop entry.
- Run
cargo xtask check. - Update docs only if launch policy or app workflow changes.
Add bridge driver:
- Read
docs/guides/add-driver.md. - Inspect
drivers/bridges/display/bootfb/RUSTOS.package.toml. - Add source under
drivers/bridges/<class>/<name>. - Add manifest with
kind = "bridge-driver". - Add
[autoload]only if policy-loaded. - Run
cargo xtask build-driver-modules. - If autoload policy changes, inspect generated driver registry after stage.
Modify kernel API:
- Read
docs/ai/task-router.md,docs/ai/contracts.md, and relevantkernel/*/src/api.rs. - Preserve
api.rsas the cross-crate boundary. - Update
docs/api/kernel.mdonly for public API surface or boot/order changes. - Run focused
cargo checkwhere possible; otherwisecargo xtask check.
Modify logging:
- Read
docs/logging.mdanddocs/ai/contracts.md. - Update
config/rustos.toml[logging]. - If adding category, update
libs/rustos-observability/src/lib.rs,tools/build_log_cfg.rs, human logging docs, and AI contracts. - Rebuild affected crates; prefer
cargo xtask buildfor kernel logging.
Update docs:
- Human docs: bilingual, English first, language anchors.
- AI docs: English only, dense, no repeated bilingual prose.
- Update
docs/SUMMARY.mdfor new human or AI pages. - If behavior contracts changed, update
docs/ai/contracts.mdor the focused AI map. - Run mdBook/link sanity checks.
Debug QEMU boot:
- Ensure
cargo xtask buildcompleted. - Run
cargo xtask run --debugcon stdiofor immediate logs. - Use
cargo xtask debugfor GDB attach. - Inspect
logs/debugcon.log,logs/qemu_interrupt.logif interrupt trace enabled. - If display issue, run
cargo xtask probe-display.
Debug GRUB display boot:
- Check
tools/xtask/src/build.rsembedded GRUB config before changing QEMU flags. - Keep GRUB video setup conservative:
load_video,gfxmode=auto,gfxpayload=keep. - Check
kernel/nucleus-core/src/multiboot2_entry.Sfor the Multiboot2 framebuffer request tag. - Confirm the kernel log prints a nonzero
boot framebuffer addr. - Confirm
platform:bootfbcan match fromstorage::boot_volume::boot_framebuffer_info(), not from an already-installed GUI backend. - Confirm
display-primaryfallback decisions use active display state, not just a loaded module record. - For QEMU virtio-gpu, confirm
virtio-gpu native: display registeredappears aftervirtio register driver.
Reduce context mid-task:
- Summarize findings into the current response before opening more files.
- Prefer one subsystem at a time.
- Close questions by pointing at source path + line/symbol, not by pasting long code.