storage: AHCI, GPT/MBR partitions, and a disk a PC can boot
q35 stopped with "no root filesystem" because its disk is SATA, like every PC since 2008, and SchOS only had IDE. And SchFS could only sit on a whole raw device, so nothing could boot from a disk that also carried an ESP. - include/blkdev.h, kernel/dev/blkdev.c: a registry of block devices found at probe time, numbered from 4. A disk's GPT (or MBR) is read when it registers, and each partition becomes a device whose block 0 is the partition's first sector. SchFS needs no format change to live in a partition; a Linux SchFS driver will see the same bytes on /dev/sdX2. SchFS has its own GPT type: 47138FA9-B79C-47A6-9F7D-AC1F7F572D5E. - AHCI driver, written from the AHCI 1.3.1 spec: BIOS handoff, COMRESET when the link is down, IDENTIFY, 48-bit DMA read/write, FLUSH. Completion is polled, so the root disk does not depend on interrupt routing. - USB sticks also register as usb0, so their partitions are found. - The root probe tries registered devices between USB and IDE, SchFS-typed partitions first. - make disk / tools/posix/mkdisk.sh: a GPT image with a 64 MB ESP and a SchFS partition, ready to dd to a stick or a disk. Tested in QEMU q35: the old two-disk setup roots on sata1; disk.img as the only SATA disk roots on sata0p2; disk.img as a USB stick (firmware boots from it) roots on usb0p2. Writes survive sync in each case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HH7xukt4aaiGj1nQEAoQf1
This commit is contained in:
parent
7e8d5e2821
commit
d7352c0db0
10 changed files with 1027 additions and 17 deletions
|
|
@ -447,12 +447,28 @@ what makes a loop over candidates legal at all.
|
|||
|---|---|---|
|
||||
| 1 | `RAMDISK_DEV` | only in a `RAMDISK_ROOT` build, where it is an explicit choice |
|
||||
| 2 | `USBDISK_DEV` | a stick that is plugged in was plugged in on purpose |
|
||||
| 3 | IDE 1 | what the old constant named |
|
||||
| 4 | IDE 0 | usually the ESP, so usually not SchFS |
|
||||
| 3 | registered partitions typed SchFS | labelled that way on purpose |
|
||||
| 4 | every other registered device | whole disks, untyped and MBR partitions |
|
||||
| 5 | IDE 1 | what the old constant named |
|
||||
| 6 | IDE 0 | usually the ESP, so usually not SchFS |
|
||||
|
||||
The **registered** devices are the ones found at probe time rather than known
|
||||
at build time, numbered from 4 (`include/blkdev.h`): a SATA disk behind AHCI
|
||||
(`sata0`), the USB stick seen a second time (`usb0`), and every partition on
|
||||
either (`sata0p2`, `usb0p2`). When a disk registers, its GPT is read, or its MBR
|
||||
if it has no GPT. Each partition then becomes a device whose block 0 is the
|
||||
partition's first sector, so SchFS in a partition and SchFS on a whole disk are
|
||||
the same bytes. The ESP is skipped because it is FAT.
|
||||
|
||||
SchFS's GPT partition type is `47138FA9-B79C-47A6-9F7D-AC1F7F572D5E`.
|
||||
`make disk` builds `build/disk.img` (`tools/posix/mkdisk.sh`), a GPT disk with a
|
||||
64 MB ESP and a SchFS partition of that type. `dd` it to a stick or a disk, or
|
||||
give it to QEMU's q35 as the only disk. Both boot, the root comes up as
|
||||
`sata0p2` or `usb0p2`, and the q35 run is the same path a PC takes.
|
||||
|
||||
`iderw()` *panics* on an absent drive rather than failing, so each candidate is
|
||||
checked with `ide_disk_present()` / `usb_storage_present()` first. That is the
|
||||
whole reason those predicates exist.
|
||||
checked with `ide_disk_present()` / `usb_storage_present()` /
|
||||
`blkdev_present()` first. That is the whole reason those predicates exist.
|
||||
|
||||
When nothing matches, the panic names what it looked at, because "no root
|
||||
filesystem" with no list is the least useful thing a kernel can say at the one
|
||||
|
|
@ -590,9 +606,10 @@ in the one process that runs first.
|
|||
stall, which is the wrong order for finding out.
|
||||
- **`/proc/bootmode` is read once, at start.** A program that wants to be
|
||||
quieter or louder later has nowhere to say so, and nothing re-reads it.
|
||||
- **The root device is compiled in.** Booting from a USB disk needs the root
|
||||
device to be selectable, which it is not; the USB mass-storage driver works
|
||||
and a superblock reads back through `bread()`, but nothing can mount it.
|
||||
- **One USB disk, found at boot.** The mass-storage driver drives the first
|
||||
stick and no other, and a stick plugged in later is not seen. See
|
||||
[usb.md](usb.md).
|
||||
- **No NVMe yet.** SATA (AHCI) and IDE are the only fixed disks.
|
||||
- **`make ramroot` is the only way to boot with no data disk.** It links a
|
||||
filesystem image into the kernel binary, which costs boot time and carries a
|
||||
licensing constraint — see [../licensing.md](../licensing.md) §4.
|
||||
|
|
|
|||
Loading…
Reference in a new issue