diff --git a/docs/runbooks/instalador-laptop-tigerlake.md b/docs/runbooks/instalador-laptop-tigerlake.md new file mode 100644 index 00000000..6b5ad27d --- /dev/null +++ b/docs/runbooks/instalador-laptop-tigerlake.md @@ -0,0 +1,143 @@ +# Runbook — el instalador para la laptop del usuario (TigerLake), y los dos muros que tiene delante + +> **Estado: ENCARGO, no cerrado.** Las recetas de este runbook se escribieron el 2026-09-16 desde el +> propio laptop —que no tiene lab ni store— así que **ninguna está sellada**. Lo que sigue es el +> trabajo para el worker, en orden, con lo que ya está medido separado de lo que hay que averiguar. +> Hermano de [`kde-qemu-desktop.md`](kde-qemu-desktop.md) y [`cosmic-desktop.md`](cosmic-desktop.md), +> de los que reusa todo el andamiaje. + +## 0. Qué se quiere + +Un medio que arranque en la laptop del usuario e **instale takana reemplazando la Artix** que hay +hoy. No un USB de pruebas —eso ya existe con `mirada-usb.sh`— sino una instalación a disco. + +## 1. La máquina, medida + +`lspci -nn`, `/proc/cpuinfo` y `lsblk` sobre el metal real, 2026-09-16: + +| pieza | qué es | driver | firmware | +|---|---|---|---| +| CPU | i7-11370H · family 6 · model 140 (0x8c) · stepping 1 | — | `intel-ucode/06-8c-01` | +| GPU | TigerLake-LP GT2 [Iris Xe] `[8086:9a49]` | `i915` / `xe` | `i915/tgl_{dmc,guc,huc}*` | +| WiFi | Intel Wi-Fi 6 AX201 `[8086:a0f0]` | `iwlwifi` | `iwlwifi-{QuZ-a0-hr-b0,cc-a0}-*.ucode` | +| Audio | 500 Series HD Audio `[8086:a0c8]` | `snd_sof_pci_intel_tgl` | `intel/sof/sof-tgl.ri` | +| Disco | NVMe 1,8 T | `nvme` | — | +| Firmware del equipo | **UEFI** (`/sys/firmware/efi` presente) | — | — | + +## 2. Lo que se escribió para esto (sin sellar) + +Cinco recetas nuevas y un perfil. Todas parsean y `takana hash` las acepta; el grafo de deps cierra. + +| receta | qué es | nota | +|---|---|---| +| `linux-firmware` | tarball 20260910 pineado (648 MB) | sha256 contrastado contra el `sha256sums.asc` de kernel.org | +| `sof-firmware` | sof-bin v2025.12.2 | **no está en linux-firmware** — medido, 0 coincidencias | +| `intel-ucode` | microcode-20260812 | tampoco: Intel lo publica aparte | +| `firmware-tigerlake` | derivada: recorta ~25 MB de las tres familias de este metal | la única que viaja en la imagen | +| `zsh` | el shell de login del usuario | seis parches de musl de Alpine | +| `[perfil.metal-tigerlake]` | la capa de hardware, componible con cualquier escritorio | `firmware-tigerlake` + `intel-ucode` | + +Esto cierra el `TODO(soberanía)` que `scripts/metal-firmware.sh` llevaba desde que se escribió: hasta +hoy el firmware se **copiaba de `/lib/firmware` del host**, o sea de la Artix que veníamos a +reemplazar. Un instalador que sólo se puede construir desde la distro que viene a sustituir no es un +instalador. + +## 3. La tanda — qué construir, en orden + +El orden importa: `firmware-tigerlake` depende de las dos de firmware y falla ruidosa si no las +encuentra materializadas. + +```sh +cd /opt/takana +flock -o work/.farm-build.lock bash -c ' + for r in linux-firmware sof-firmware intel-ucode firmware-tigerlake zsh; do + ./target/release/takana --store ./store build "$r" || { echo "FALLÓ: $r"; break; } + done' +``` + +`flock -o`, no `flock` a secas — CLAUDE.md §1, y está medido: el lock lo sostiene la descripción de +fichero abierta y los nietos la heredan. + +### Lo que puede salir mal, y cómo se ve + +- **`zsh` sale dinámico.** Es lo que le pasó a `bash`: si el `configure` mete `-rdynamic`, el wrapper + de cc del lab tira el `-static` y el binario queda contra `libncursesw.so.6`, que ningún artefacto + del corpus provee. Síntoma: `Error relocating ... symbol not found`. Arreglo conocido: + `make LOCAL_LDFLAGS=`. **Comprobar con `file`: debe decir `statically linked`.** +- **`linux-firmware` tarda y pesa.** 648 MB de fetch, ~2 GB extraídos. El worker tiene 71 G libres. +- **`firmware-tigerlake` aborta con `0 blobs de SOF`.** Significa que `sof-firmware` no se materializó + como dep. No ablandar la aserción: ese contador es la única defensa contra un `/lib/firmware` a + medias, que no falla al construir y falla meses después en el metal como «no hay WiFi». + +## 4. ⚠ Muro 1 — la rama EFI del instalador es justo la que se cuelga en este firmware + +Éste es el hallazgo que ordena el trabajo, y sale de cruzar dos ficheros que nadie había leído juntos. + +`scripts/takana-live-install.sh:275-281` detecta el firmware y bifurca: + +> `--- Detección de firmware: UEFI ⇒ rama EFI-stub SOBERANA (ADR 0010 paso 5); BIOS ⇒ MBR+GRUB ---` + +O sea: en esta laptop, que es UEFI, el instalador tomaría **la rama EFI-stub**. Y +`scripts/metal-usb-sdboot.sh` dice, en su tercera línea: + +> *Alternativa de BRINGUP al boot por EFI-stub directo (que **en el firmware del usuario se cuelga +> tras 'Measured initrd PCR 9'**, por el quirk de LoadOptions del firmware).* + +**Es el mismo firmware.** El lazo completo de instalación EFI está validado en OVMF +(`scripts/efi-install-test.sh`), y OVMF no tiene ese quirk. Así que el instalador probablemente +funcione perfecto en la prueba y se cuelgue en el metal de destino. + +Las tres salidas, en orden de coste: + +1. **Llevar el instalador a systemd-boot**, que es el camino ya probado en este metal: pasa una + cmdline limpia y entrega el initrd por `LoadFile2`, esquivando el quirk. El precio está escrito y + aceptado como deuda: `systemd-bootx64.efi` es un binario ajeno del host — crutch de bringup. +2. **Arrancar el medio por systemd-boot y dejar que instale la rama EFI-stub.** No sirve: el disco + instalado arrancaría por EFI-stub y se colgaría igual, sólo que después de borrar Artix. +3. **Loader soberano propio.** Es el `TODO` que ya está anotado y no es trabajo de una sesión. + +⇒ **Recomendado: (1).** Y el test de aceptación no es OVMF: es el USB arrancando en el metal. + +## 5. ⚠ Muro 2 — el particionado, y una pregunta que es del usuario + +`takana-live-install.sh` particiona en **MBR**, incluida su rama EFI (una ESP tipo `0xEF` en tabla +MBR, que UEFI acepta igual). Sobre el disco de esta laptop eso tiene dos consecuencias: + +- El NVMe es de **1,8 T**. MBR direcciona hasta 2 T: entra por poco, pero es el borde exacto del + formato y no hay razón para quedarse ahí cuando el disco ya es GPT. +- El instalador **reparticiona el disco entero**. Hoy ese disco tiene `/home` con **893 G usados de + 1,1 T** — el trabajo del usuario, incluido `~/tawasuyu` (497 G). + +> **Pregunta abierta, y es decisión del usuario, no del runbook:** ¿la instalación conserva `/home` +> —instalando sólo sobre la raíz de 164 G— o se lleva el disco entero con respaldo previo? El +> instalador hoy no sabe hacer lo primero: no tiene modo «usar esta partición y no tocar las otras». + +Mientras eso no se decida, **no correr el instalador sobre `/dev/nvme0n1`.** El camino sin riesgo es +el USB: `metal-usb-sdboot.sh` produce una imagen para `dd` a un pendrive y no toca el disco interno. + +## 6. Orden de trabajo propuesto + +1. Construir la tanda del §3 y verificar que `zsh` sale estático y que `firmware-tigerlake` reporta + los tres contadores distintos de cero. +2. Armar un USB de prueba con el perfil compuesto y **arrancarlo en el metal**: + ```sh + scripts/targets.py cli metal-tigerlake escritorio-kde # la lista de la imagen + scripts/metal-usb-sdboot.sh # → work/hammer-metal-usb.img + ``` + Lo que se valida acá no es el escritorio: es **el firmware**. Que asocie el WiFi, que el display + tome el DMC y que el DSP de audio levante. Son las tres cosas que hoy sólo funcionan porque las + presta la Artix instalada. +3. Recién entonces, el instalador: la rama systemd-boot del §4 y la decisión de particionado del §5. +4. Y sólo después, KDE/GNOME/COSMIC en metal con GPU real — hoy los tres corren por llvmpipe, que en + QEMU es correcto y en una Iris Xe es tirar la GPU a la basura. + +## 7. Lo que este runbook NO resuelve + +- **La laptop sigue sin poder hidratar.** Su `.dev-fs/alpine` tiene 104 paquetes contra los 110 de + `lab-toolchain.lock`, así que calcula `ArtifactHash` distintos y no encuentra nada del store + compartido. Hasta que `farm-lab-sync.sh` corra hacia acá, todo lo de este runbook pasa por el + worker. +- **`kitty`, el terminal del usuario, no tiene receta.** `foot` sí está sellada y es el terminal + Wayland del proyecto; sirve de puente, pero no es lo que él usa. +- **Los escritorios en metal con aceleración.** Distinto problema del firmware: es mesa con el driver + Iris real en vez de llvmpipe. diff --git a/docs/state/targets.toml b/docs/state/targets.toml index c889dd1f..25f89892 100644 --- a/docs/state/targets.toml +++ b/docs/state/targets.toml @@ -169,6 +169,15 @@ paquetes = [ "pigz", # gzip en paralelo "miller", # `jq` para CSV/TSV — el hueco de datos tabulares "dwarves", # `pahole`: inspeccionar el BTF/DWARF del kernel. Esta distro compila el suyo + # ── BARRIDO DE LA MÁQUINA DEL USUARIO (2026-09-16) ────────────────────────────────────────── + # `zsh` es EL SHELL DE LOGIN del usuario, medido en su historial (1611 `cd`, 1054 `cargo`, 134 + # `zellij`), y no tenía receta ni en el corpus ni en ninguna de las cuatro colas. Una imagen de + # takana instalada en su laptop lo dejaba en `bash`: funciona, pero no es su máquina. Entra en + # `cli` y no en `base` porque `base` define el shell del SISTEMA (bash) y esto es el del usuario + # — dos hechos distintos, como `paquetes` y `servicios` un piso más abajo. + # Es el mismo hueco de RUNTIME que `bash-completion`: nadie lo alcanza por deps de build, así que + # ninguna métrica de deuda podía verlo. Sólo se ve mirando la máquina de quien la usa. + "zsh", ] [perfil.escritorio-mirada] @@ -1439,3 +1448,47 @@ paquetes = [ # `shell = /bin/sh` —no `/bin/false`—, porque este demonio existe para abrir PTYs: con la shell # inerte el servicio arranca, se supervisa, y cada pestaña muere al instante. servicios = ["sshd", "gitea", "caddy", "minga", "squid", "crond", "chronyd", "shuma-daemon", "shuma-gateway"] + +# ════════════════════════════════════════════════════════════════════════════════════════════════ +[perfil.metal-tigerlake] +descripcion = "capa de HARDWARE de la laptop del usuario: firmware y microcódigo del metal real" +cola = "corpus" +# ── POR QUÉ ES UN PERFIL Y NO PAQUETES SUELTOS EN CADA ESCRITORIO ─────────────────────────────── +# Esto no es un escritorio ni un toolbox: es **lo que hace falta para que ESTE metal arranque con +# todo su hardware vivo**. Se compone con cualquiera de los cuatro escritorios en vez de duplicarse +# en los cuatro — que es exactamente el error que el SDD 27 §2 describe («hoy el repo mezcla las +# tres capas en una sola lista por escritorio»). +# +# ── LA MÁQUINA, MEDIDA ───────────────────────────────────────────────────────────────────────── +# `lspci -nn` + `/proc/cpuinfo` sobre el metal real, 2026-09-16: +# +# CPU 11th Gen Intel Core i7-11370H · family 6 · model 140 (0x8c) · stepping 1 +# GPU Intel TigerLake-LP GT2 [Iris Xe] [8086:9a49] ⇒ i915 / xe +# WiFi Intel Wi-Fi 6 AX201 [8086:a0f0] ⇒ iwlwifi +# Audio Intel 500 Series HD Audio [8086:a0c8] ⇒ snd_sof_pci_intel_tgl +# Disco NVMe ⇒ nvme (sin firmware) +# +# ── POR QUÉ HASTA HOY NO EXISTÍA ─────────────────────────────────────────────────────────────── +# Porque el firmware se COPIABA DEL HOST: `scripts/metal-firmware.sh` lee `/lib/firmware` de la +# Artix que ya está instalada. Eso alcanza para un USB de pruebas y NO alcanza para un instalador — +# un instalador que sólo se puede construir desde la distro a la que viene a reemplazar no es un +# instalador. El `TODO(soberanía)` de ese script es justamente esto. +# +# ── NO ENTRA EN NINGÚN ESCRITORIO POR DEFECTO ────────────────────────────────────────────────── +# Es específico de un modelo de laptop. Se pide explícitamente al armar la imagen: +# +# scripts/targets.py cli metal-tigerlake escritorio-kde +# +# Otro metal = otro perfil de estos, con su propia receta `firmware-` derivada del mismo +# `linux-firmware`. Ese es el punto de haberlo partido en dos recetas. +paquetes = [ + # Los blobs de las tres familias de este hardware, recortados del linux-firmware pineado. + # Arrastra por deps a `linux-firmware` (648 MB de tarball) y a `sof-firmware`, que NO van en la + # imagen: sólo viaja el recorte de ~25 MB. Es la misma economía que `atuq` sobre `firefox`. + "firmware-tigerlake", + # Microcódigo de la CPU. Va aparte del firmware porque se carga por otro camino: el árbol plano + # sirve para la carga tardía, y el `GenuineIntel.bin` que la receta deja en + # `/usr/share/intel-ucode/` es el que el armador de la imagen debe prepender al initramfs como + # cpio SIN comprimir para la carga TEMPRANA — la que llega a tiempo para las mitigaciones. + "intel-ucode", +]