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
|
|
@ -25,6 +25,7 @@
|
|||
#include "buf.h"
|
||||
#include "dma.h"
|
||||
#include "usb.h"
|
||||
#include "blkdev.h"
|
||||
|
||||
#define CBW_SIGNATURE 0x43425355 // "USBC"
|
||||
#define CSW_SIGNATURE 0x53425355 // "USBS"
|
||||
|
|
@ -332,6 +333,40 @@ usb_storage_dump(void)
|
|||
brelse(b);
|
||||
}
|
||||
|
||||
// The same disk, as the block device registry sees it: whole, as "usb0", and
|
||||
// with its partitions read and registered behind it. A stick written with
|
||||
// tools/posix/mkdisk.sh -- or by any installer -- keeps SchFS in a partition
|
||||
// next to its ESP, and the fixed USBDISK_DEV, which is the whole medium, can
|
||||
// never see it there.
|
||||
static int
|
||||
ums_blk_rw(void *priv, uint64 lba, uint32 count, void *buf, int write)
|
||||
{
|
||||
int n;
|
||||
(void)priv;
|
||||
if(count * SECTOR_SIZE > BSIZE || lba + count > ums.nsectors)
|
||||
return -1;
|
||||
acquiresleep(&ums.lock);
|
||||
if(write)
|
||||
memmove(ums.xfer, buf, count * SECTOR_SIZE);
|
||||
n = scsi_rw((uint32)lba, count, ums.xfer, write);
|
||||
if(n == (int)(count * SECTOR_SIZE) && !write)
|
||||
memmove(buf, ums.xfer, count * SECTOR_SIZE);
|
||||
releasesleep(&ums.lock);
|
||||
return n == (int)(count * SECTOR_SIZE) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
ums_blk_flush(void *priv)
|
||||
{
|
||||
(void)priv;
|
||||
return usb_storage_flush();
|
||||
}
|
||||
|
||||
static const struct blkdev_ops ums_blk_ops = {
|
||||
.rw = ums_blk_rw,
|
||||
.flush = ums_blk_flush,
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static int
|
||||
|
|
@ -407,6 +442,7 @@ storage_probe(struct usb_dev *dev)
|
|||
cprintf("usb-storage: %s %s, %d sectors (%d MB)\n",
|
||||
vendor, product, ums.nsectors,
|
||||
(int)((uint64)ums.nsectors * SECTOR_SIZE / (1024 * 1024)));
|
||||
blkdev_register("usb0", &ums_blk_ops, 0, ums.nsectors, SECTOR_SIZE);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
|
|
|||
Loading…
Reference in a new issue