SchOS/.claude/memory/schunix-iso-boot.md
Nexoniarz 85f0ebf802 memory: the installer is scoped, and the live CD is off the list
Records that a mountable ISO 9660 root was called off -- the ISO already
boots a complete system from the ramdisk, so it is the live environment
and an installer makes a mountable disc redundant, which drops the ATAPI
driver and ISO 9660 filesystem entirely.

Also records the installer's shape (both firmwares from the start, .sip
before anything installs), the five-stage dependency chain, and the 4 GB
limit the raw block device carries.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 22:20:20 +02:00

5.2 KiB

name description metadata
schunix-iso-boot `make iso` builds a bootable CD; it needs El Torito no-emulation plus ATAPI because the loader never uses INT 13h
node_type type originSessionId modified
memory project a665e14b-86bd-4b41-a228-51377f3e9225 2026-08-09T20:19:56.990Z

make iso produces a bootable schunix.iso (added 2026-08-04). Always a RAMROOT build — a disc that needed a second disk for its root would not be an install medium, and read-only media cannot host a writable root anyway.

Why it is built the way it is. Schunix's loader never calls INT 13h: it drives the IDE registers directly, and stage2 has already switched to protected mode before it reads the kernel. That rules out both El Torito emulation modes (hard-disk emulation exists only through the BIOS) and floppy emulation (2.88 MB cap). So:

  • boot/cdboot.S — a separate stage 1 for optical media. tools/mkiso.sh passes -boot-load-size 25, so the BIOS loads cdboot and all 24 sectors of stage2 before anything of ours runs, putting stage2 at 0x7E00 exactly where bootasm.S would have. cdboot only records the medium and jumps.
  • The medium flag is one byte past the verbose flag, at VBE_INFO_ADDR + 0x101. bootasm.S must clear it or a warm reboot from a disc sends a hard-disk boot looking for an optical drive.
  • stage2main.c gained an ATAPI reader (PACKET + SCSI READ(12), 2048-byte blocks with a one-block cache) and finds where it was loaded from by reading the El Torito boot catalog: LBA 17, pointer at offset 0x47, then Load RBA at catalog offset 40.
  • Do not pass -boot-info-table to xorriso — it patches 56 bytes over offset 8 of the boot image, which is the middle of cdboot's code. That is why the boot catalog is parsed instead.

The trap that cost the most time here: ATAPI's 0x14/0xEB signature is only valid until something issues a command, and the BIOS has just finished reading the disc to load us — so on a CD boot the signature is always stale. atapi_reset() (SRST via the control port at io + 0x206) is what makes the probe work.

Two unbounded waits were hiding behind that, both of which hung with no message on a machine with no ATA disk: waitdisk() in stage2main.c and idewait() in kernel/dev/ide.c. Both are bounded now, ideinit() tolerates an empty channel, and anything that probes a disk must call ide_disk_present() first — iderw() rightly panics on an absent drive.

Check it with pwsh -File tools/windows/bootcheck.ps1 -Iso -Fb, which boots with no hard disk attached at all. See schunix-verify-by-driving-shell.

2026-08-09: two boot entries, a real hierarchy, and a repair

The disc used to hold exactly one file (boot/schos.bin) with 8.3 uppercase names and a single El Torito entry. Now:

/boot/schos.bin BIOS entry, unchanged
/boot/efiboot.img UEFI entry: FAT image built with mtools
/EFI/BOOT/BOOTX64.EFI the loader, also a visible file
/bin /etc /usr ... the staged sysroot, as an ordinary tree
  • Rock Ridge + Joliet for real names, permissions and symlinks. Keep -cache-inodes: the sysroot is a toybox multicall binary with ~240 hard links to it, and without inode caching each link becomes its own copy — 28 MB becomes ~200 MB.
  • -isohybrid-gpt-basdat so dd to a stick boots under UEFI. UEFI only, and not an oversight: BIOS isohybrid needs syslinux's isohdpfx.bin, and even with it this loader reads the kernel over ATAPI, which a stick presented as a hard disk cannot serve. usbstick.img is the BIOS-from-USB answer.
  • The FAT image carries the kernel too. BOOTX64.EFI opens \schos\kernel on the volume it was loaded from, which for a UEFI boot is that FAT image and not the ISO 9660 tree. Without it the loader halts with EFI_NOT_FOUND. The kernel is therefore on the disc twice; the alternative is teaching the loader to search other volumes, which is a feature, not a packaging tweak.

make iso and make ramroot had been broken and nobody noticed. build/fs-ram.img was still built by the v1 mkfs while the kernel accepts only SchFS as root, so the ramdisk was a format it could not mount: schfs root: no SchFS volume on the root device, in forkret. It is an mkschfs image now, which needed --exclude added to mkschfs — dropping the exclude list was not an option, because the ramdisk is linked into the kernel binary and what goes into it is a licensing question (schunix-ramdisk-root-sizing). RAMDISK_NINODES is gone: SchFS has no preallocated inode table.

Not a live CD, and deliberately staying that way (decided 2026-08-09). The disc boots from the ramdisk embedded in the kernel, not from itself. Mounting it as root would need an ATAPI block driver (kernel/dev/ide.c speaks only ATA — 0x20/0x30/0xC4, no PACKET) plus an ISO 9660 filesystem behind struct fs_ops; only the bootloader does ATAPI, and only in real mode.

Nexoniarz called that work off: the ISO already boots a complete system from the ramdisk, so it is the live environment, and an installer makes a mountable disc redundant. The installer copies from the running root, so it never reads the disc as a filesystem at all. See schunix-roadmap-and-projects.