subverge

Disk layout

What install writes, sector by sector, with no partitions or filesystem. Useful with a hex editor and a disk image.

The map

Sectors are 512 bytes.

LBA 0           MBR
LBA 1-16        stage 2
LBA 64          the kernel, as many sectors as it needs
LBA 4096        the state header, "SVSTATE1"
LBA 4097        slot 0, root, 2048 sectors
LBA 6145        slot 1, tab 1
LBA 8193        slot 2, tab 2
LBA 10241       slot 3, tab 3
LBA 12289       slot 4, tab 4
LBA 14337       the end of everything Subverge uses

About 7 MiB in all. install refuses any drive smaller than 8M. Anything past the end is ignored.

The kernel gets the sectors from 64 up to 4095, which is just under 2 MiB. If a kernel you've built doesn't fit, install fails with the kernel doesn't fit in its slot. The current one is under a megabyte.

The kernel copy

install doesn't write the running kernel. At boot, before anything else runs, the kernel copies its own .data section aside, and install writes the code from memory followed by that untouched copy of the data. So an installed kernel boots fresh, without whatever state the live system had built up, and without anything you poked into it.

The state header

One sector at LBA 4096:

Offset Size Field
0 8 SVSTATE1
8 5 × 4 the length in bytes of each slot's contents
28 5 × 4 an FNV-1a checksum of each slot's contents
48 8 how many saves have ever happened
56 padding to 512

If the magic is wrong, the header is treated as empty, and every slot as unused. When a slot is saved, its data is written first and the header second, so a save interrupted halfway leaves the old header pointing at a slot whose checksum no longer matches, and that slot is ignored at the next boot rather than loaded half-written.

The slots

Each slot is 2048 sectors, 1 MiB, and holds plain omega source with a zero byte after it, padded to a whole sector. Slot 0 is root, every unit after its #>> name line. Slots 1 to 4 are the worlds of tabs 1 to 4. See saving for what's in them and when they're written.

A slot whose length is 0, too big, or whose checksum doesn't match is treated as empty.

Finding the home drive

At boot the kernel reads sector 1 of each of the four IDE drives, and the first one with SUBVERGE at byte 8 is home. If two drives both have Subverge installed, the first one wins, and the other one is just a disk.

Looking at it

On the host, with the VM shut down:

$ dd if=disk.img bs=512 skip=4096 count=1 | xxd | head -4
$ dd if=disk.img bs=512 skip=6145 count=4 | strings

shows you the header and the start of tab 1's world. Don't write to the image while QEMU has it open.