B1 — kernel con disco+FS: linux.toml añade VIRTIO_BLK/VIRTIO_PCI/VIRTIO_NET/EXT4_FS
built-in (=y, sin módulos), aditivo al path initramfs. B2 — infra de disco:
- scripts/disk-image.sh: empaqueta un rootfs como imagen ext4 booteable con
`mke2fs -d` bajo `unshare -r` (archivos root-owned sin sudo, como el cpio
--owner=root:root; evita EACCES en el copy-up de overlay del rebuild).
- scripts/drive-rebuild.py: modo DISK= ⇒ QEMU monta la imagen como virtio /dev/vda
y el kernel arranca con `root=/dev/vda rw rdinit=/sbin/init` — sin initramfs.
Verificado en QEMU/KVM: el kernel monta /dev/vda ext4 como root REAL y arje-zero
arranca como PID 1 DIRECTO, sin el hack /init+switch_root (el muro pivot_root del
path initramfs desaparece por construcción: / ya es un mount pivotable).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
54 lines
3.0 KiB
Bash
Executable File
54 lines
3.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# disk-image.sh — Etapa B (imagen en disco real): empaqueta un rootfs como imagen ext4 booteable de
|
|
# disco virtio (/dev/vda) en vez de initramfs. Con un kernel que trae VIRTIO_BLK+EXT4 built-in
|
|
# (recipes/linux.toml), QEMU monta la imagen como root REAL y el kernel arranca con
|
|
# `root=/dev/vda rw rdinit=/sbin/init` — sin initramfs, sin el wrapper /init+switch_root: `/` ya es un
|
|
# mount ext4 pivotable (el muro pivot_root del path initramfs desaparece por construcción).
|
|
#
|
|
# `mke2fs -d <dir>` puebla la imagen DESDE un directorio sin montar nada y sin root (e2fsprogs >= 1.43).
|
|
#
|
|
# Uso:
|
|
# ./scripts/disk-image.sh # crea work/hammer-disk.img desde work/builder-rootfs
|
|
# BOOT=1 KERNEL=<bzImage> KVM=1 ./scripts/disk-image.sh # además bootea y corre rebuild-stage1
|
|
#
|
|
# Variables:
|
|
# ROOTFS dir rootfs a empaquetar (default work/builder-rootfs, lo arma selfhost-verify)
|
|
# IMG imagen de salida (default work/hammer-disk.img)
|
|
# SIZE tamaño de la imagen (default 6G; el rootfs ronda ~2G + holgura para el rebuild)
|
|
# BOOT 1 ⇒ bootea con drive-rebuild.py tras crear la imagen
|
|
# KERNEL bzImage con VIRTIO_BLK+EXT4 (requerido si BOOT=1)
|
|
# KVM/MEM/NET passthrough a drive-rebuild.py
|
|
set -eu
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
cd "$ROOT"
|
|
|
|
ROOTFS="${ROOTFS:-work/builder-rootfs}"
|
|
IMG="${IMG:-work/hammer-disk.img}"
|
|
SIZE="${SIZE:-6G}"
|
|
|
|
[ -d "$ROOTFS" ] || { echo "no existe ROOTFS: $ROOTFS (corré selfhost-verify para armar el builder)" >&2; exit 1; }
|
|
[ -x "$ROOTFS/sbin/init" ] || [ -L "$ROOTFS/sbin/init" ] || { echo "ROOTFS sin /sbin/init (arje-zero)" >&2; exit 1; }
|
|
|
|
echo "==> rootfs : $ROOTFS ($(du -sh "$ROOTFS" | cut -f1))"
|
|
echo "==> imagen : $IMG ($SIZE, ext4, label hammer-root)"
|
|
rm -f "$IMG"
|
|
# Ownership root en la imagen (igual que el `--owner=root:root` del cpio): el rebuild usa bwrap+overlay
|
|
# con un userns que mapea 0→0; si los ficheros van con el uid del host (1000) el copy-up falla EACCES.
|
|
# `unshare -r` mapea nuestro uid→0, así los ficheros uid-1000 se ven como root y mke2fs escribe uid 0
|
|
# en la imagen — sin sudo. mke2fs -d puebla desde el dir sin montar. Fallback a mke2fs directo si no hay
|
|
# unshare (la imagen quedaría uid-host: bootea y da shell, pero el rebuild fallaría en el copy-up).
|
|
if command -v unshare >/dev/null 2>&1 && unshare -r true 2>/dev/null; then
|
|
unshare -r mke2fs -q -t ext4 -L hammer-root -d "$ROOTFS" "$IMG" "$SIZE"
|
|
else
|
|
echo " (sin unshare -r: imagen con uid del host; el rebuild in-VM podría fallar el copy-up)" >&2
|
|
mke2fs -q -t ext4 -L hammer-root -d "$ROOTFS" "$IMG" "$SIZE"
|
|
fi
|
|
echo "==> imagen creada: $(du -h "$IMG" | cut -f1)"
|
|
|
|
if [ "${BOOT:-0}" = 1 ]; then
|
|
[ -n "${KERNEL:-}" ] || { echo "BOOT=1 requiere KERNEL=<bzImage con VIRTIO_BLK+EXT4>" >&2; exit 1; }
|
|
echo "==> booteando de disco (root=/dev/vda, sin initramfs ni switch_root)"
|
|
DISK="$IMG" KERNEL="$KERNEL" KVM="${KVM:-0}" MEM="${MEM:-6144}" NET="${NET:-1}" \
|
|
python3 scripts/drive-rebuild.py
|
|
fi
|