`scripts/metal-firmware.sh` llevaba desde que se escribió con este pie:
TODO(soberanía): reemplazar FWSRC=host por un pin a un commit de linux-firmware
Eso significaba que una imagen de takana para el metal sólo se podía armar desde una
máquina que YA tuviera el firmware instalado por otra distro. Un instalador que sólo se
puede construir desde la distro a la que viene a reemplazar no es un instalador.
Cuatro recetas, y la partición entre ellas es la decisión:
· linux-firmware — tarball 20260910 pineado. 648 MB, ~2 GB extraídos. Es una BASE y no
entra en ningún perfil: nadie manda eso en una imagen de escritorio.
· firmware-tigerlake — DERIVADA, recorta ~25 MB: las tres familias que este metal pide.
Es la que viaja. Otro metal = otra derivada de dos líneas, no otro fetch de 648 MB.
Misma economía que atuq sobre firefox (SDD 26).
· sof-firmware — porque el SOF NO viene en linux-firmware. Medido, no supuesto:
entradas del tarball ... 5323
intel/sof .............. 0 ✗
i915/tgl ............... 15 ✓
iwlwifi ................ 201 ✓
· intel-ucode — tampoco viene: trae amd-ucode pero el de Intel lo publica Intel.
Y una contraintuitiva que queda escrita para no re-tropezarla: TigerLake va por IPC3, no
por IPC4. Lo esperable era tomar la serie más alta de sof-bin (v2.14.x); medido, esa serie
no contiene NINGÚN fichero tgl. El firmware de TGL sólo existe en la rama IPC3, y el más
nuevo que lo trae es v2.2.x/sof-v2.2/sof-tgl.ri.
El sha256 de linux-firmware se contrastó contra el sha256sums.asc que kernel.org publica
firmado — no contra el fichero que bajamos, que sería comprobar que un fichero es igual a
sí mismo.
⚠ NINGUNA ESTÁ SELLADA: escritas desde el laptop, que no tiene lab ni store. Las aserciones
de cada `install` están puestas para que el primer build falle ruidoso en vez de producir
un /lib/firmware a medias — que no falla al construir y falla meses después en el metal
como «no hay WiFi», sin una línea que lo asocie con esto (CLAUDE.md §3).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
76 lines
4.7 KiB
TOML
76 lines
4.7 KiB
TOML
# linux-firmware 20260910 — los BLOBS del hardware. La receta que le faltaba al metal.
|
|
#
|
|
# ══ POR QUÉ ESTA RECETA ROMPE LA REGLA, Y POR QUÉ ESTÁ BIEN ════════════════════════════════════
|
|
# takana compila todo desde fuente. Esto NO se compila desde fuente: es firmware binario que Intel,
|
|
# Realtek y el resto no liberan. La soberanía de «reproducir, no confiar» **no aplica** acá, igual
|
|
# que no aplica al microcódigo de la CPU: son DATOS FIJOS, no código que podamos auditar ni
|
|
# rebuildear. Lo que sí podemos hacer —y hacemos— es **fijarlos por contenido**: un tarball con su
|
|
# sha256, como cualquier fuente pineada (ADR 0006). El artefacto es reproducible aunque su
|
|
# contenido sea opaco.
|
|
#
|
|
# ══ QUÉ TODO CIERRA ════════════════════════════════════════════════════════════════════════════
|
|
# `scripts/metal-firmware.sh` lleva desde que se escribió con este comentario al pie:
|
|
#
|
|
# TODO(soberanía): reemplazar FWSRC=host por un pin a un commit de linux-firmware
|
|
# (recipe fetch+extract).
|
|
#
|
|
# Eso es esta receta. Hasta hoy el firmware del metal se COPIABA DEL HOST (`/lib/firmware` de la
|
|
# Artix del usuario), lo que significa que una imagen de takana sólo se podía armar desde una
|
|
# máquina que ya tuviera el firmware correcto instalado por otra distro. Un instalador que hay que
|
|
# construir desde la distro que viene a reemplazar no es un instalador.
|
|
#
|
|
# ══ PESA 648 MB COMPRIMIDO, Y POR ESO NO VA EN NINGÚN PERFIL ═══════════════════════════════════
|
|
# El árbol extraído son ~2 GB: firmware de todas las GPU, WiFi, bluetooth, DSP y controladoras que
|
|
# Linux conoce. Meter eso en una imagen de escritorio sería absurdo. **Esta receta es una BASE, no
|
|
# un miembro de perfil**: quien la consume es `firmware-tigerlake`, que extrae las cuatro familias
|
|
# que una laptop concreta pide. Si mañana hay otro metal, es otra receta derivada de dos líneas —
|
|
# no un segundo fetch de 648 MB.
|
|
#
|
|
# Por eso `perfiles` no la reclama nadie en `targets.toml`: entra por la dep de su derivada.
|
|
name = "linux-firmware"
|
|
version = "20260910"
|
|
license = "LicenseRef-linux-firmware-various" # cada blob trae su propia licencia en WHENCE
|
|
|
|
[source]
|
|
tarball = "https://cdn.kernel.org/pub/linux/kernel/firmware/linux-firmware-20260910.tar.xz"
|
|
# sha256 bajado y calculado el 2026-09-16, y **contrastado contra el `sha256sums.asc` que kernel.org
|
|
# publica firmado en el mismo directorio** — no sólo contra el fichero que bajamos, que sería
|
|
# comprobar que un fichero es igual a sí mismo. Coinciden.
|
|
sha256 = "f3937ca282ba256242e2b6dbe523df8a80007d29ffd61f56d270190865492ea8"
|
|
|
|
# ══ QUÉ TRAE Y QUÉ NO — MEDIDO SOBRE EL TARBALL, NO SUPUESTO ═══════════════════════════════════
|
|
# entradas ........ 5323
|
|
# i915/tgl ........ 15 ✓ (DMC, GuC, HuC de TigerLake)
|
|
# iwlwifi ......... 201 ✓ (en `intel/iwlwifi/`, no en la raíz)
|
|
# intel/sof ....... 0 ✗ ⇒ el audio va por `recipes/sof-firmware.toml`, aparte
|
|
# amd-ucode ....... sí (pero el microcódigo de Intel NO: lo publica Intel por su cuenta)
|
|
|
|
[build]
|
|
compiler = "zig-cc" # entra en el hash aunque no se compile nada; se deja el default del corpus
|
|
target = "x86_64-linux-musl"
|
|
link = "static"
|
|
strip_debug = false # son blobs: no hay secciones de depuración que separar
|
|
flags = []
|
|
|
|
[build.phases]
|
|
configure = "echo 'linux-firmware: nada que configurar — son blobs'"
|
|
compile = "echo 'linux-firmware: nada que compilar — son blobs'"
|
|
# El `install` del propio árbol (`make install`) usa un script que depende de rdfind/symlink
|
|
# rewriting. Se evita: copiar el árbol tal cual es más simple y no pierde los symlinks internos
|
|
# (cp -a los preserva), que es exactamente lo que el kernel espera encontrar.
|
|
install = '''
|
|
set -e
|
|
mkdir -p /out/lib/firmware
|
|
cp -a ./* /out/lib/firmware/
|
|
# WHENCE es el índice de licencias por blob. Se conserva: es la única trazabilidad legal que
|
|
# tienen estos ficheros y `scripts/licencias-*.sh` lo va a querer leer.
|
|
[ -f /out/lib/firmware/WHENCE ] || { echo "linux-firmware: falta WHENCE — el tarball no es el que se espera" >&2; exit 1; }
|
|
# Aserción ruidosa (CLAUDE.md §3): un árbol de firmware vacío pasaría por artefacto presente.
|
|
n=$(find /out/lib/firmware -type f | wc -l)
|
|
[ "$n" -gt 5000 ] || { echo "linux-firmware: sólo $n ficheros — el árbol llegó incompleto" >&2; exit 1; }
|
|
echo "linux-firmware: $n ficheros instalados"
|
|
'''
|
|
|
|
[deps]
|
|
build = ["busybox"]
|