#!/usr/bin/env sh # metal-firmware.sh — inyecta el firmware del WiFi AX201 (y reg.db) en /lib/firmware de un rootfs. # # El firmware de iwlwifi son BLOBS binarios NO compilables desde fuente (Intel no libera el código); la # soberanía de hammer (build-from-source) no aplica acá — son datos fijos como el microcódigo de la CPU. # Se fijan por contenido (igual que un tarball pinned): se copian de un linux-firmware ya presente y se # descomprimen a .ucode plano (el kernel metal NO habilita FW_LOADER_COMPRESS, así evitamos esa dep). # # Target: Intel Wi-Fi 6 AX201 [8086:a0f0] en TigerLake ⇒ familias QuZ-a0-hr-b0 + cc-a0 (el driver elige # la API más alta que soporta) + regulatory.db(+.p7s) que cfg80211 verifica con la clave built-in. # # Uso: scripts/metal-firmware.sh # Vars: FWSRC dir origen del firmware (default /lib/firmware del host) # # TODO(soberanía): reemplazar FWSRC=host por un pin a un commit de linux-firmware (recipe fetch+extract). set -eu DST="${1:?uso: metal-firmware.sh }" FWSRC="${FWSRC:-/lib/firmware}" OUT="$DST/lib/firmware" mkdir -p "$OUT" # patrones de firmware que el AX201 puede pedir (ambas familias, todas las API presentes) PATTERNS="iwlwifi-QuZ-a0-hr-b0-*.ucode iwlwifi-cc-a0-*.ucode" n=0 for pat in $PATTERNS; do for src in "$FWSRC"/$pat "$FWSRC"/$pat.zst "$FWSRC"/$pat.xz; do [ -e "$src" ] || continue base=$(basename "$src") case "$base" in *.zst) dst="$OUT/${base%.zst}"; zstd -q -d -f -o "$dst" "$src" ;; *.xz) dst="$OUT/${base%.xz}"; xz -dc "$src" > "$dst" ;; *) dst="$OUT/$base"; cp "$src" "$dst" ;; esac n=$((n+1)) done done # regulatory db (texto firmado; cfg80211 lo carga vía firmware loader y verifica .p7s con clave built-in) for f in regulatory.db regulatory.db.p7s; do if [ -e "$FWSRC/$f" ]; then cp "$FWSRC/$f" "$OUT/$f"; n=$((n+1)); fi done [ "$n" -gt 0 ] || { echo "metal-firmware: NO encontré firmware AX201 en $FWSRC" >&2; exit 1; } echo "metal-firmware: $n blobs → $OUT" ls "$OUT" | sed 's/^/ /'