Commit Graph

49 Commits

Author SHA1 Message Date
Daniel Samson 1882161cb4
docs: system-image.md — the boot capsule documented in full
system.img was only mentioned in passing (efi.md, system-requirements.md);
its format, builder, fallback chain, and kernel-side life were spread across
pack-system-image.py, build.zig, efi.zig, initial-ramdisk.zig, and vfs.zig.
New dedicated page covers all of it, cross-linked from every prior mention
and added to the docs index.
2026-07-22 10:37:55 +01:00
Daniel Samson e854f65623
docs: full docs-vs-code audit — fix every stale claim across 40 docs
Every doc verified claim-by-claim against the code by parallel audit agents,
then fixed and adversarially re-verified. Two waves of staleness corrected:
the originally audited findings (higher-half boot handoff, kernel VFS
takeover, fault isolation + claim release + driver restart, AML/S5 moving to
ring 3, threading's shipped design, USB+FAT landing) and a second pass of
adjacent claims the verifiers caught (smp.md 'not built yet' intro,
system-requirements' PS/2-only and no-storage claims, halting.md's red-panic
and no-IDT text, testing.md's serial mirroring, router-era vfs-protocol
wording, capsule-first boot loading).

threading.md now documents the shared-fate gap explicitly: the design says a
process dies whole, the kernel today kills only the offending thread.

Also fixes three stale code comments (isr.s exceptionHandler, acpi.zig
sleepValue, build.zig boot-volume) — comments only, no behavior change.
2026-07-22 09:09:53 +01:00
Daniel Samson f9dea7790a
docs: rename arch.md to architecture.md and update all references
Rename the file to match current naming conventions and update all
cross-references throughout the documentation. Update the content to
reflect the current state of the codebase:

- Module is now called "architecture", not "arch"
- Directory is system/kernel/architecture/, not system/kernel/arch/
- Generic kernel file is kernel.zig, not main.zig
- Updated file listing for x86_64 architecture module (added smp.zig,
  per-cpu.zig, ioapic.zig, trampoline.s)
- Updated function list in cpu.zig to include enterUser/userExit and
  address-space management
- Clarified that _start lives in architecture-specific isr.s
- Expanded architecture-specific vs generic comparison table with
  actual current modules

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-22 02:10:00 +01:00
Daniel Samson 28b3635979 docs+code: spell out aspace/vaddr/paddr per coding standards
Expand the abbreviations flagged in docs/coding-standards.md (names spelled
out in full unless an acronym) across the kernel, runtime, ABI, tests, and
docs:

  aspace -> address_space  (AspaceRef -> AddressSpaceRef, retainAspace ->
           retainAddressSpace, loaded_aspace -> loaded_address_space, the
           liveAspaceCount/aspaceDestroyCount test hooks, etc.)
  vaddr  -> virtual_address
  paddr  -> physical_address

The kernel test case and its serial markers are renamed to match:
aspace-refcount -> address-space-refcount (kernel dispatch string and
test/qemu_test.py case name kept in sync). Prose in docs uses the natural
"address space"/"virtual address"; backticked field/identifier references
use the code spelling.

Also expand the bare "AS" abbreviation in three ABI comments and reframe the
set_thread_pointer ABI/handler docs to lead with the arch-neutral concept
(user-space TLS thread pointer; x86_64 IA32_FS_BASE, aarch64 TPIDR_EL0)
rather than x86 FS-first, matching scheduler.zig's existing framing.

Foreign ABI names preserved: the ELF p_vaddr field and mmap/mmio remain.

Verified: zig build, zig build test, and the full 25-case QEMU guardrail
suite all green.
2026-07-21 01:45:47 +01:00
Daniel Samson def34e71fc threads(M6): getCurrentId, docs, and CI wiring — threading built
New thread_self=42 syscall backs runtime.Thread.getCurrentId (the calling
thread's kernel task id). thread-test gains an id mode: two workers read
getCurrentId and the main thread confirms all three ids are non-zero and
distinct. Per-thread threadlocal TLS is deferred by design (no consumer; it would
need context-switched fs.base for an unused feature), as are RwLock/WaitGroup.

Marks the threading feature built (M1-M6): threading.md + docs/README.md status
updated, all thread-* cases wired into qemu_test.py.

Gate thread-id PASS; full suite green: 21/21 (thread-spawn/join/futex/mutex/id,
aspace-refcount, + 15 guardrail cases), zig build clean, zig build test green.
2026-07-20 21:55:13 +01:00
Daniel Samson 6e8b02d771 threads: design doc + /loop build plan
Add docs/threading.md (native runtime.Thread mirroring std.Thread over a
private thread ABI) and docs/threading-plan.md (6 milestones, each with a
serial-checkable gate + guardrail, plus an unattended /loop execution
contract). Index both in docs/README.md.
2026-07-20 20:39:24 +01:00
Daniel Samson 914af52b94
build: release-x86-64 — the flashable hybrid ISO (Etcher/dd + optical), built in-repo 2026-07-20 13:37:10 +01:00
Daniel Samson bdd8a48476
docs: vdso + vfs-protocol — the public ABI boundary, linked from the index 2026-07-20 13:36:50 +01:00
Daniel Samson 626e3c5e9b
docs: link the NVIDIA + Intel GPU feasibility studies from the index
Point the display entry (#19) at nvidia-gpus.md and intel-igpu.md as future native scanout backends.
2026-07-14 18:40:59 +01:00
Daniel Samson 0217662808
display: resilient scanout — supervised driver, survive loss, re-attach (v2 V6)
The compositor now survives the virtio-gpu driver dying and re-attaches when device-manager
restarts it — the last piece of display v2.

Three parts:

- The driver hellos the device manager (role: bus). It never did, so the manager — which
  spawns it supervised and expects a hello — was stopping it at the 3s hello deadline every
  run (the gate markers just printed first). Now it is properly supervised: not stopped for
  silence, and restarted on death.

- A kernel IPC fix so a call to a dead service errors instead of hanging. An endpoint records
  its owner; when that task dies, its registered endpoints are marked dead (and any parked
  senders woken with -EPEER), so ipc_call returns -EPEER rather than blocking on a reply that
  will never come. Without this the compositor's first present after the driver died blocked
  forever. General robustness — any client of any service benefits.

- The compositor re-attaches. Its .scanout calls now fail cleanly (caught), freezing the last
  frame; when the restarted driver re-announces, attach_scanout detects the backend is already
  virtio and logs "scanout re-attached", mapping the fresh shared surface and re-looking-up
  .scanout. (The previous shm mapping leaks — no shm_unmap syscall yet — but its frames are the
  dead driver's, reclaimed on exit.)

- device-manager gains a "test-scanout-restart" mode (like test-usb-restart) that kills the
  virtio-gpu driver once after it hellos; the displayReattachTest kernel scenario drives it.

Gate: python3 test/qemu_test.py display-reattach — "scanout upgraded to virtio-gpu" then
"scanout re-attached", no CPU exception, passing 3/3. host tests, ipc/ipc-call/ipc-cap,
supervision, shm, display-service, display-demo, virtio-gpu, display-native, and
display-modeset all pass; default zig build clean. v2 (V1-V6) complete.
2026-07-14 13:10:21 +01:00
Daniel Samson 2723b6f778
docs: display v2 design + plan (pluggable scanout backend)
Keep the GOP framebuffer as the floor, make scanout a pluggable backend, and
upgrade to a native virtio-gpu driver when it announces itself (dynamic
hot-attach; GOP stays the fallback for "no driver ever"). v2 builds the shm
cross-process memory capability, shared with the future client-surface path.
Milestones V1 (backend seam) → V6 (resilience + tests), each with a gate.
2026-07-14 09:28:31 +01:00
Daniel Samson cd812cc00e
display: framebuffer handoff primitive + service design (D1)
Kick off the display service track (docs/display.md, docs/display-plan.md): a
user-space compositor that owns the framebuffer. GOP and the PCI display device
are two views of one controller; GOP dies at ExitBootServices, so the portable
base is the boot-handoff linear framebuffer.

D1 makes that framebuffer reachable from user space over the existing device
claim/mmio_map path rather than a bespoke syscall:

- device-abi: a `display` DeviceClass, a DisplayInfo{w,h,pitch,format} on the
  descriptor, and a flags field on resources with a write-combining bit.
- devices-broker: seedDisplay() publishes the loader's framebuffer as a
  root-level `display` node (one WC-flagged memory resource); kmain seeds it
  after discovery. displayDevice()/displayClaimed() track the claim.
- paging/mmio_map: mapUserDeviceInto gains a write_combining bool — a WC-flagged
  resource maps through PAT entry 4 instead of strong-uncacheable (an
  uncacheable framebuffer blit is glacial).
- console: falls silent while a display service holds the framebuffer, and is
  forced back on by the panic/exception paths.

Gate: the `display` kernel test asserts the seeded node's shape and that the
claim + mmio_map leaf is genuinely write-combining (PAT bit set, PCD/PWT clear).
Regression-checked discovery/ioport/claim-release/supervision/device-list/
device-manager with the +1 device in the table.
2026-07-14 00:54:56 +01:00
Daniel Samson 347a041d85
Phase 1a: add the native runtime.fs, retire the posix shim
The first step of the Zig self-hosting roadmap (docs/zig-self-hosting.md): give
danos programs a danos-native file API and remove the premature POSIX compatibility
shim. This also resolves the earlier misplacement of a full-write helper into the
compat layer — that behaviour now lives natively in runtime.fs.File.writeAll.

- library/runtime/fs.zig: the danos-native file client over the VFS (open/read/
  write/writeAll/seekTo/attributes/close, directory listing, mount). Handles are
  *values* — a File/Directory owns its VFS node id and byte offset — so there is no
  per-process fd table or descriptor limit, unlike the POSIX fd model the shim
  emulated. This is where the operations that later become std.os.danos are staged.
- Retire library/posix/ (unistd, stdio): only five call sites used it, all file
  operations, all migrated to runtime.fs — fat (mount), the vfs-test and fat-test
  clients, and init/log-flush (the boot-log flush). stdio was already dead.
- build.zig: drop the posix module, its addUserBinary parameter, the per-binary
  import, and the ~26 call-site arguments.
- Docs: the VFS protocol's client is now runtime.fs; the docs index and
  coding-standards note posix is retired and the foreign-ABI naming exception now
  applies to the future std.os.danos seam; the process-lifecycle note points the
  future musl layer at that same seam rather than the deleted directory.

Deferred by design (see the roadmap): the C-ABI runtime.os errno seam is built at
fork time (its shape must match std/os/danos.zig); truncate/mkdir/rename are
Phase 2; stdio-byte fds and cwd are later slices.

Verified: zig build, zig build test, zig build check-fat-image, and a sequential
QEMU sweep — vfs, vfs-client-death (the park/hold-handle path), fat-mount, log-flush,
orderly-shutdown, initial-ramdisk (log-flush silent in the bare sweep), smoke, init,
usb-storage, device-manager — all green.
2026-07-13 19:43:56 +01:00
Daniel Samson 53e42837e0
Docs: add the Zig self-hosting roadmap
A forward-looking design note on making danos a real Zig target
(-target x86_64-danos) and eventually running the compiler on it, focused on
the standard-library surface (not the editor/terminal).

The core realisation: Zig 0.16 (post-writergate) collapses an OS port to ONE
seam — std.fs is gone, everything routes through the std.Io vtable, and
std.posix is generic over a single per-OS `system` module (std.os.<tag>). So the
port is "write std.os.danos once" and the whole fs/process/Io tower lights up,
rather than reimplementing the namespaces.

Records the decisions this shapes now: build runtime.os (the seam, promoted into
a forked std/os/danos.zig later) plus a thin runtime.fs; retire the premature
library/posix shim (only 5 unistd call sites); do NOT hand-mirror the high-level
std namespaces; do NOT emulate the Linux ABI; defer musl. Covers the host/target/
self-host roles and the four-part compiler fork, a coverage table of what danos
has vs the gaps (mkdir/unlink/rename/truncate, richer stat, wall-clock, env, cwd,
entropy, stdio bytes), a phased plan (target -> read-side+retire-posix ->
fs-mutation+stat -> single-threaded self-linked compiler), and the risks
(fork rebase treadmill, -fsingle-threaded and -fno-llvm/-fno-lld being
load-bearing, the "w"-does-not-truncate corruption bug). Linked from the docs index.
2026-07-13 19:26:51 +01:00
Daniel Samson 452080e997
Add runtime.time, drop demo drivers, harden TSC timekeeping
Time is a kernel concern in danos: the kernel owns the scheduling timer and
already exposes monotonic time via the clock/sleep/timer_bind syscalls, so a
userspace time service would be a redundant, slower path. This adds the generic
runtime.time module over those syscalls, retires the two demonstration drivers,
reorganizes the milestone docs, and makes the monotonic clock correct on Intel,
AMD, and inside any VM.

runtime.time (library/runtime/time.zig)
- Instant/Duration interface: now, sleep, spin, after, monotonicNanos, available
- a thin layer over system.clock/sleep/timerOnce; unit-tested arithmetic

Remove the demo drivers hpet and bus (a teaching example belongs in the docs,
not shipped in the tree)
- system/drivers/ now holds only real drivers: pci-bus, ps2-bus, usb-xhci-bus
- device-manager end-to-end test repointed to pci-bus (asserts on kernel state:
  the process table and the device tree, not a racy serial marker)
- device_register containment moved to a new in-kernel `containment` test
- the driver-model worked example moved inline into docs/drivers.md

Reorganize milestone docs into topic docs
- m17-m18 / m19-m20 / m21 plans dissolved into process-lifecycle, device-manager,
  discovery, and acpi docs; new docs/power.md and docs/timers.md; ~20 citations
  repointed; plan docs deleted

TSC reliability (apic.zig, smp.zig, cpu.zig, kernel.zig)
- check the invariant-TSC bit (CPUID 0x80000007 EDX[8]) on Intel and AMD
- cross-core "warp" check at SMP bring-up, pairwise BSP<->AP as each core comes up
- fall back to the HPET clocksource when the TSC is not invariant (a bare VM) or
  not synchronized (a warp), switched continuously so time never jumps
- boot log reports the outcome; new tsc-sync test exercises the TSC + warp path

Verified: zig build; zig build test; 60/60 QEMU cases (incl. new containment and
tsc-sync).
2026-07-13 11:56:43 +01:00
Daniel Samson 5b63a841ba
Docs: add system-requirements.md to the docs index 2026-07-13 11:11:04 +01:00
Daniel Samson 75d62660b0
Bring the docs up to the M17-M18 reality; pre-settle M19-M20 ambiguities
resilience.md: steps 1-4 of the ladder are built — supervision, exit
reasons, restart with backoff, crash-loop caps, all proven by scenario;
what remains is scope, not mechanism. README statuses follow. drivers.md
gains the driver-contract section (harness, hello, crash-freely). The
M19-M20 plan pre-settles three things the loop would otherwise have had
to decide alone: the memory-map pass-through for apertures, the manager
spawning 'discovery' from M20.1, and hid[8] riding ChildAdded for ACPI
string identity until the FDT widening.
2026-07-13 01:49:52 +01:00
Daniel Samson 77901bbba6
WIP: USB 2026-07-12 22:24:47 +01:00
Daniel Samson 1bf91115dd
Generalize input module to mouse and joystick/gamepad events
Extend the input service beyond the keyboard so mouse and joystick/gamepad
drivers can broadcast too, with per-device publish and subscribe methods.

- protocol: KeyEvent joins MouseEvent (motion/buttons/scroll) and
  JoystickEvent (axes/buttons), all carried in a common InputEvent envelope
  tagged with a DeviceKind. A subscribe request carries a device_mask, so a
  subscriber names the classes it wants and the service routes each event only
  to interested subscribers (a mouse-only listener never wakes for keystrokes).
- runtime: per-device publish methods (publishKeyboardEvent/publishMouseEvent/
  publishJoystickEvent) and subscribe helpers (subscribeKeyboard/Mouse/Joystick,
  each typed, plus subscribe(mask)/subscribeAll returning the tagged envelope).
- service: subscriber table gains a device_mask; broadcast routes by the
  event's device class.
- mouse driver now publishes (synthetic) mouse events like the keyboard driver;
  input-source cycles all three classes; input-test subscribes to all and only
  emits its "ok" marker once it has received one of each class — so the passing
  test proves per-device routing, not just delivery. Real HID decoding stays a
  follow-up.

No kernel changes: ipc_send is generic and the 36-byte InputEvent fits its
64-byte payload. Full QEMU suite 48/48; serial log confirms keyboard, mouse,
and joystick all reach one subscription.
2026-07-11 15:21:09 +01:00
Daniel Samson 65244e3103
Add input module: broadcast keyboard events over IPC
Programs can now subscribe to keyboard events (key_down/key_up/key_press)
and drivers can broadcast them, through a new user-space input service.

The delivery model is forced by danos IPC: a synchronous rendezvous holds
one pending reply, so a server cannot park N subscribers blocked in a
"wait for next event" call — delivery must be push. But a synchronous push
has no timeout and the kernel never wakes a sender parked on a dead peer's
endpoint, so one dying subscriber would hang all input. So this lands the
roadmap's planned asynchronous buffered send and builds the service on it:

- ipc_send (syscall 26): non-blocking post to an endpoint's bounded payload
  ring, delivered through reply_wait as a buffered message (notify_message_bit).
  A full ring drops the oldest. It can never hang on a dead/slow peer.
- input-protocol + runtime.input helpers (subscribe/next, connectSource/
  publish) — the first real consumer of M13 capability passing: a subscriber
  hands the service its own endpoint as a capability.
- input service (fan-out via ipc_send, dead-subscriber pruning), a synthetic
  input-source, and input-test; the ps2-bus keyboard driver publishes to it.
  Real IRQ1 scancode decoding (which must live in the bus, the PNP0303 owner)
  is a documented follow-up; the source is synthetic for now.
- build/init wiring, an `input` QEMU case, and docs/input.md.

Full QEMU suite 48/48, including the new input case and every IPC/endpoint
regression (ipc, ipc-call, ipc-cap, vfs, hpet, bus, irqfree).
2026-07-11 15:03:24 +01:00
Daniel Samson d218d93f79
Add process management: enumerate, supervisor-gated kill, exit notifications
process_enumerate snapshots the task table (the device_enumerate shape, so
ps is a user program); system_spawn returns the child id, records the caller
as supervisor, and takes an exit endpoint; process_kill is allowed only for
the supervisor. Every death — exit, fault, or kill — posts a child-exit badge
to that endpoint (the IRQ-as-IPC pattern as SIGCHLD). A target caught off-CPU
is reaped in place; a running one is condemned and finished at its next
system call or tick, guarded so teardown never lands mid-kernel-operation.
Tested by process-list, process-kill, and supervision (a ring-3 supervisor
exercising the whole surface); design notes in docs/process-management.md.
2026-07-11 09:32:25 +01:00
Daniel Samson 3ec2d1828a
docs: abi is the kernel↔runtime contract, not spoken by applications
Correct the abi.zig header (and the matching build.zig / README lines): the syscall ABI
is the private contract between the kernel and the runtime library, not something every
user program speaks. danos applications call the `runtime` (the stable, danos-native
ABI); the runtime is the only thing that issues system calls, and POSIX layers over the
runtime — the same split as libSystem on macOS or win32 over the NT syscalls. The call
numbers here are an implementation detail the runtime hides and may renumber, not a
public interface.
2026-07-10 20:38:41 +01:00
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
Daniel Samson 47610e8ee2
Device manager (increment 1): discover + match
The device manager is the ring-3 process that turns the device tree into a running
system — the udev-analog. It is mechanism-vs-policy done right: the kernel
enumerates the hardware and enforces the claim capability; this decides which
driver serves which device, using no special privilege (the same device_enumerate
any process could call).

This first increment does the discovery + matching half: system/services/
device-manager enumerates /system/devices, matches each device to a driver by
class (a small static policy table), and logs the decision — finding the HPET
(a timer) and deciding `hpet` serves it. It does not spawn yet: spawning needs a
`system_spawn` system call (the kernel spawns every initial-ramdisk binary in a
loop today), which is the next increment. New `device-manager` test; suite 36/36
plus host tests.
2026-07-10 14:20:14 +01:00
Daniel Samson d19a0ae38d
Rename the shared contract module danos -> system; QEMU logs to /var/log/system
The shared kernel<->user ABI contract (BootInformation, the SystemCall numbers,
DeviceDescriptor, page_size, ...) is now the `system` module at
system/system.zig, following the convention that a directory's root file takes
the directory's name.

One overlap to note: the runtime's syscall wrappers are already `runtime.system`,
so the single file that uses both the contract and those wrappers
(library/runtime/heap.zig) aliases the wrappers locally as `system_calls`. The
two are distinct (top-level `system` vs `runtime.system`); everywhere else the
contract is just `system`.

Also: the QEMU run's serial capture now lands in the FHS log location,
zig-out/var/log/system/serial0-<timestamp>.log — a stand-in for the kernel's own
logging system, which will eventually write there itself.

Suite 35/35 plus host tests green.
2026-07-10 14:09:38 +01:00
Daniel Samson 3d1de37d0e
Make zig-out a FHS image, and the boot volume
`zig build` now installs into a FHS-shaped zig-out that *is* the danos filesystem
and the boot volume — no more zig-out/bin or a separate esp/:

  zig-out/EFI/BOOT/BOOTX64.efi        (firmware entry; UEFI fixes this path)
  zig-out/boot/initial-ramdisk.img
  zig-out/system/kernel               (the kernel binary)
  zig-out/system/services/init  vfs
  zig-out/system/drivers/hpet   bus

Binaries land at their addressed, leaf-collapsed paths per the sub-project
resolution rule (system/services/init/init.zig -> system/services/init); vfs, hpet,
and bus are installed to their FHS homes too, so the image is complete even though
at boot they arrive inside the initial-ramdisk.

The bootloader (boot/efi.zig) now loads each artifact from its FHS path
(system\kernel, system\services\init, boot\initial-ramdisk.img); run-x86-64 mounts
zig-out directly; the QEMU test harness assembles its ESP from the FHS zig-out.

Also renames system/kernel/main.zig -> kernel.zig so the kernel follows the
name/name.zig convention (kernel/ = ring-0 code, services/ = ring-3 OS services).
Documents the resolution rule in the repository-layout section (README + coding
standard). Suite 35/35 plus host tests green.
2026-07-10 13:57:02 +01:00
Daniel Samson ceacc6b514
Post-reorg cleanup: POSIX layer, and naming fixes
Follow-up to the monorepo re-org. Suite 35/35 plus host tests green.

POSIX compatibility is now its own library, library/posix/ (unistd, stdio),
layered strictly over the runtime — it calls the runtime's IPC/heap, never
system calls directly. The runtime is now POSIX-free (the danos-native
application ABI). The VFS wire protocol is danos-native throughout
(Stat -> FileStatus, .stat -> .status, O_CREAT -> create); the POSIX layer
maps the POSIX spellings at the boundary. The coding standard's ABI-name
exception is scoped to one place: a file is allowed POSIX spellings only if it
lives under library/posix/ — everywhere else, danos naming with no exception.

Naming fixes, all mechanical:
- initrd -> initial-ramdisk: the source file, the module, the tool
  (make-initial-ramdisk.py), the artifact (initial-ramdisk.img, including the
  bootloader's load path), and the identifiers.
- system/kernel/device-service.zig -> devices-broker.zig: it is ring-0 kernel
  code (the trusted device table + claim capability), not a ring-3 service. The
  future user-space device *manager* (policy) will live in system/services/.
- Dropped the daemon `d` suffix: hpetd -> hpet, busd -> bus. A driver lives in
  system/drivers/, so the folder already says what it is; encoding the role in
  the name too is redundant. The coding standard drops that exception.
- system/devices/aml/interp.zig -> interpreter.zig (the type was already
  Interpreter).
2026-07-10 13:33:06 +01:00
Daniel Samson 8754d4e46a
Re-organize the source tree as a monorepo mirroring the FHS
The source layout now mirrors the runtime filesystem hierarchy
(docs/danos-file-system-hierarchy-FSH.md): what lives under system/ in the
source is what a running danos represents under /system. Each service and
driver is a sub-project directory that is its own Zig module — cross-project
references go by module name, never by a path into another project's files.

Moves (all git mv, history preserved):
- src/            -> system/            (danos internals; the self-representation)
    root.zig      -> danos.zig          (the kernel<->user contract module)
    kernel/arch/  -> kernel/architecture/   (arch -> architecture)
    device/       -> devices/           (what /system/devices reflects)
    boot/         -> /boot              (the loaders, top level)
- sbin/           -> split by role:
    init, vfs     -> system/services/<name>/<name>.zig
    hpetd, busd   -> system/drivers/<name>/<name>.zig
    vfs-test      -> system/services/vfs/vfs-test.zig  (inside the vfs project)
- lib/            -> library/runtime/   (room for other libraries beside runtime)

The VFS wire protocol becomes its own module, system/services/vfs/protocol.zig
("vfs-protocol"): the vfs sub-project exposes its interface, and the runtime's
file layer imports it by name. First instance of the "protocol module" pattern
(docs/driver-model.md); usb/block will expose theirs the same way.

Also: fix a naming-standard violation in the protocol — Op -> Operation (and
req -> request, _pad -> _padding). Docs updated: /system/services added to the
FHS doc, a repository-layout section added to the docs index, and stale source
paths swept across comments and docs.

Runtime boot paths are unchanged (the bootloader still loads /sbin/init);
aligning the runtime filesystem to the FHS is a separate follow-up. Suite 35/35
plus host tests green.
2026-07-10 12:55:56 +01:00
Daniel Samson 15b70856c9
M11–M12: IRQ-as-IPC and bus drivers; expand names tree-wide
Two driver-model milestones plus a tree-wide naming pass. Suite 35/35
(QEMU) + host tests green.

M11 — IRQ-as-IPC. A ring-3 driver now sleeps until its device interrupts
it. New src/kernel/irq.zig: per-GSI endpoint bindings, comptime per-vector
trampolines, dispatch = mask GSI -> LAPIC EOI -> notifyLocked, all under one
lock region. irq_bind/irq_ack syscalls, gated by the device claim like
mmio_map. interruptDispatch no longer EOIs — each handler owns its EOI,
because a level line must be masked before it is acknowledged (irq_ack is
the unmask). Bindings are keyed on the owning task and released on exit
(a shared endpoint's siblings survive). hpetd rewritten interrupt-driven.
Tests: hpet (rewritten, reads back the I/O APIC routing) and irqfree.

M12 — bus drivers. DeviceDesc gains a parent, making the device table a
tree. dev_register (device_register) lets a process publish children below
a device it claimed; the kernel enforces resource containment (a child's
resources must nest in its parent's), so a descriptor can't fabricate a
window over kernel RAM. Descriptor copied in via copyFromUser (physmap
walk — an unmapped user pointer fails the call instead of faulting the
kernel). Per-parent child cap bounds table exhaustion. sbin/busd.zig is a
worked bus driver. Test: bus.

Naming — per docs/coding-standards.md: non-acronym abbreviations spelled
out (message, descriptor, device_service, scheduler, runtime, physical,
interpreter, ...); acronyms kept (IPC, MMIO, DMA, HCD, ...); files are
kebab-case (ipc-synchronous.zig, device-service.zig, vfs-protocol.zig, ...).
Exceptions: POSIX/C ABI names and Zig idioms (init/len/ptr) kept. Module
collisions resolved by specific naming (config -> parameters, device.zig
alias -> device_model). AML op/Op disambiguated: op = opcode, Op =
operation; per-opcode parse handlers renamed opX -> parseX.

New driver docs: drivers.md, driver-model.md (bus/class/HCD shapes + the
proposed M13–M16 ABI), coding-standards.md.
2026-07-10 11:39:56 +01:00
Daniel Samson 26d2f5259c
document the multi-sink logging model 2026-07-08 10:41:47 +01:00
Daniel Samson 2ee898a91e
add device platform module with ACPI support 2026-07-08 09:23:41 +01:00
Daniel Samson 6f6ccc8bc9 moving kernel code to kernel/ 2026-07-05 10:19:11 +01:00
Daniel Samson 7c3cffb337 moving efi code to boot 2026-07-05 10:01:01 +01:00
Daniel Samson d055de7141 documenting things to research 2026-07-03 21:40:59 +01:00
Daniel Samson a6de418e42 documenting smp and scheduling to research 2026-07-03 21:24:44 +01:00
Daniel Samson f9f0511ac2 documenting research for arm and device discovery 2026-07-03 20:22:48 +01:00
Daniel Samson 99d6bf5ce3 renaming run-efi to run-x86-64 2026-07-03 19:45:44 +01:00
Daniel Samson 31bf86af56 IPC 2026-07-03 15:09:16 +01:00
Daniel Samson df774691c8 Fixed-priority preemptive scheduler 2026-07-03 14:30:33 +01:00
Daniel Samson e80043b611 Calibrated timer / clock 2026-07-03 14:17:00 +01:00
Daniel Samson 269729f2f2 Built heap allocation 2026-07-03 13:41:55 +01:00
Daniel Samson 56219b4050 Documenting sysv 2026-07-03 13:06:27 +01:00
Daniel Samson 5ea521d054 Built device interrupts 2026-07-03 12:57:40 +01:00
Daniel Samson c8e89e8115 Cross-architecture test suite 2026-07-03 12:39:26 +01:00
Daniel Samson 9cf135302d Built paging / the kernel's own page tables (with a TSS+IST) 2026-07-03 12:23:55 +01:00
Daniel Samson 0cc71ec8aa Built GDT + IDT + exception handlers 2026-07-03 12:05:41 +01:00
Daniel Samson cb2f49cb48 added physical memory manager 2026-07-03 11:24:26 +01:00
Daniel Samson 628c4f6d57 Move to multi arch support and added memory map 2026-07-03 11:11:19 +01:00
Daniel Samson c2435760c4 Add README file in docs 2026-07-03 10:31:08 +01:00