Files
danos/README.md
T
Daniel Samson be81394be3 Split the system contract into boot-handoff / abi / device-abi
The `system` module (formerly `danos`) had become a grab-bag: it held the
loader<->kernel handoff *and* the kernel<->user ABI *and* the device wire types, in
one module three different audiences imported. Usage proved the seam — the
bootloader never touched the syscall/device ABI, and user space never touched the
boot handoff — so split it by audience, one module per contract:

  system/boot-handoff.zig       loader <-> kernel: BootInformation, Framebuffer,
                                MemoryMap, the VM layout + physicalToVirtual, kernel_abi
  system/abi.zig                kernel <-> user, core: SystemCall, mmap prot flags,
                                page_size, notify_badge_bit, ServiceId
  system/devices/device-abi.zig kernel <-> user, devices: DeviceDescriptor,
                                DeviceClass, ResourceDescriptor, ResourceKind, ...

device-abi is the devices sub-project's public interface, exposed as its own module
the way vfs exposes vfs-protocol — importable by user space, unlike the
kernel-internal device model it also feeds. That collapses a real duplication:
DeviceClass and ResourceKind were defined twice (device-model.zig and the contract,
kept "in sync by hand"); device-model now re-exports them from device-abi, so the
enum a driver matches on and the one the kernel classifies with are one type.

Each import now declares which contract it speaks: the bootloader imports only
boot-handoff; a driver only abi + device-abi (via the runtime); the kernel all
three. This also retires the `system` / `runtime.system` name overlap. page_size
lands in abi (it's part of the mmap contract user space aligns to); the bootloader
keeps its own local 4 KiB constant so it depends on nothing but the handoff.

All 21 importers rewired, docs updated to keep /system mapping to source. Build,
host tests, and the QEMU suite (36/36) all green.
2026-07-10 18:08:51 +01:00

69 lines
2.7 KiB
Markdown

# DanOS
Codename: Shodan
Version: 1
A small operating system, written from scratch in Zig — a bootloader (`boot/`)
and a microkernel (`system/kernel/`), sharing a neutral handoff contract (`system/boot-handoff.zig`).
It boots x86-64 via UEFI, and so far has a framebuffer console, a physical frame
allocator, its own paging with W^X permissions, interrupt/exception handling, a
LAPIC timer, a kernel heap, a fixed-priority preemptive scheduler, and in-kernel IPC
channels. See [`docs/`](docs/README.md) for how each piece works.
## Prerequisites
- **Zig 0.16.x** — the build is pinned to this line (`.zig-version`); other minor
versions are rejected, because Zig makes breaking changes between releases
pre-1.0. A toolchain manager such as [zvm](https://github.com/tristanisham/zvm)
or `zigup` will pick up `.zig-version` automatically.
- **QEMU** (`qemu-system-x86_64`) — to run and test the kernel. On macOS,
`brew install qemu` also bundles the OVMF firmware below.
- **OVMF** UEFI firmware — the `edk2-ovmf` package (Arch), `ovmf` (Debian/Ubuntu),
or `edk2-ovmf` (Fedora); on macOS it ships inside the Homebrew `qemu` formula.
Both the build and the test harness probe the known Arch/Debian/Fedora/macOS
layouts and use the first that exists, so no configuration is normally needed.
Override with `-Dovmf-code=` / `-Dovmf-vars=` (build) if yours lives elsewhere.
- **Python 3** — for the QEMU integration test harness.
## Build
```sh
zig build
```
Produces a FHS-shaped `zig-out/` that *is* the danos filesystem and the boot volume:
the UEFI bootloader at `zig-out/EFI/BOOT/BOOTX64.efi`, the kernel at
`zig-out/system/kernel`, init at `zig-out/system/services/init`, drivers under
`zig-out/system/drivers/`, and the initial-ramdisk at `zig-out/boot/`.
## Run
Boot it in QEMU with OVMF (opens a display window):
```sh
zig build run-x86-64
# distro with OVMF elsewhere:
zig build run-x86-64 -Dovmf-code=/path/OVMF_CODE.fd -Dovmf-vars=/path/OVMF_VARS.fd
```
## Test
```sh
zig build test # host unit tests (the platform-independent shared code)
python3 test/qemu_test.py # QEMU integration tests: boots the kernel and asserts
# on its serial output (see docs/testing.md)
```
The integration harness builds and boots the kernel once per test case, checking
memory, the frame allocator, paging (incl. NX and the null guard), the heap,
interrupts, and exception handling. It exits non-zero on any failure, so it drops
straight into CI.
## Documentation
Design notes explaining the *why* behind the code live in
[`docs/`](docs/README.md) — start with [`docs/README.md`](docs/README.md).
## Logo
San Serif Text "Dan OS" with a black karate belt around it.