Files
takana/recipes/intel-ucode.toml
sergioandClaude Opus 5 099226b2d1 firmware del metal: el TODO de soberanía cerrado — los blobs dejan de copiarse del host
`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>
2026-09-16 15:12:08 -04:00

76 lines
4.2 KiB
TOML

# intel-ucode 20260812 — el microcódigo de la CPU. Va en el arranque, no en el userland.
#
# ══ POR QUÉ NO VIENE EN linux-firmware ═════════════════════════════════════════════════════════
# El tarball de kernel.org trae `amd-ucode` pero **no el de Intel**: Intel lo publica por su cuenta
# en `intel/Intel-Linux-Processor-Microcode-Data-Files`, con su propia licencia. Medido sobre
# `linux-firmware-20260910.tar.xz` el 2026-09-16.
#
# ══ QUÉ CPU ═══════════════════════════════════════════════════════════════════════════════════
# La laptop del usuario, leída de `/proc/cpuinfo`:
#
# 11th Gen Intel Core i7-11370H family 6 · model 140 (0x8c) · stepping 1
# ⇒ le toca `intel-ucode/06-8c-01` (microcódigo corriendo hoy: 0xbe)
#
# La receta instala el árbol ENTERO igual, no sólo ese fichero: el cargador elige por signature en
# boot, y recortarlo ataría el artefacto a esta máquina exacta — que es justo lo que
# `firmware-tigerlake` hace a propósito y esto no debe hacer. Son 17 MB comprimidos.
#
# ══ LOS DOS CAMINOS DE CARGA, Y POR QUÉ HACEN FALTA LOS DOS ════════════════════════════════════
# · **Tardía** (`/lib/firmware/intel-ucode/<sig>`): el kernel la aplica con el sistema ya arriba.
# Sirve, pero llega después de que las mitigaciones de CPU se hayan decidido.
# · **Temprana** (`kernel/x86/microcode/GenuineIntel.bin` dentro de un cpio SIN comprimir, al
# principio del initramfs): el kernel la lee antes de levantar los cores secundarios. Es la que
# de verdad importa, y es la que hay que enganchar en el armado de la imagen.
#
# Esta receta deja los dos: el árbol plano y el `GenuineIntel.bin` ya concatenado, listo para que
# el armador de la imagen lo prependa. **No arma el cpio** — eso es trabajo de la imagen, no del
# artefacto, y meterlo acá obligaría a esta receta a saber cómo se arma el initramfs.
#
# ⚠ **PUNTO DE PARTIDA, NO SELLADA.** Escrita desde el laptop, sin lab ni store.
name = "intel-ucode"
version = "20260812"
license = "LicenseRef-Intel-Software-License" # license/LICENSE en el árbol; NO es libre
[source]
tarball = "https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/archive/refs/tags/microcode-20260812.tar.gz"
# sha256 del tarball bajado el 2026-09-16.
sha256 = "7614616d7b2988c278060486f47de716ef44c19317928cb45ac9e288fafd5bd1"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "static"
strip_debug = false
flags = []
[build.phases]
configure = "echo 'intel-ucode: nada que configurar'"
compile = "echo 'intel-ucode: nada que compilar'"
install = '''
set -e
[ -d intel-ucode ] || { echo "intel-ucode: no está el dir intel-ucode/ — ¿cambió el layout del release?" >&2; exit 1; }
mkdir -p /out/lib/firmware/intel-ucode
cp intel-ucode/* /out/lib/firmware/intel-ucode/
# Aserción ruidosa: el árbol tiene ~130 signatures. Si llegan cuatro, algo se cortó.
n=$(find /out/lib/firmware/intel-ucode -type f | wc -l)
[ "$n" -gt 50 ] || { echo "intel-ucode: sólo $n signatures — el árbol llegó incompleto" >&2; exit 1; }
# La signature de la laptop del usuario. No se recorta el árbol por ella, pero SÍ se comprueba que
# está: si un release futuro la dejara caer, el metal quedaría sin microcódigo en silencio.
[ -f /out/lib/firmware/intel-ucode/06-8c-01 ] || {
echo "intel-ucode: falta 06-8c-01 (TigerLake i7-11370H) — el metal del usuario se queda sin ucode" >&2; exit 1; }
# Blob para carga TEMPRANA: todas las signatures concatenadas, que es exactamente el formato que el
# cargador del kernel espera en kernel/x86/microcode/GenuineIntel.bin.
mkdir -p /out/usr/share/intel-ucode
cat intel-ucode/* > /out/usr/share/intel-ucode/GenuineIntel.bin
[ -s /out/usr/share/intel-ucode/GenuineIntel.bin ] || { echo "intel-ucode: GenuineIntel.bin salió vacío" >&2; exit 1; }
echo "intel-ucode: $n signatures + GenuineIntel.bin ($(wc -c < /out/usr/share/intel-ucode/GenuineIntel.bin) B)"
'''
[deps]
build = ["busybox"]