SchOS/include/blkdev.h
Nexoniarz d7352c0db0 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
2026-10-22 10:57:41 +02:00

49 lines
2.3 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
// Block devices that are found rather than assumed.
//
// The first four device numbers are fixed and always were: IDE 0 and 1, the
// ramdisk, the first USB stick. Everything since -- a SATA disk behind AHCI,
// an NVMe namespace, and every partition on any of them -- registers here at
// probe time and is handed the next free number from BLKDEV_FIRST.
//
// A partition is a block device in its own right, with block 0 at its first
// sector. That is the whole of partition support from a filesystem's side:
// SchFS on /dev/sata0p2 sees a volume that starts at zero, exactly as it would
// on a whole disk, and needs to know nothing about GPT -- which is also what
// a Linux driver for SchFS will see when it is handed /dev/sda2.
#define BLKDEV_FIRST 4
#define NBLKDEV 16 // so device numbers stay below SCHFS_DEV (64)
// The GPT partition type of a SchFS volume, as it is written and printed:
// 47138FA9-B79C-47A6-9F7D-AC1F7F572D5E. sgdisk and fdisk accept it as is.
// Generated for SchFS on 2026-10-22; nothing else uses it.
#define SCHFS_GPT_TYPE "47138FA9-B79C-47A6-9F7D-AC1F7F572D5E"
// What a driver supplies. `rw` moves `count` of the device's own sectors at
// `lba` to or from `buf`, a kernel address; it is never asked for more than
// BSIZE bytes at once. Returns 0, or -1 if the device refused.
struct blkdev_ops {
int (*rw)(void *priv, uint64 lba, uint32 count, void *buf, int write);
int (*flush)(void *priv); // 0 when there is nothing to flush
};
// Register a whole disk. Its partition table, if it has one, is read here and
// every partition registered after it. Returns the disk's device number, or
// -1 if the table is full.
int blkdev_register(const char *name, const struct blkdev_ops *ops,
void *priv, uint64 nsectors, uint32 secsize);
int blkdev_present(uint dev);
void blkdev_rw(struct buf *b);
int blkdev_flush(uint dev);
// For the root probe: the registered devices in order, partitions after the
// disk they are on. Returns the device number of the i'th, or -1 past the end.
int blkdev_nth(int i);
const char *blkdev_name(uint dev);
int blkdev_is_schfs(uint dev); // a partition typed SCHFS_GPT_TYPE
int blkdev_info(char *buf, int cap); // /proc/partitions