Files
takana/docs/13-release-engineering.md
T
sergioandClaude Opus 4.8 50960d3c38 Etapa E1: imagen de disco auto-booteable (GRUB BIOS), sin -kernel
Primer entregable de release engineering (SDD 13 nuevo): scripts/install-image.sh
produce una imagen GPT que se BOOTEA SOLA en QEMU (`-drive file=img`, sin
-kernel ni firmware extra) — SeaBIOS → MBR → GRUB → kernel del propio disco →
arje-zero PID 1. Capaz de arrancar en hardware real.

Layout: vda1=BIOS boot (ef02), vda2=/ (con /boot/bzImage + /boot/grub),
vda3=/store, vda4=/var/lib/hammer. Reusa el particionado sin-root de B3
(sfdisk + mke2fs -d bajo unshare -r + dd conv=sparse) y el wrapper /sbin/init.

GRUB instalado SIN root ni loop: grub-bios-setup sondea el disco físico del
host (/dev/nvme…, 660 root:disk) para adivinar el root device del dir -d y falla
sin privilegios. Lo reemplaza un patch binario determinista sobre la ABI estable
de GRUB i386-pc: grub-mkimage arma core.img; un script Python escribe core.img
en la BIOS boot partition y parchea los punteros (boot.img off 0x5c kernel_sector
→ LBA de core.img; core.img off 0x1F4 blocklist.start → resto de core.img),
con asserts de los valores por defecto (1 y 2) para fallar ruidoso si la ABI
cambia. boot.img va al MBR sin pisar la GPT protective (sólo 440 B).

Verificado in-VM (KVM, sin -kernel): SeaBIOS → GRUB 2.14 → Linux 6.16.12 →
vda1..4 detectadas, vda2 root + vda3/vda4 montadas por el wrapper (0 errores) →
arje-zero PID 1 + hammerd (store=/store journal=/var/lib/hammer/journal).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 13:29:47 -04:00

4.0 KiB
Raw Blame History

SDD 13 — Release engineering (Etapa E): imagen auto-booteable, instalador, mirror, upgrades

Estado: EN CURSO. Etapa E del roadmap (docs/10-roadmap.md, memoria distro-completion-roadmap). Es trabajo nuevo: las Etapas AD dejaron un sistema que (A) se orquesta, (B) bootea de disco particionado real, (C) tiene userland Rust-nativo y (D) atesta confianza. Falta convertir eso en algo que un tercero instale y arranque sin el host de dev: una imagen que bootea sola (sin qemu -kernel), un instalador a disco físico, un mirror del store y un camino de upgrade.

1. El gap concreto que abre la Etapa E

Hasta B3 la imagen de disco (scripts/disk-image.sh, GPT con /, /store, /var/lib/hammer dedicados) no se auto-bootea: el drive-rebuild.py la arranca con qemu -kernel <bzImage> -append root=/dev/vdaN — el kernel lo carga QEMU, no la imagen. Eso sirve para verificar el auto-alojamiento, pero un disco así no arranca en hardware real ni en una VM "normal": le falta un bootloader en el propio disco.

2. Decisión de bootloader: GRUB BIOS (i386-pc) ahora, UEFI después

  • GRUB BIOS (i386-pc) — ELEGIDO para el primer corte. QEMU trae SeaBIOS built-in ⇒ un disco con GRUB en el MBR + una BIOS boot partition (GPT type ef02) bootea con qemu-system-x86_64 -drive file=img sin firmware extra ni -kernel. Se instala en userspace, sin root ni loop: grub-mkimage arma core.img y grub-bios-setup escribe boot.img→MBR + core.img→partición BIOS sobre el fichero imagen (es I/O de bloques, no necesita montar). Los módulos de GRUB y el kernel van en /boot de la partición root, que mke2fs -d puebla desde un directorio.
  • UEFI (EFI-stub + ESP FAT) — diferido. El kernel ya trae CONFIG_EFI_STUB=y, pero (a) el host de dev no tiene firmware OVMF usable para verificar el arranque, y (b) poblar un ESP FAT sin root exige mtools (ausente). Camino futuro cuando haya OVMF + mtools (o se construyan): ESP con EFI/BOOT/BOOTX64.EFI = el bzImage (EFI-stub), cmdline por loader.conf/UKI.

3. Layout de la imagen instalable (GPT, BIOS)

/dev/vda1  BIOS boot (ef02, ~2 MiB, sin fs)   core.img de GRUB
/dev/vda2  /                ext4  [hammer-root]   + /boot/bzImage + /boot/grub
/dev/vda3  /store           ext4  [hammer-store]  artefactos CAS (inmutable)
/dev/vda4  /var/lib/hammer  ext4  [hammer-state]  estado mutable (journal, overlays)

Cadena de arranque: SeaBIOS → MBR (boot.img) → core.img (BIOS boot part) → lee (hd0,gpt2)/boot/grub/ grub.cfglinux /boot/bzImage root=/dev/vda2 rdinit=/sbin/init → wrapper /sbin/init monta vda3/vda4 → exec /usr/bin/arje-zero (PID 1). El wrapper es el mismo puente de B3 (arje todavía no lee fstab/cards de montaje por sí mismo).

scripts/install-image.sh produce esta imagen. Reusa la técnica de particionado sin-root de B3 (sfdisk + mke2fs -d bajo unshare -r + dd conv=sparse,notrunc) y añade la BIOS boot partition, el kernel en /boot, los módulos GRUB en /boot/grub/i386-pc y los pasos grub-mkimage/grub-bios-setup.

4. Piezas pendientes de la Etapa E (orden tentativo)

  • E1 — imagen auto-booteable (GRUB BIOS): primer corte (scripts/install-image.sh). Bootea en QEMU sin -kernel hasta la shell de arje-zero. Hoy empaqueta el builder rootfs (con toolchain); un product rootfs lean es refinamiento.
  • E2 — instalador a disco físico: un hammer install <device> que particiona un disco real y vuelca las tres particiones + GRUB (la misma lógica, apuntando a /dev/sdX en vez de un fichero).
  • E3 — mirror del store: servir/replicar /store content-addressed (BLAKE3) entre máquinas; el hash ES la dirección, así que un mirror es un CAS replicado + resolución por hash.
  • E4 — upgrades: aplicar un nuevo árbol Stage 1 sin reinstalar — atómico vía el modelo overlay + el journal (D), con rollback al árbol anterior.
  • E5 — ISO/medio de arranque: medio live para correr el instalador (xorriso/grub-mkrescue; herramental a construir).