Phase 205 — create first non-booting disk/root skeleton
At a glance
| Field | Value |
|---|---|
| Phase family | Phase 2 — bootable image |
| Run command | make phase 205 |
| Underlying make target/script | vm/phase2/build-image-skeleton.sh |
| Runs on | host with rootful loop/mount/filesystem work |
| Main proof/artifact | Creates artifacts/onix-image/onix.raw as a non-booting disk/root skeleton. |
Phase 205 is the first phase that creates the real future ONIX disk shape.
It takes this directory:
artifacts/onix-root-tree/
and creates this raw disk image:
artifacts/onix-image/onix.raw
This is a raw disk image, meaning it is just bytes arranged like a normal disk. QEMU can later attach it as a virtual disk.
Phase 205 is rootful because Linux only lets root do some disk operations:
losetup attach file as loop disk
sgdisk write partition table
mkfs.* create filesystems
mount mount filesystems
umount unmount filesystems
The script follows the same pattern as the forge disk builder: it starts as
your user, then re-execs itself through sudo only when root is needed. Run
make doctor or make phase 001 once if the passwordless builder rule needs
to be refreshed.
What Phase 205 creates
The generated image path is:
artifacts/onix-image/onix.raw
Default size:
12 GiB
The default partition plan is:
| # | Label | Filesystem | Size | Mount during assembly |
|---|---|---|---|---|
| 1 | ONIX-ESP | vfat | 512 MiB | /efi |
| 2 | ONIX-BOOT | vfat | 1 GiB | /boot |
| 3 | onix-root | xfs | 8 GiB | / |
| 4 | ONIX-PERSIST | xfs | rest | /persist |
The sizes can be overridden later with environment variables:
ONIX_IMAGE_SIZE
ONIX_IMAGE_ESP_SIZE
ONIX_IMAGE_BOOT_SIZE
ONIX_IMAGE_ROOT_SIZE
What a loop device is
The image is a normal file on the host:
artifacts/onix-image/onix.raw
But partitioning tools expect a block device, not a regular file.
Linux loop devices solve that. losetup temporarily presents the file as a
fake disk:
artifacts/onix-image/onix.raw
│
│ losetup
▼
/dev/loopX
Then partitions appear as:
/dev/loopXp1
/dev/loopXp2
/dev/loopXp3
/dev/loopXp4
When the phase finishes, it unmounts the filesystems and detaches the loop
device. The final artifact is only the .raw file.
What gets copied
Phase 205 mounts the onix-root partition and copies the root tree into it:
artifacts/onix-root-tree/ -> onix-root filesystem mounted at /
It uses tar with “do not preserve host owner” behavior so files inside the
image become root:root, not bresilla:bresilla.
That matters because this host-owned file:
artifacts/onix-root-tree/usr/lib/os-release
must become this root-owned file inside the image:
/usr/lib/os-release
What Phase 205 adds after the copy
The root tree has the main OS payload and mount points.
The disk assembly phase also creates persistent bind-source directories on the
ONIX-PERSIST partition:
/persist/home
/persist/nix
and ensures the root filesystem has the bind target:
/nix
That matches the default fstab lines:
/persist/home /home none bind
/persist/nix /nix none bind
What Phase 205 verifies
make phase 205 verifies:
- Phase 204 contract still passes
- GPT partition names are correct
- filesystem labels are correct
- filesystem types are correct
/usr/lib/os-releaseexists in the root filesystem- copied files are root-owned inside the image
/tmpis still mode1777/etc/fstabstill refers to the planned labels/persist/home,/persist/nix, and/nixexist- no EFI loader exists yet
The last check is intentional. If Phase 205 finds:
/efi/EFI/BOOT/BOOTX64.EFI
it fails, because that would mean we accidentally started bootloader work too early.
Why Phase 205 is still not bootable
A disk can have a correct root filesystem and still not boot.
To boot, it also needs things like:
kernel
initramfs
init system
bootloader
bootloader entries
kernel command line
Phase 205 avoids all of that on purpose. It proves only:
root tree -> real partitioned disk image
That keeps the debugging surface small. If Phase 205 passes, then a future boot failure is probably in the boot layer, not in the root-tree-copy layer.