feat(boot): the loader tells the kernel its boot disk; system=v3 is refused on a stick

uefi.h: the UEFI device path and Block I/O protocols, a typed LocateDevicePath, and BootDisk
{gpt, is_stick, disk_guid[16]} appended to BootInfo after args (boot_info_offsets.h unchanged).
The loader, before ExitBootServices, cuts its image's device path at the partition's HardDrive
node, locates the whole disk's Block I/O (whole path consumed, not a logical partition, 512-byte
blocks), reads it as 1 KiB blocks through a loader-side blkio adapter, and runs the kernel's own
gpt_read: is it a StarshipOS stick (identity and Artemis partitions), and its DiskGUID
(gpt_disk_guid, new). No HardDrive node (an ISO/CD boot), no GPT, or any failure: not a stick.
Monolithic builds only (the non-monolithic loader does not link gpt.c, and does not build today:
kernel/src/vm/vm_core.c -- reported, not fixed).

The kernel prints 'Boot disk: a StarshipOS stick' or '... not a StarshipOS stick', and on a stick
system=v3 gives 'System: v3 is not on this stick -- StarForth v4' and boots v4.

Tests: stick_v3 (new), stick_boot and zuse x3 failed on the new lines before, pass after; v3_keys
still boots v3 off a stick. Acceptance: amd64, aarch64, riscv64 to [zuse@Hera] ok>, POST 538/538,
dict_hash 0xfec8c47cfc6f437f; v4 suite and test-32 0 failures.

Plan: docs/v4.0.0/plans/2026-10-27-stick-4-one-disk.md, Task 3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-28 12:08:48 -04:00
co-authored by Claude Opus 5.5
parent a321c537f7
commit 1b45f5f85f
34 changed files with 20202 additions and 5 deletions
+4
View File
@@ -29,6 +29,10 @@ typedef struct {
* Reads only. */
int gpt_read(blkio_dev_t *disk, gpt_part_t *parts, unsigned max, unsigned *count);
/* The DiskGUID (header bytes 56..71, as on disk) of the last gpt_read that
* returned GPT_OK: which disk it was, so a stick can be told from another. */
void gpt_disk_guid(uint8_t guid[16]);
/* The index of the first partition of `type`, or -1. */
int gpt_find(const gpt_part_t *parts, unsigned count, const uint8_t type[16]);
+73 -1
View File
@@ -264,6 +264,26 @@ typedef EFI_STATUS (EFIAPI *EFI_LOCATE_PROTOCOL)(
void **Interface
);
/* Device path (UEFI 2.x 10.2): a list of nodes, each a 4-byte header
* (Type, SubType, Length little-endian) followed by its data, ending in an
* End node (Type 0x7F, SubType 0xFF). */
typedef struct {
UINT8 Type;
UINT8 SubType;
UINT8 Length[2];
} EFI_DEVICE_PATH_PROTOCOL;
#define EFI_DEVICE_PATH_TYPE_MEDIA 0x04
#define EFI_DEVICE_PATH_SUBTYPE_HARDDRIVE 0x01
#define EFI_DEVICE_PATH_TYPE_END 0x7F
#define EFI_DEVICE_PATH_SUBTYPE_END_ENTIRE 0xFF
typedef EFI_STATUS (EFIAPI *EFI_LOCATE_DEVICE_PATH)(
EFI_GUID *Protocol,
EFI_DEVICE_PATH_PROTOCOL **DevicePath,
EFI_HANDLE *Device
);
typedef EFI_TPL (EFIAPI *EFI_RAISE_TPL)(
EFI_TPL NewTpl
);
@@ -302,7 +322,7 @@ typedef struct _EFI_BOOT_SERVICES {
void *Reserved;
void *RegisterProtocolNotify;
EFI_LOCATE_HANDLE LocateHandle;
void *LocateDevicePath;
EFI_LOCATE_DEVICE_PATH LocateDevicePath;
void *InstallConfigurationTable;
/* Image Services */
@@ -463,6 +483,44 @@ typedef struct {
static const EFI_GUID EFI_LOADED_IMAGE_PROTOCOL_GUID =
{0x5B1B31A1,0x9562,0x11d2, {0x8E,0x3F,0x00,0xA0,0xC9,0x69,0x72,0x3B}};
static const EFI_GUID EFI_DEVICE_PATH_PROTOCOL_GUID =
{0x09576e91,0x6d3f,0x11d2, {0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b}};
/* Block I/O (UEFI 2.x 13.9): the boot disk read whole, before ExitBootServices
* (docs/v4.0.0/plans/2026-10-27-stick-4-one-disk.md, Task 3). */
static const EFI_GUID EFI_BLOCK_IO_PROTOCOL_GUID =
{0x964e5b21,0x6459,0x11d2, {0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b}};
typedef struct {
UINT32 MediaId;
BOOLEAN RemovableMedia;
BOOLEAN MediaPresent;
BOOLEAN LogicalPartition;
BOOLEAN ReadOnly;
BOOLEAN WriteCaching;
UINT32 BlockSize;
UINT32 IoAlign;
UINT64 LastBlock;
} EFI_BLOCK_IO_MEDIA;
struct _EFI_BLOCK_IO_PROTOCOL;
typedef EFI_STATUS (EFIAPI *EFI_BLOCK_READ)(
struct _EFI_BLOCK_IO_PROTOCOL *This,
UINT32 MediaId,
UINT64 Lba,
UINTN BufferSize,
void *Buffer
);
typedef struct _EFI_BLOCK_IO_PROTOCOL {
UINT64 Revision;
EFI_BLOCK_IO_MEDIA *Media;
void *Reset;
EFI_BLOCK_READ ReadBlocks;
void *WriteBlocks;
void *FlushBlocks;
} EFI_BLOCK_IO_PROTOCOL;
static const EFI_GUID EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID =
{0x0964e5b22,0x6459,0x11d2, {0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b}};
@@ -635,6 +693,14 @@ typedef void (EFIAPI *EFI_RESET_SYSTEM)(
/* ---- BootInfo extension ------------------------------------------------ */
#include "kernel_args.h"
/* The boot disk, as the loader found it. All zero when the firmware gave
* no whole-disk Block I/O for it (an ISO or CD boot) or it has no GPT. */
typedef struct {
uint8_t gpt; /* its GPT read GPT_OK */
uint8_t is_stick; /* it has a StarshipOS identity and a StarshipOS Artemis partition */
uint8_t disk_guid[16]; /* the GPT header's DiskGUID, as on disk */
} BootDisk;
/* Boot Info Structure (passed to kernel) */
typedef struct {
EFI_MEMORY_DESCRIPTOR *memory_map;
@@ -656,6 +722,12 @@ typedef struct {
/* Parsed boot command-line arguments */
KernelArgs args;
/* The disk the loader was booted from (appended after args, so
* boot_info_offsets.h is unchanged): filled before ExitBootServices
* from the boot disk's GPT, read with the kernel's own gpt.c
* (docs/v4.0.0/plans/2026-10-27-stick-4-one-disk.md, Task 3). */
BootDisk boot_disk;
} BootInfo;
#endif /* STARKERNEL_UEFI_H */