A boot printed about thirty lines before reaching a prompt. Every one was
useful once, and printed on every boot for ever they train the person in front
of the machine to stop reading their own console -- which is expensive on the
day one of them changes.
SchOS UEFI loader
Press F8 for boot options... booting
Welcome to SchOS! (F8 at boot for the full log, or dmesg once you are in)
root@schos / »
**Nothing was deleted, it was routed.** consputc() already wrote to the klog
ring before anywhere else, so a line can be kept in full while being held back
from the two places a person looks. kinfo() is cprintf() with that routing, and
`dmesg` still has the whole boot with timestamps afterwards. The rule for which
is which is not how interesting a line is -- everything was interesting to
somebody once -- but whether you would want to see it on a machine that is
*working*. `pci: 7 devices` is yes the first time and no every time after;
`e1000: no DMA memory for the rings` is yes for ever and stays a cprintf.
The verbose boot the F8 menu already offered now means something much bigger,
which is the other half of this: it is the only way to see any of it live.
Userspace follows through /proc/bootmode, one word. schinit, schinitd and vgpud
hold back their progress lines and never their failures -- a supervisor that
goes quiet when a job dies is worse than one that chatters.
Two things found by testing rather than by reading:
- schinit read /proc/bootmode *before* bootstrap() mounted /proc, so it got
"quiet" every time and the verbose boot was quiet in the one process that
runs first. It reads after the mount now.
- resolvconf announced "already exists; -f to replace it" on every boot after
the first, which is a line about having done nothing. It is quiet when the
file already says what it would have written, and speaks only when the two
disagree -- which means the nameserver changed and the machine is using the
old one.
Verified both ways: quiet boot is six lines, a forced-verbose build prints all
thirty plus the `verbose boot:` steps, and /proc/kmsg holds every line in both.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
find_rsdp() scanned the EBDA and 0xE0000-0x100000. That is a BIOS
convention, and UEFI firmware is under no obligation to leave a copy
there -- OVMF does not. So the kernel found no RSDP, no MADT and no
IOAPIC, and nothing routed IRQ 4. Serial output is polled, so the machine
booted all the way to a shell prompt and then ignored every key, which
reads as a broken console rather than a missing table.
The UEFI loader reads the RSDP out of the EFI configuration table,
preferring ACPI 2.0 for its XSDT, and leaves it at SCHBOOT_RSDP_ADDR --
the same low-memory hand-off block the e820 map already uses, now
described in include/schboot.h so the two sides cannot disagree.
The kernel validates it rather than trusting it: the BIOS path never
writes that slot, so there it holds whatever was in memory, and following
a wild pointer faults before there is anything to report the fault with.
Signature and checksum do that. It deliberately does not require 16-byte
alignment -- that rule is about searching the BIOS area, and OVMF's RSDP
sits at 0x3f77e014, so demanding it threw away the one address this code
exists to use.
UEFI now reports "acpi: 1 cpu, lapic at ..., ioapic id 0" and the ISO
boots to an interactive shell: uname, ls /bin (241), writing and reading
a file, ps, /proc/schfs -- all driven over serial.
BIOS unchanged: bootcheck 108 [ok], same ACPI line as before.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
An x86-64 operating system built from xv6, now largely rewritten: SMP,
a copy-on-write root filesystem (SchFS), PCI/USB/virtio drivers, a TTF
rasteriser, and a Linux-numbered syscall ABI.
No history before this point -- the tree was never under version control.
This commit exists so the rename that follows has something to undo to.