tawasuyu

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 1576Shell 205Rust 111Markdown 993774 Definiciones

⎇ 84e3737e10e17927380ed3e232e50cebfdd39123 recipes/firmware-intel.toml TOML · 130 líneas · 7.7 KB Historia crudo

feat(firmware): una derivada para UN PORTATIL INTEL CUALQUIERA, no para una laptop 400b91498 · sergio ·

1# firmware-intel — los blobs que pide UN PORTÁTIL INTEL CUALQUIERA, no una laptop en particular.
2#
3# ══ POR QUÉ, EN PALABRAS DEL OPERADOR ══════════════════════════════════════════════════════════
4# *«que no sea particularizado tampoco, que voy a instalar a una i5 random y debe funcionar
5# también»* (2026-10-15). `firmware-tigerlake` es, por diseño y por su propio encabezado, «los blobs
6# que pide EXACTAMENTE la laptop del usuario, y nada más»: `iwlwifi-QuZ-a0-hr-b0-*.ucode` y
7# `i915/tgl_*.bin`. En otra máquina —otra generación de Core, otro módulo Wi-Fi— esos dos globs dan
8# CERO ficheros y la receta aborta, o peor: entra sin el blob que esa máquina necesita y el síntoma
9# es «no hay red», que es lo que costó la noche del 14 de octubre.
10#
11# Ésta es la misma idea una vuelta más arriba: **todas** las generaciones de iwlwifi y **todas** las
12# de i915, que es lo que convierte «funciona en mi laptop» en «funciona en un portátil Intel».
13#
14# ══ QUÉ CUBRE, Y QUÉ NO ════════════════════════════════════════════════════════════════════════
15#   · `intel/iwlwifi/*.ucode` — TODA la familia: 7260/7265, 8000, 9000, AX200/201/210, BE200…
16#     Es el módulo Wi-Fi del grueso del parque de portátiles Intel de los últimos diez años.
17#   · `i915/*` — el DMC de todas las generaciones (skl, kbl, cml, icl, tgl, adl, mtl…) y el GuC.
18#     Sin el DMC el display enciende pero **el ahorro de energía en runtime queda deshabilitado**,
19#     que en un portátil se nota en la batería y no en la pantalla (por eso nadie lo ve).
20#   · `regulatory.db` + `.p7s` — sin la base regulatoria el supplicant no puede elegir canal.
21#   · SOF genérico (`sof-hda-generic*.tplg` + los `.ri` que haya) — el audio de las Intel con HDA.
22#
23# **NO cubre** Realtek (`rtw88`/`rtw89`), Qualcomm (`ath10k`/`ath11k`), Broadcom (`brcm`) ni
24# MediaTek, y eso es una decisión de TAMAÑO escrita a propósito: sumarlas pasa de ~120 MB a ~310 MB
25# en el medio de instalación. Cada una es otra receta derivada de dos líneas sobre la misma
26# `linux-firmware` —así está pensado el mecanismo— y el día que alguien instale en una máquina con
27# wifi Realtek, la salida es `firmware-realtek`, no inflar ésta.
28#
29# **Tampoco cubre `amdgpu`/`radeon`** (son ~300 MB solos) y acá sí hay un motivo técnico y no de
30# peso: takana pinta por `mesa-swrast`, software puro. Una GPU sin firmware no acelera, y acá no se
31# acelera de todos modos.
32#
33# ══ SIN COMPRIMIR, igual que la derivada de tigerlake ══════════════════════════════════════════
34# El kernel `linux-metal` **no habilita `FW_LOADER_COMPRESS`**, así que un `.zst` no se carga y el
35# fallo se lee exactamente igual que un fichero ausente (`Direct firmware load for … failed with
36# error -2`). Medido en el dmesg del metal el 2026-10-14.
37#
38# ⚠️ **Y FALTA LA OTRA MITAD, que no es de esta receta:** el `iwlwifi` de estos kernels va
39# COMPILADO EN EL KERNEL y pide su `.ucode` a los 0,49 s de arranque, cuando la raíz todavía no está
40# montada. Poner los blobs en `/lib/firmware` de la raíz **no alcanza para el arranque**: el único
41# sitio donde el kernel los puede encontrar a esa altura es el INITRAMFS. Está anotado en la cola:
42# el initramfs que escribe el instalador tiene que llevar `lib/firmware`. Sin eso esta receta sirve
43# para un `rescan` en caliente y no para que la máquina arranque con red.
44name    = "firmware-intel"
45version = "20260910"          # sigue a linux-firmware: no tiene versión propia
46license = "LicenseRef-linux-firmware-various"
47
48[source]
49dir = "firmware-intel"
50
51[build]
52compiler = "zig-cc"
53target   = "x86_64-linux-musl"
54link     = "static"
55strip_debug = false
56flags   = []
57
58[build.phases]
59configure = "echo 'firmware-intel: nada que configurar'"
60compile   = "echo 'firmware-intel: nada que compilar — son blobs de la dep'"
61install = '''
62set -e
63SRC=/lib/firmware
64DST=/out/lib/firmware
65[ -d "$SRC" ] || { echo "firmware-intel: no está el árbol de linux-firmware en $SRC" >&2; exit 1; }
66[ -f "$SRC/WHENCE" ] || { echo "firmware-intel: falta WHENCE — la dep no se materializó entera" >&2; exit 1; }
67mkdir -p "$DST/intel/iwlwifi" "$DST/i915" "$DST/intel/sof/intel-signed" "$DST/intel/sof-tplg"
68
69# ── 1. Wi-Fi: TODA la familia iwlwifi ─────────────────────────────────────────────────────────
70# Sin glob de generación: el nombre que pide el driver sale del chip Y de la versión de API que ese
71# kernel soporta (`iwlwifi-<chip>-<N>.ucode`, probando de N hacia abajo), así que recortar por
72# generación es adivinar dos cosas a la vez. Son ~100 MB y es lo que compra «funciona en un portátil
73# Intel cualquiera».
74wifi=0
75for d in "$SRC/intel/iwlwifi" "$SRC"; do
76  [ -d "$d" ] || continue
77  for f in "$d"/iwlwifi-*.ucode; do
78    [ -f "$f" ] || continue
79    cp -L "$f" "$DST/intel/iwlwifi/" 2>/dev/null && wifi=$((wifi+1))
80  done
81done
82# El loader busca en `/lib/firmware` Y en `/lib/firmware/intel/iwlwifi` según la versión del driver;
83# los enlaces duros no cuestan disco y tapan las dos convenciones.
84for f in "$DST"/intel/iwlwifi/*.ucode; do
85  [ -f "$f" ] || continue
86  ln "$f" "$DST/$(basename "$f")" 2>/dev/null || cp -L "$f" "$DST/" || true
87done
88[ "$wifi" -gt 40 ] || { echo "firmware-intel: sólo $wifi blobs de iwlwifi — esperaba la familia entera (>40); ¿se materializó linux-firmware?" >&2; exit 1; }
89
90# ── 2. La base regulatoria: sin ella el supplicant no elige canal ─────────────────────────────
91for f in regulatory.db regulatory.db.p7s; do
92  [ -f "$SRC/$f" ] && cp -L "$SRC/$f" "$DST/"
93done
94[ -f "$DST/regulatory.db" ] || { echo "firmware-intel: falta regulatory.db" >&2; exit 1; }
95
96# ── 3. Gráficos Intel: el DMC de TODAS las generaciones, y el GuC/HuC ─────────────────────────
97gfx=0
98for f in "$SRC"/i915/*.bin; do
99  [ -f "$f" ] || continue
100  cp -L "$f" "$DST/i915/" && gfx=$((gfx+1))
101done
102[ "$gfx" -gt 10 ] || { echo "firmware-intel: sólo $gfx blobs de i915 — esperaba todas las generaciones (>10)" >&2; exit 1; }
103
104# ── 4. Audio SOF genérico ─────────────────────────────────────────────────────────────────────
105# El topology `sof-hda-generic` es el que sirve a cualquier Intel con HDA; los `.ri` firmados van
106# todos porque el que carga lo decide el PCI id de la máquina, no nosotros.
107snd=0
108if [ -d "$SRC/intel/sof/intel-signed" ]; then
109  for f in "$SRC"/intel/sof/intel-signed/sof-*.ri; do
110    [ -f "$f" ] || continue
111    cp "$f" "$DST/intel/sof/intel-signed/"
112    ln -sf "intel-signed/$(basename "$f")" "$DST/intel/sof/$(basename "$f")"
113    snd=$((snd+1))
114  done
115fi
116if [ -d "$SRC/intel/sof-tplg" ]; then
117  for f in "$SRC"/intel/sof-tplg/sof-hda-generic*.tplg; do
118    [ -f "$f" ] && cp -L "$f" "$DST/intel/sof-tplg/" && snd=$((snd+1))
119  done
120fi
121# El audio NO aborta la receta: una máquina sin sonido es usable y una sin red no. Se dice y sigue.
122[ "$snd" -gt 0 ] || echo "firmware-intel: 0 blobs de SOF — esta imagen va a quedar sin audio HDA" >&2
123
124n=$(find "$DST" -type f | wc -l)
125k=$(du -sk "$DST" | cut -f1)
126echo "firmware-intel: $n ficheros, ${k} KiB (wifi=$wifi i915=$gfx sof=$snd)"
127'''
128
129[deps]
130build = ["linux-firmware", "sof-firmware", "wireless-regdb"]