Etapa metal: kernel-metal (drivers reales =y) + firmware AX201 + ESTADO.md
Pieza 1+2 de 'hammer en el metal' (laptop TigerLake, WiFi AX201): - recipes/linux-metal.toml: variante del kernel con hardware real built-in (efifb/simpledrm, USB+HID, AHCI/NVMe, cfg80211+mac80211+iwlwifi/iwlmvm, e1000e/r8169, USB-CDC). Conserva los bits hammer (overlay/userns/fanotify/ virtio) ⇒ sigue booteando en QEMU. MODULES=off (monolítico, sin modprobe). Deja linux.toml INTOCADO (su of_tree es load-bearing del selfhost). - scripts/metal-firmware.sh: inyecta iwlwifi-QuZ-a0-hr-b0/cc-a0 + regulatory.db en /lib/firmware de un rootfs (descomprime .zst → .ucode plano). Blobs fijos (TODO pin a linux-firmware). - ESTADO.md: resumen humano del proyecto. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Semántico sayk'uy
Mana ima sutichaypas t'ikrakurqanchu: qillqalla, yachachiylla utaq willaylla t'ikrakurqan.
3 qillqakuna · +185 −0
- ESTADO.md +62 −0
- recipes/linux-metal.toml +77 −0
- scripts/metal-firmware.sh +46 −0
diff --git a/ESTADO.md b/ESTADO.md
new file mode 100644
index 00000000..796d4a1d
--- /dev/null
+++ b/ESTADO.md
@@ -0,0 +1,62 @@
+# ¿Dónde está hammer hoy? (mapa amigable)
+
+> Una foto en lenguaje humano de qué funciona, qué falta y por dónde seguir.
+> Fecha: 2026-06-22. Para el detalle de arquitectura, ver [`docs/`](docs/).
+
+## La idea en una frase
+
+`hammer` es una distro de Linux con dos pisos: un **sótano de laboratorio** que compila
+todo desde fuente de forma reproducible y guarda cada binario por su hash, y un **piso de
+arriba** clásico y mutable (un Linux normal con `/bin`, `/lib`, `/etc`) donde puedes romper
+cosas y revertir. Está pensada para que una **IA** entienda y modifique el sistema entero.
+
+## El semáforo: qué está listo
+
+| Pieza | Estado | En cristiano |
+|---|---|---|
+| 🟢 Núcleo del laboratorio | **Listo** | Compila aislado (bubblewrap + zig cc + musl), direcciona por hash BLAKE3 |
+| 🟢 Auto-hospedaje (self-host) | **Listo y verificado** | El toolchain se reconstruye a sí mismo *bit a bit* dentro de una VM |
+| 🟢 Kernel propio | **Listo** | Linux 6.16.12 compilado por nosotros, **arranca** la VM y se reproduce idéntico |
+| 🟢 Frente Rust/LLVM | **Cerrado** | Cadena pura mrustc → rustc 1.91.1, sin binarios ajenos de confianza |
+| 🟢 Paquetería `.swm` | **Listo (6/6 piezas)** | Empaquetar, repo firmado, instalar/desinstalar, deps, repo por red |
+| 🟢 Catálogo de software | **145 recetas** | Subió de 88 a 145 en una sola sesión (sobre todo CLIs de Rust) |
+| 🟡 Instalar en disco real | **En curso** | Imágenes EFI/ISO existen; falta pulir "instalar desde el live" |
+| 🟡 Userland Rust-nativo | **En curso** | coreutils/findutils de uutils ya construyen y corren |
+| ⚪ Distro instalable redonda | **Pendiente** | Las etapas B/D/E del roadmap |
+
+## Lo más importante que se logró
+
+1. **Soberanía del arranque.** No dependemos de binarios precocidos de nadie. Partiendo de
+ un compilador mínimo, hammer reconstruye su propio Rust, su propio kernel y sus propias
+ herramientas — y al hacerlo dos veces da **exactamente el mismo resultado** (reproducible
+ bit a bit). Eso se probó dentro de una máquina virtual, no solo en teoría.
+
+2. **Una "granja" de software que escala.** Hay un pipeline que toma recetas de `nixpkgs` y
+ Alpine, las adapta al formato de hammer, las compila y promueve las que funcionan al
+ catálogo. En esta sesión pasó de 88 a 145 paquetes, casi todo CLIs de Rust populares
+ (ripgrep, bat, fd, zoxide, helix, zellij, uv, ruff, biome…).
+
+3. **El "techo" actual es conocido.** Lo que frena más builds ya no es un misterio: es la
+ versión mínima de Rust que pide cada programa (MSRV) y los paquetes que arrastran C/C++
+ (`openssl`, `git2`). Subir el toolchain de 1.91.1 a 1.96 destrabó una tanda entera.
+
+## Por dónde sigue
+
+- **Escalar el catálogo a cientos** de paquetes con la cola ya pre-cargada
+ (`JOBS=4 scripts/build-farm.sh`).
+- **Terminar "instalar desde el live"**: que arrancar el ISO y darle a instalar deje un
+ sistema usable en disco (Etapa B del roadmap).
+- **Seguir reemplazando el userland** por equivalentes Rust-nativos (xargs es el próximo).
+- Pulidos opcionales: squashfs+overlay, arranque EFI fino, rollback al boot.
+
+## Para orientarte en el repo
+
+- `crates/` — el código de hammer (CLI, daemon, build lab, journal, overlay…).
+- `recipes/` — el catálogo (145 `.toml`); `recipes/incoming/` es la cola por procesar.
+- `scripts/` — orquestadores: `selfhost-verify.sh` (la prueba de fuego), `build-farm.sh`
+ (la granja), `import-batch.sh` (importa tandas), `rust-frontier/` (la cadena Rust pura).
+- `docs/` — el diseño completo (SDD); empieza por `00-vision.md` y `10-roadmap.md`.
+
+---
+*Este archivo es el resumen humano. El estado técnico denso vive en la memoria del proyecto
+y en los mensajes de commit (en español, granulares).*
diff --git a/recipes/linux-metal.toml b/recipes/linux-metal.toml
new file mode 100644
index 00000000..907c86ce
--- /dev/null
+++ b/recipes/linux-metal.toml
@@ -0,0 +1,77 @@
+# Linux kernel 6.16.12 — VARIANTE "METAL": booteable en hardware real (no sólo QEMU).
+#
+# Hermana de recipes/linux.toml (el kernel QEMU-tuned del selfhost-verify, INTOCADO: su of_tree es
+# load-bearing para la reproducibilidad bit-a-bit). Esta variante NO recorta el hardware; al revés, lo
+# habilita built-in (=y) porque el producto hammer es monolítico (arje-zero PID1, sin udev/modprobe en
+# el camino de boot ⇒ todo lo que haga falta para arrancar/ver/teclear/conectar debe ser =y, no =m).
+#
+# Target concreto: laptop TigerLake-LP (Intel Iris Xe + Wi-Fi 6 AX201 [8086:a0f0]), boot EFI.
+# - Pantalla: DRM_SIMPLEDRM + SYSFB_SIMPLEFB + FB_EFI (framebuffer del GOP de EFI; NO i915 → sin
+# firmware GuC/DMC/HuC, consola fbcon basta). i915/amdgpu/nouveau/radeon quedan OFF.
+# - Teclado: USB_HID + HID_GENERIC + i8042/atkbd (teclado integrado del portátil suele ser PS/2).
+# - Discos: AHCI/ATA + NVMe + USB_STORAGE + SCSI/sd (NVMe es lo más probable en TigerLake).
+# - WiFi: cfg80211 + mac80211 + iwlwifi + iwlmvm (AX201 usa el path mvm). El firmware
+# (iwlwifi-QuZ-a0-hr-b0-*.ucode, cc-a0-*) + regulatory.db NO van acá — son blobs no
+# compilables; se inyectan en /lib/firmware del rootfs (ver scripts/metal-firmware.sh).
+# - Red extra: e1000e/r8169/igb/igc/tg3 (Ethernet común) + USB-CDC/RNDIS (tether del celu) — baratos.
+# - Boot: EFI_STUB + EFI_PARTITION + VFAT (ESP) + ISO9660/Joliet (leer el medio live).
+#
+# Conserva TODO lo que hammer necesita (de linux.toml): E1000/OVERLAY_FS(+subfeatures)/USER_NS/
+# NAMESPACES/FANOTIFY/VIRTIO* ⇒ esta misma imagen sigue booteando en QEMU (para poder testear el boot
+# antes de quemar el USB). MODULES=off ⇒ monolítico puro (sin .ko que nadie cargaría).
+#
+# Compilador: CC=gcc/HOSTCC=gcc — MISMA decisión del gueto-GCC que linux.toml (zig cc choca con el
+# kbuild x86). Build ~45min (config ancha). Build-deps idénticos (flex/bison/m4/openssl/elfutils +
+# bootstrap-libs apk del bootstrap-devfs.sh).
+
+name = "linux-metal"
+version = "6.16.12"
+
+[source]
+tarball = "https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.16.12.tar.gz"
+sha256 = "ffc6af80b014ddebd55e116aa29a9f7a5256c87a29a8a9dd97270b6d49625109"
+
+[build]
+compiler = "zig-cc"
+target = "x86_64-linux-musl"
+link = "dynamic"
+
+[deps]
+build = ["flex", "bison", "m4", "openssl", "elfutils"]
+
+[build.phases]
+configure = """
+make ARCH=x86_64 defconfig && \
+scripts/config -d MODULE_SIG -d MODULE_SIG_ALL -d DEBUG_INFO_BTF -d DEBUG_INFO -d MODULES \
+ -d UNWINDER_ORC -e UNWINDER_FRAME_POINTER \
+ -e BLK_DEV_INITRD -e DEVTMPFS -e DEVTMPFS_MOUNT -e TMPFS \
+ -e OVERLAY_FS -e USER_NS -e NAMESPACES \
+ -e FANOTIFY -e FANOTIFY_ACCESS_PERMISSIONS \
+ -e OVERLAY_FS_REDIRECT_DIR -e OVERLAY_FS_INDEX -e OVERLAY_FS_XINO_AUTO -e OVERLAY_FS_METACOPY \
+ -e VIRTIO -e VIRTIO_PCI -e VIRTIO_BLK -e VIRTIO_NET -e EXT4_FS \
+ -e PCI -e PCIEPORTBUS -e ACPI \
+ -e SATA_AHCI -e ATA -e ATA_PIIX -e SCSI -e BLK_DEV_SD -e BLK_DEV_LOOP \
+ -e NVME_CORE -e BLK_DEV_NVME \
+ -e USB_SUPPORT -e USB -e USB_PCI -e USB_XHCI_HCD -e USB_XHCI_PCI \
+ -e USB_EHCI_HCD -e USB_EHCI_PCI -e USB_OHCI_HCD -e USB_UHCI_HCD -e USB_STORAGE \
+ -e HID -e HID_GENERIC -e USB_HID -e INPUT_EVDEV \
+ -e INPUT_KEYBOARD -e KEYBOARD_ATKBD -e INPUT_MOUSE -e MOUSE_PS2 \
+ -e SERIO -e SERIO_I8042 -e VT -e VT_CONSOLE \
+ -e DRM -e DRM_SIMPLEDRM -e SYSFB_SIMPLEFB -e FB -e FB_EFI \
+ -e FRAMEBUFFER_CONSOLE -e FRAMEBUFFER_CONSOLE_DETECT_PRIMARY \
+ -e EFI -e EFI_STUB -e EFI_PARTITION -e EFIVAR_FS \
+ -e VFAT_FS -e FAT_FS -e MSDOS_FS -e NLS_CODEPAGE_437 -e NLS_ISO8859_1 -e NLS_UTF8 \
+ -e ISO9660_FS -e JOLIET \
+ -e WLAN -e WIRELESS -e CFG80211 -e MAC80211 -e RFKILL \
+ -e WLAN_VENDOR_INTEL -e IWLWIFI -e IWLMVM \
+ -e ETHERNET -e NET_VENDOR_INTEL -e E1000 -e E1000E -e IGB -e IGC \
+ -e NET_VENDOR_REALTEK -e R8169 -e NET_VENDOR_BROADCOM -e TG3 \
+ -e USB_NET_DRIVERS -e USB_USBNET -e USB_NET_CDCETHER -e USB_NET_CDC_NCM -e USB_NET_RNDIS_HOST \
+ -d DRM_I915 -d DRM_AMDGPU -d DRM_NOUVEAU -d DRM_RADEON -d AGP \
+ -d SOUND -d SND -d MEDIA_SUPPORT -d INFINIBAND -d BT -d NFC -d CAN \
+ -d WATCHDOG -d THUNDERBOLT -d FIREWIRE \
+ -d XFS_FS -d BTRFS_FS -d F2FS_FS -d JFS_FS -d REISERFS_FS -d GFS2_FS -d NTFS3_FS && \
+make ARCH=x86_64 olddefconfig
+"""
+compile = "make ARCH=x86_64 CC=gcc HOSTCC=gcc -j\"$(nproc)\" bzImage"
+install = "mkdir -p /out/boot && cp arch/x86/boot/bzImage /out/boot/bzImage && cp .config /out/boot/config-6.16.12-metal"
diff --git a/scripts/metal-firmware.sh b/scripts/metal-firmware.sh
new file mode 100755
index 00000000..d7c9b7cc
--- /dev/null
+++ b/scripts/metal-firmware.sh
@@ -0,0 +1,46 @@
+#!/usr/bin/env sh
+# metal-firmware.sh — inyecta el firmware del WiFi AX201 (y reg.db) en /lib/firmware de un rootfs.
+#
+# El firmware de iwlwifi son BLOBS binarios NO compilables desde fuente (Intel no libera el código); la
+# soberanía de hammer (build-from-source) no aplica acá — son datos fijos como el microcódigo de la CPU.
+# Se fijan por contenido (igual que un tarball pinned): se copian de un linux-firmware ya presente y se
+# descomprimen a .ucode plano (el kernel metal NO habilita FW_LOADER_COMPRESS, así evitamos esa dep).
+#
+# Target: Intel Wi-Fi 6 AX201 [8086:a0f0] en TigerLake ⇒ familias QuZ-a0-hr-b0 + cc-a0 (el driver elige
+# la API más alta que soporta) + regulatory.db(+.p7s) que cfg80211 verifica con la clave built-in.
+#
+# Uso: scripts/metal-firmware.sh <rootfs-dir>
+# Vars: FWSRC dir origen del firmware (default /lib/firmware del host)
+#
+# TODO(soberanía): reemplazar FWSRC=host por un pin a un commit de linux-firmware (recipe fetch+extract).
+set -eu
+
+DST="${1:?uso: metal-firmware.sh <rootfs-dir>}"
+FWSRC="${FWSRC:-/lib/firmware}"
+OUT="$DST/lib/firmware"
+mkdir -p "$OUT"
+
+# patrones de firmware que el AX201 puede pedir (ambas familias, todas las API presentes)
+PATTERNS="iwlwifi-QuZ-a0-hr-b0-*.ucode iwlwifi-cc-a0-*.ucode"
+n=0
+for pat in $PATTERNS; do
+ for src in "$FWSRC"/$pat "$FWSRC"/$pat.zst "$FWSRC"/$pat.xz; do
+ [ -e "$src" ] || continue
+ base=$(basename "$src")
+ case "$base" in
+ *.zst) dst="$OUT/${base%.zst}"; zstd -q -d -f -o "$dst" "$src" ;;
+ *.xz) dst="$OUT/${base%.xz}"; xz -dc "$src" > "$dst" ;;
+ *) dst="$OUT/$base"; cp "$src" "$dst" ;;
+ esac
+ n=$((n+1))
+ done
+done
+
+# regulatory db (texto firmado; cfg80211 lo carga vía firmware loader y verifica .p7s con clave built-in)
+for f in regulatory.db regulatory.db.p7s; do
+ if [ -e "$FWSRC/$f" ]; then cp "$FWSRC/$f" "$OUT/$f"; n=$((n+1)); fi
+done
+
+[ "$n" -gt 0 ] || { echo "metal-firmware: NO encontré firmware AX201 en $FWSRC" >&2; exit 1; }
+echo "metal-firmware: $n blobs → $OUT"
+ls "$OUT" | sed 's/^/ /'