gioser

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1389Shell 137Markdown 80Rust 802602 Definitions

feat(firmware): una derivada para UN PORTATIL INTEL CUALQUIERA, no para una laptop

`firmware-tigerlake` es, por su propio encabezado, «los blobs que pide EXACTAMENTE la laptop
del usuario, y nada mas»: `iwlwifi-QuZ-a0-hr-b0-*.ucode` y `i915/tgl_*.bin`. En otra maquina
esos dos globs dan CERO ficheros y la receta aborta — y el operador lo pidio asi, textual:
«que no sea particularizado tampoco, que voy a instalar a una i5 random y debe funcionar
tambien».

firmware-intel lleva TODA la familia iwlwifi (sin glob de generacion: el nombre que pide el
driver sale del chip Y de la version de API que el kernel soporta, probando de N hacia abajo,
asi que recortar por generacion es adivinar dos cosas a la vez), el DMC de todas las
generaciones de i915, regulatory.db y el SOF generico. ~120 MB.

Lo que deja afuera esta escrito y es decision de tamanio, no olvido: Realtek, Qualcomm,
Broadcom y MediaTek pasarian el medio de 120 a ~310 MB, y cada una es otra derivada de dos
lineas sobre la misma linux-firmware — asi esta pensado el mecanismo. amdgpu/radeon quedan
afuera por un motivo tecnico: takana pinta por mesa-swrast, software puro.

⚠️ FALTA LA OTRA MITAD, y no es de esta receta: el iwlwifi de estos kernels va COMPILADO EN
EL KERNEL y pide su .ucode a los 0,49 s, cuando la raiz no esta montada. `/lib/firmware` de la
raiz no alcanza para el arranque: el unico sitio es el INITRAMFS que escribe el instalador.
Sin eso esto sirve para un rescan en caliente y no para arrancar con red.

NO se declara en ningun perfil todavia: ni esta receta ni `linux-firmware` estan selladas
(`takana hash --check` dice NO-SELLADO para las dos), y un perfil que declara lo que no esta
en el store rompe el armado de la imagen entera. Forjar primero — son 648 MB de tarball —
y declarar despues.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

400b91498ce5207b3a846d23f8e98409d69340f8 · by sergio · (7 d ago) · parent 0f66c9973 · browse the tree at this commit

Semantic delta

No definition changed: this change is text, documentation or data.

1 files · +130 −0

diff --git a/recipes/firmware-intel.toml b/recipes/firmware-intel.toml
new file mode 100644
index 00000000..0802dd2c
--- /dev/null
+++ b/recipes/firmware-intel.toml
@@ -0,0 +1,130 @@
+# firmware-intel — los blobs que pide UN PORTÁTIL INTEL CUALQUIERA, no una laptop en particular.
+#
+# ══ POR QUÉ, EN PALABRAS DEL OPERADOR ══════════════════════════════════════════════════════════
+# *«que no sea particularizado tampoco, que voy a instalar a una i5 random y debe funcionar
+# también»* (2026-10-15). `firmware-tigerlake` es, por diseño y por su propio encabezado, «los blobs
+# que pide EXACTAMENTE la laptop del usuario, y nada más»: `iwlwifi-QuZ-a0-hr-b0-*.ucode` y
+# `i915/tgl_*.bin`. En otra máquina —otra generación de Core, otro módulo Wi-Fi— esos dos globs dan
+# CERO ficheros y la receta aborta, o peor: entra sin el blob que esa máquina necesita y el síntoma
+# es «no hay red», que es lo que costó la noche del 14 de octubre.
+#
+# Ésta es la misma idea una vuelta más arriba: **todas** las generaciones de iwlwifi y **todas** las
+# de i915, que es lo que convierte «funciona en mi laptop» en «funciona en un portátil Intel».
+#
+# ══ QUÉ CUBRE, Y QUÉ NO ════════════════════════════════════════════════════════════════════════
+#   · `intel/iwlwifi/*.ucode` — TODA la familia: 7260/7265, 8000, 9000, AX200/201/210, BE200…
+#     Es el módulo Wi-Fi del grueso del parque de portátiles Intel de los últimos diez años.
+#   · `i915/*` — el DMC de todas las generaciones (skl, kbl, cml, icl, tgl, adl, mtl…) y el GuC.
+#     Sin el DMC el display enciende pero **el ahorro de energía en runtime queda deshabilitado**,
+#     que en un portátil se nota en la batería y no en la pantalla (por eso nadie lo ve).
+#   · `regulatory.db` + `.p7s` — sin la base regulatoria el supplicant no puede elegir canal.
+#   · SOF genérico (`sof-hda-generic*.tplg` + los `.ri` que haya) — el audio de las Intel con HDA.
+#
+# **NO cubre** Realtek (`rtw88`/`rtw89`), Qualcomm (`ath10k`/`ath11k`), Broadcom (`brcm`) ni
+# MediaTek, y eso es una decisión de TAMAÑO escrita a propósito: sumarlas pasa de ~120 MB a ~310 MB
+# en el medio de instalación. Cada una es otra receta derivada de dos líneas sobre la misma
+# `linux-firmware` —así está pensado el mecanismo— y el día que alguien instale en una máquina con
+# wifi Realtek, la salida es `firmware-realtek`, no inflar ésta.
+#
+# **Tampoco cubre `amdgpu`/`radeon`** (son ~300 MB solos) y acá sí hay un motivo técnico y no de
+# peso: takana pinta por `mesa-swrast`, software puro. Una GPU sin firmware no acelera, y acá no se
+# acelera de todos modos.
+#
+# ══ SIN COMPRIMIR, igual que la derivada de tigerlake ══════════════════════════════════════════
+# El kernel `linux-metal` **no habilita `FW_LOADER_COMPRESS`**, así que un `.zst` no se carga y el
+# fallo se lee exactamente igual que un fichero ausente (`Direct firmware load for … failed with
+# error -2`). Medido en el dmesg del metal el 2026-10-14.
+#
+# ⚠️ **Y FALTA LA OTRA MITAD, que no es de esta receta:** el `iwlwifi` de estos kernels va
+# COMPILADO EN EL KERNEL y pide su `.ucode` a los 0,49 s de arranque, cuando la raíz todavía no está
+# montada. Poner los blobs en `/lib/firmware` de la raíz **no alcanza para el arranque**: el único
+# sitio donde el kernel los puede encontrar a esa altura es el INITRAMFS. Está anotado en la cola:
+# el initramfs que escribe el instalador tiene que llevar `lib/firmware`. Sin eso esta receta sirve
+# para un `rescan` en caliente y no para que la máquina arranque con red.
+name    = "firmware-intel"
+version = "20260910"          # sigue a linux-firmware: no tiene versión propia
+license = "LicenseRef-linux-firmware-various"
+
+[source]
+dir = "firmware-intel"
+
+[build]
+compiler = "zig-cc"
+target   = "x86_64-linux-musl"
+link     = "static"
+strip_debug = false
+flags   = []
+
+[build.phases]
+configure = "echo 'firmware-intel: nada que configurar'"
+compile   = "echo 'firmware-intel: nada que compilar — son blobs de la dep'"
+install = '''
+set -e
+SRC=/lib/firmware
+DST=/out/lib/firmware
+[ -d "$SRC" ] || { echo "firmware-intel: no está el árbol de linux-firmware en $SRC" >&2; exit 1; }
+[ -f "$SRC/WHENCE" ] || { echo "firmware-intel: falta WHENCE — la dep no se materializó entera" >&2; exit 1; }
+mkdir -p "$DST/intel/iwlwifi" "$DST/i915" "$DST/intel/sof/intel-signed" "$DST/intel/sof-tplg"
+
+# ── 1. Wi-Fi: TODA la familia iwlwifi ─────────────────────────────────────────────────────────
+# Sin glob de generación: el nombre que pide el driver sale del chip Y de la versión de API que ese
+# kernel soporta (`iwlwifi-<chip>-<N>.ucode`, probando de N hacia abajo), así que recortar por
+# generación es adivinar dos cosas a la vez. Son ~100 MB y es lo que compra «funciona en un portátil
+# Intel cualquiera».
+wifi=0
+for d in "$SRC/intel/iwlwifi" "$SRC"; do
+  [ -d "$d" ] || continue
+  for f in "$d"/iwlwifi-*.ucode; do
+    [ -f "$f" ] || continue
+    cp -L "$f" "$DST/intel/iwlwifi/" 2>/dev/null && wifi=$((wifi+1))
+  done
+done
+# El loader busca en `/lib/firmware` Y en `/lib/firmware/intel/iwlwifi` según la versión del driver;
+# los enlaces duros no cuestan disco y tapan las dos convenciones.
+for f in "$DST"/intel/iwlwifi/*.ucode; do
+  [ -f "$f" ] || continue
+  ln "$f" "$DST/$(basename "$f")" 2>/dev/null || cp -L "$f" "$DST/" || true
+done
+[ "$wifi" -gt 40 ] || { echo "firmware-intel: sólo $wifi blobs de iwlwifi — esperaba la familia entera (>40); ¿se materializó linux-firmware?" >&2; exit 1; }
+
+# ── 2. La base regulatoria: sin ella el supplicant no elige canal ─────────────────────────────
+for f in regulatory.db regulatory.db.p7s; do
+  [ -f "$SRC/$f" ] && cp -L "$SRC/$f" "$DST/"
+done
+[ -f "$DST/regulatory.db" ] || { echo "firmware-intel: falta regulatory.db" >&2; exit 1; }
+
+# ── 3. Gráficos Intel: el DMC de TODAS las generaciones, y el GuC/HuC ─────────────────────────
+gfx=0
+for f in "$SRC"/i915/*.bin; do
+  [ -f "$f" ] || continue
+  cp -L "$f" "$DST/i915/" && gfx=$((gfx+1))
+done
+[ "$gfx" -gt 10 ] || { echo "firmware-intel: sólo $gfx blobs de i915 — esperaba todas las generaciones (>10)" >&2; exit 1; }
+
+# ── 4. Audio SOF genérico ─────────────────────────────────────────────────────────────────────
+# El topology `sof-hda-generic` es el que sirve a cualquier Intel con HDA; los `.ri` firmados van
+# todos porque el que carga lo decide el PCI id de la máquina, no nosotros.
+snd=0
+if [ -d "$SRC/intel/sof/intel-signed" ]; then
+  for f in "$SRC"/intel/sof/intel-signed/sof-*.ri; do
+    [ -f "$f" ] || continue
+    cp "$f" "$DST/intel/sof/intel-signed/"
+    ln -sf "intel-signed/$(basename "$f")" "$DST/intel/sof/$(basename "$f")"
+    snd=$((snd+1))
+  done
+fi
+if [ -d "$SRC/intel/sof-tplg" ]; then
+  for f in "$SRC"/intel/sof-tplg/sof-hda-generic*.tplg; do
+    [ -f "$f" ] && cp -L "$f" "$DST/intel/sof-tplg/" && snd=$((snd+1))
+  done
+fi
+# El audio NO aborta la receta: una máquina sin sonido es usable y una sin red no. Se dice y sigue.
+[ "$snd" -gt 0 ] || echo "firmware-intel: 0 blobs de SOF — esta imagen va a quedar sin audio HDA" >&2
+
+n=$(find "$DST" -type f | wc -l)
+k=$(du -sk "$DST" | cut -f1)
+echo "firmware-intel: $n ficheros, ${k} KiB (wifi=$wifi i915=$gfx sof=$snd)"
+'''
+
+[deps]
+build = ["linux-firmware", "sof-firmware", "wireless-regdb"]