Untitled
Day 30 evidence
Date: 2026-09-22
Source baseline
- Integrated-demo implementation commit:
07d63e7 - Final kernel binary SHA-256:
a5209e8fd220c64e3d7b3e3b2449d16e8f2f4e315db5562bc3e5c2a5390fc470 - Final kernel ELF SHA-256:
80a6d0825b79c0749d2cfa5951a42c334a30a7d64a0742bc4399ad77cb3bd45e - Final disk image SHA-256:
4c4a315af550ee8f38dd8c1fa5fd2c067d2a4077d28b793b67fc36edae5e48d2 DEMO.EXESHA-256:a246a279682e38bea0a2613800599f69d4dd54161b6e2bf2dc95dbe6ae1f5474- First/reset/fresh screenshot SHA-256:
aa1eb7b93da3ab1f61eb6a41ea2d3a7dc888e5c9595d08fc21262cd5939eeead
The Day 30 image is a separate final entrypoint. Historical images and their
test limits remain unchanged. The old process, fd and Shell demos still expose
four process slots; the final image exposes six so that the Shell, DEMO, two
COUNT children and BADPTR can coexist.
Environment
- QEMU 8.2.2 (
Debian 1:8.2.2+ds-0ubuntu1.18) - SeaBIOS 1.16.3 package image
- GDB 15.1
- GCC 13.3.0 and GNU Binutils 2.42
- NASM 2.16.01
- Machine:
pc-i440fx-7.2, TCG,qemu32, 1 CPU, 64 MiB
The unpacked tools under /tmp/build-an-os-tools are an execution dependency
of this environment and are not included in the attachment.
Specialized command
1 | |
Exit status: 0.
The command starts one QEMU process, runs the full scenario, issues QMP
system_reset, repeats it in the same process, then stops that process and
repeats in a new QEMU process. It removes the normal -no-reboot flag only for
this test because reset is the behavior under test.
Directory ABI and FAT-loaded programs
Day 30 adds syscall 12, readdir(index, entry). The kernel copies a fixed
16-byte entry containing a printable 8.3 name, attributes and a 32-bit size.
The FAT implementation still exposes only the fixed root directory and filters
deleted, long-name, volume-label and subdirectory entries. It remains read-only.
The final FAT image contains 13 visible files. LS.EXE is the existing Day 23
multi-call user executable dispatched as ls; DEMO.EXE is a separate 1212
byte ELF loaded through the same FAT/file/ELF path. The retained terminal log
contains:
1 | |
The final GDB checks observed fat_directory_files=13 and 16 directory-sector
reads. day30_demo_reads=3 records the ELF header/program-header/load reads;
it is an implementation observation, not a general lower bound for ELF files.
Fault order and surviving processes
DEMO.EXE creates two COUNT children and one BADPTR child. BADPTR faults on
address 0x00100000 with vector 14. The kernel snapshots both COUNT progress
values before publishing the BADPTR exit, waits until both values are larger,
and only then releases the counters. Each round produced ordered events:
1 | |
The fresh-process sample completed both events within one 100 Hz clock tick,
so it printed after-fault=0; its event sequence was still 1 < 2, and both
recorded progress values increased by one. Tick equality is therefore not used
as an ordering proof.
The terminal then showed:
1 | |
The successful command after DEMO proves that the Shell regained control. It
does not claim recovery from a kernel fault: the page fault belonged to a user
process and followed the existing process-isolation path.
Three-round replay
All three rounds reached the first prompt with the same saved user state:
1 | |
After exit, all rounds reported the same semantic terminal state:
1 | |
Each final breakpoint also asserted zero live open-file objects and references,
equal terminal produced/consumed bytes, two released terminal endpoints, at
least ten reaped processes, and equality between pre-UI and post-UI free-page
counts. Serial output ended with:
1 | |
The QMP transcript records the accepted hard reset and three screendump
requests. The HMP transcript records every injected key and mouse command. The
three screenshots are byte-identical because each round ends at the same fixed
terminal contents and cursor state.
Cumulative regression
After the specialized check, these current targets all exited zero:
1 | |
The combined receipt is docs/day30-cumulative.txt. The current run’s Shell
check passed on its first attempt. An earlier development run needed a rerun
because the older fd demonstration has a scheduling-sensitive observation;
that incident is not counted as a passing run, and the retained final sequence
is entirely green.
The repository-wide legacy make check is not reported as passing. Its Day 7
check-exceptions expectation predates vector 44 for IRQ12 and vector 128 for
the DPL3 syscall gate. The current cumulative list uses the maintained targets
for those later mechanisms instead of weakening the old check.
The source archive SHA-256 is
9c4a841efc8b6a51f9509586cdcd8889d8276ec9d8bcde9d7cdc4363e6dfbf3a.
It contains no build/ directory. A fresh extraction rebuilt the project and
passed the same 17-target sequence. kernel-final.bin, mbr-final.img and
day30-user.elf matched byte for byte. The debug kernel-final.elf hash differs
because DWARF records the absolute compilation directory; DW_AT_comp_dir
changed from the repository path to the temporary extraction path, while the
objcopied kernel binary remained identical. The external receipt is
docs/day30-zipcheck.txt and is intentionally not stored inside the archive.
Evidence boundary
- QMP
system_resetis a guest hard reset inside one QEMU process. The third
round uses a new QEMU process, but neither path validates a physical power
cycle or different firmware. - HMP key and mouse injection gives a deterministic device path. It is not a
subjective manual usability test and does not validate physical PS/2 or VGA
hardware. - The FAT layer remains a fixed, read-only FAT16 root with ASCII 8.3 names.
There are no subdirectories, long names, writes, persistence protocol or
crash recovery. - Six task slots are sufficient for the frozen final scene, not a scalable
process-table design. There is still one CPU, no SMP synchronization and no
dynamic task-table growth. - Equal counters and page totals at three fixed endpoints constrain leaks in
this scenario. They do not prove absence of every delayed or unexercised
lifetime bug.
