# 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--.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"]