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>
This commit is contained in:
@@ -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).*
|
||||
@@ -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"
|
||||
Executable
+46
@@ -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/^/ /'
|
||||
Reference in New Issue
Block a user