Not yet accepted (plan 2026-10-29-stick-5, Task 2, step 3). - gpt.c: the writer, gpt_grow_last() -- the backup entry array and header to the disk's end, the last partition to the last usable sector (whole MiB, capped), both headers' CRCs, the backup before the primary, the protective MBR's size; gpt_alternate_lba(). - sk_v4_grow.c: the volume grown to its partition -- its fence (the Artemis signature, Zuse's genesis marker) moved to the new top, the header last; the partition grown no further than the BAM tracks (the block subsystem places the fence by the device's size, so a volume must fill it). - sk_v4_identity.c: a stick of 8 GB or more whose GPT ends short of the disk is grown before its partitions are opened; "Artemis: grown to fill the stick" / "under 8 GB -- not grown" / "past 256 GiB ... left unused". - block_subsystem: blk_volume_compute_totals() (compute_totals_from_B, public) and blk_subsys_set_format_bam_for(); v3's behaviour unchanged. - mkartemis --bam-for, mkdiskimage.sh --bam-for, kernel/Makefile STICK_GROW_MIN_BYTES / STICK_ARTEMIS_CAP_GIB: the stick's and data stick's Artemis BAM sized for 256 GiB (6144 devblocks). STICK.md 5a: 256 GiB (R1). After: stick_grow PASS (16 GiB: 12129370 user blocks, 8 s POST to prompt; second boot not grown, recognised; sfdisk --verify: no errors), stick_small PASS, check_images.sh PASS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GE3SDvQn5EoxdGufk84zz2
72 lines
3.3 KiB
C
72 lines
3.3 KiB
C
/* gpt.h -- the GPT reader, and a block device of one partition.
|
|
* docs/v4.0.0/STICK.md 3 and 4; docs/v4.0.0/plans/2026-10-26-stick-2-gpt-reader.md.
|
|
*/
|
|
#ifndef STARKERNEL_GPT_H
|
|
#define STARKERNEL_GPT_H
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include "blkio.h"
|
|
|
|
/* The two StarshipOS partition types, as their GUIDs are on disk. */
|
|
extern const uint8_t gpt_type_starship_identity[16]; /* 23BEBFE1-4817-4CF3-A537-9069BF159788 */
|
|
extern const uint8_t gpt_type_starship_artemis[16]; /* BCD7B586-1C8E-4EEF-86A3-273A8D8EE624 */
|
|
|
|
typedef struct {
|
|
uint8_t type[16];
|
|
uint64_t first_lba;
|
|
uint64_t last_lba;
|
|
} gpt_part_t;
|
|
|
|
#define GPT_OK 0 /* a valid GPT */
|
|
#define GPT_NONE 1 /* not a GPT disk -- no protective MBR -- (or one whose sectors are not 512 bytes): read it raw */
|
|
#define GPT_BAD 2 /* a protective MBR, but its header or entry array does not check out: not used */
|
|
#define GPT_EIO 3 /* its first block could not be read: not used */
|
|
|
|
/* Read `disk`'s protective MBR, primary GPT header and partition-entry array,
|
|
* checking both CRC-32s, the revision, the sizes and the geometry. On GPT_OK,
|
|
* `*count` partitions with a non-zero type (at most `max`) are in `parts`.
|
|
* 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 backup header's LBA (header bytes 32..39) of the last gpt_read that
|
|
* returned GPT_OK: a disk whose backup header is not its last sector is larger
|
|
* than the table written to it. */
|
|
uint64_t gpt_alternate_lba(void);
|
|
|
|
/* Grow the partition of `type` -- which must be the disk's last -- to the end
|
|
* of `disk` (plan 2026-10-29-stick-5, Task 2): the backup entry array and
|
|
* header moved to the disk's last sectors, the partition's last LBA to the
|
|
* last usable sector before them (on a whole MiB, at most `max_part_sectors`
|
|
* long), both headers rewritten with their CRCs -- the backup first, so a
|
|
* write torn between them leaves the old primary valid -- and the protective
|
|
* MBR's size. GPT_OK with `*new_last_lba` the partition's last LBA (unchanged,
|
|
* and nothing written, when the backup header is already the disk's last
|
|
* sector); GPT_BAD or GPT_EIO otherwise. */
|
|
int gpt_grow_last(blkio_dev_t *disk, const uint8_t type[16], uint64_t max_part_sectors, uint64_t *new_last_lba);
|
|
|
|
/* 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]);
|
|
|
|
/* A partition as a block device: its block n is the disk's block
|
|
* first_fblock + n; blocks past fblocks are refused. */
|
|
typedef struct {
|
|
blkio_dev_t *disk;
|
|
uint32_t first_fblock;
|
|
uint32_t fblocks;
|
|
} gpt_part_dev_t;
|
|
|
|
/* Open `dev` as partition `p` of `disk`, its state in `st` (which must live
|
|
* as long as `dev`). BLKIO_EINVAL for a partition that does not start and end
|
|
* on a 1 KiB block, or that runs past the disk. */
|
|
int gpt_part_open(blkio_dev_t *dev, gpt_part_dev_t *st, blkio_dev_t *disk, const gpt_part_t *p);
|
|
|
|
/* CRC-32 (IEEE 802.3, reflected, polynomial 0xEDB88320), as GPT uses. */
|
|
uint32_t gpt_crc32(const void *buf, size_t len);
|
|
|
|
#endif /* STARKERNEL_GPT_H */
|