Pin zig version to 0.16 LTS

This commit is contained in:
Daniel Samson 2026-07-03 13:49:47 +01:00
parent 269729f2f2
commit 9a834c91ff
3 changed files with 73 additions and 1 deletions

1
.zig-version Normal file
View File

@ -0,0 +1 @@
0.16.0

View File

@ -2,7 +2,60 @@
Codename: Shodan
Version: 1
Operating System written for me
A small x86-64 operating system kernel, written from scratch in Zig. It boots 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, and a
kernel heap. 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.
- **OVMF** UEFI firmware — the `edk2-ovmf` package (Arch), `ovmf` (Debian/Ubuntu),
or `edk2-ovmf` (Fedora). The build defaults to the Arch paths
(`/usr/share/edk2/x64/OVMF_{CODE,VARS}.4m.fd`); override with `-Dovmf-code=` and
`-Dovmf-vars=` if your distro installs them elsewhere.
- **Python 3** — for the QEMU integration test harness.
## Build
```sh
zig build
```
Produces the UEFI bootloader (`zig-out/bin/BOOTX64.efi`) and the kernel ELF
(`zig-out/bin/danos`).
## Run
Boot it in QEMU with OVMF (opens a display window):
```sh
zig build run-efi
# distro with OVMF elsewhere:
zig build run-efi -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

View File

@ -1,6 +1,24 @@
const std = @import("std");
const builtin = @import("builtin");
/// danos is developed against Zig 0.16.x. Pre-1.0 Zig makes breaking API changes
/// between minor releases, and the .zon's `minimum_zig_version` only enforces a
/// floor so reject anything off the 0.16 line to keep the build reproducible.
fn ensureZigVersion() void {
const v = builtin.zig_version;
if (v.major != 0 or v.minor != 16) {
std.debug.print(
"danos requires Zig 0.16.x, but this is {d}.{d}.{d}. " ++
"Zig makes breaking changes between minor releases pre-1.0.\n",
.{ v.major, v.minor, v.patch },
);
std.process.exit(1);
}
}
pub fn build(b: *std.Build) void {
ensureZigVersion();
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});