Replace the keyboard driver's synthetic stream with the real path: - ps2-bus binds IRQ1 (interrupt bits set only after the bind), drains port 0x60 on each interrupt, and forwards every byte to the attached child driver over async ipc_send, routed by the status register's auxiliary-output bit. Children attach via the new well-known ps2_bus service, handing over their endpoint as a capability. - scancode.zig (new, pure, host-tested): scancode set 2 -> USB HID usage decoding (F0/E0/E1 prefix state machine) plus keyboard state — pressed-key bitmap, typematic-repeat classification, modifier and caps-lock tracking. - keyboard.zig decodes the forwarded stream and publishes real key_down/key_press/key_up events, filling key_press characters via xkeyboard-config (layout from argv[2], default us) and synthesizing ASCII control characters for Enter/Tab/Backspace/Escape. - protocol.zig names the full HID usage set in Keycode; build.zig threads the xkeyboard-config module into user binaries. Verified end to end in QEMU via monitor sendkey: shift, caps lock, and control-character synthesis all decode correctly. The mouse driver still publishes its synthetic stream; attaching it to the bus the same way is the follow-up. |
||
|---|---|---|
| boot | ||
| docs | ||
| library | ||
| system | ||
| test | ||
| tools | ||
| .gitignore | ||
| .zig-version | ||
| README.md | ||
| build.zig | ||
| build.zig.zon | ||
README.md
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/ 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 orzigupwill pick up.zig-versionautomatically. - QEMU (
qemu-system-x86_64) — to run and test the kernel. On macOS,brew install qemualso bundles the OVMF firmware below. - OVMF UEFI firmware — the
edk2-ovmfpackage (Arch),ovmf(Debian/Ubuntu), oredk2-ovmf(Fedora); on macOS it ships inside the Homebrewqemuformula. 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
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):
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
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/ — start with docs/README.md.
Logo
San Serif Text "Dan OS" with a black karate belt around it.