📶 metal: WiFi por ath10k (QCA9377) + cosmic-diag esperaba con reloj en vez de con hecho
WIFI. El OptiPlex 3060 SÍ tiene WiFi: `pci 0000:02:00.0: [168c:0042]` = Qualcomm Atheros QCA9377. No aparecía interfaz porque el kernel sólo llevaba IWLWIFI. Añadido ATH10K/ATH10K_PCI a linux-metal-dual + el firmware QCA9377 a la imagen + `wifi-up`. El detalle que hace falta: con MODULES desactivado el driver va BUILTIN y prueba el dispositivo a los ~5s pidiendo firmware, pero el rootfs se monta a los ~13s ⇒ `Direct firmware load failed -2` y la tarjeta queda muda, sin módulo que cargar después. `wifi-up` fuerza un re-probe PCI (remove+rescan) con /lib/firmware ya montado. Es la MISMA carrera que la del initramfs con el USB, un piso más abajo. COSMIC-DIAG. La 1ª versión esperaba `sleep 50` y en esa máquina la sesión tarda ~105s en llegar al compositor ⇒ el dmesg «después» se capturó ANTES de que cosmic-comp arrancara y salió byte a byte idéntico al de antes. El viaje se gastó sin dato, y yo leí ese dmesg vacío como «no hubo segfault», que era una conclusión sin respaldo. Ahora espera al HECHO: que cosmic-comp aparezca y luego desaparezca (techo de 6 min). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -73,6 +73,7 @@ scripts/config -d MODULE_SIG -d MODULE_SIG_ALL -d DEBUG_INFO_BTF -d DEBUG_INFO -
|
||||
-e ISO9660_FS -e JOLIET -e DEVTMPFS \
|
||||
-e WLAN -e WIRELESS -e CFG80211 -e MAC80211 -e RFKILL \
|
||||
-e WLAN_VENDOR_INTEL -e IWLWIFI -e IWLMVM -e IWLDVM \
|
||||
-e WLAN_VENDOR_ATH -e ATH_COMMON -e ATH10K -e ATH10K_PCI \
|
||||
-e ETHERNET -e NET_VENDOR_INTEL -e E1000 -e E1000E -e IGB -e IGC \
|
||||
-e NET_VENDOR_REALTEK -e R8169 -e NET_VENDOR_BROADCOM -e TG3 \
|
||||
-e USB_NET_DRIVERS -e USB_USBNET -e USB_NET_CDCETHER -e USB_NET_CDC_NCM -e USB_NET_RNDIS_HOST \
|
||||
|
||||
@@ -174,10 +174,28 @@ cat > "$MERGED/usr/bin/cosmic-diag" <<'DIAG'
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
L=/var/log/cosmic
|
||||
mkdir -p "$L"
|
||||
echo "== cosmic-diag: corriendo la sesión y capturando todo en $L (unos 60s) =="
|
||||
echo "== cosmic-diag: corriendo la sesión y capturando todo en $L =="
|
||||
/bin/busybox dmesg > "$L/dmesg-antes.txt" 2>&1
|
||||
cosmic-start > "$L/run.txt" 2>&1 &
|
||||
sleep 50
|
||||
# ⚠ NO usar un `sleep` fijo. La 1ª versión esperaba 50s y en el OptiPlex 3060 la sesión tarda ~105s
|
||||
# en llegar al compositor (seatd, bus, logind, pipewire, wireplumber, cada uno con su espera) ⇒ el
|
||||
# dmesg «después» se capturaba ANTES de que cosmic-comp arrancara, salía byte a byte idéntico al de
|
||||
# antes, y el viaje se gastaba sin dato. Ahora se espera al HECHO, no al reloj: que cosmic-comp
|
||||
# aparezca y después desaparezca. Ésa es la ventana donde el kernel diría un segfault.
|
||||
vivo() { for c in /proc/[0-9]*/comm; do [ "$(cat "$c" 2>/dev/null)" = cosmic-comp ] && return 0; done; return 1; }
|
||||
i=0; visto=0
|
||||
while [ $i -lt 72 ]; do # 72 × 5s = 6 min de techo
|
||||
if vivo; then
|
||||
[ $visto = 0 ] && echo " cosmic-comp vivo (t=$((i*5))s), esperando a que muera o se estabilice"
|
||||
visto=1
|
||||
elif [ $visto = 1 ]; then
|
||||
echo " cosmic-comp DESAPARECIÓ (t=$((i*5))s) — capturando dmesg"
|
||||
break
|
||||
fi
|
||||
i=$((i + 1)); sleep 5
|
||||
done
|
||||
[ $visto = 0 ] && echo " ⚠ cosmic-comp nunca apareció en $((i*5))s — capturo igual"
|
||||
sleep 2
|
||||
/bin/busybox dmesg > "$L/dmesg-despues.txt" 2>&1
|
||||
/bin/busybox sync
|
||||
echo "== listo. Lo que importa: =="
|
||||
@@ -190,6 +208,71 @@ echo "== evidencia completa en $L — apagá y traé el USB =="
|
||||
DIAG
|
||||
chmod 0755 "$MERGED/usr/bin/cosmic-diag"
|
||||
|
||||
# ── WiFi: la QCA9377 del OptiPlex, y por qué hace falta un re-probe ──────────────────────────────
|
||||
# `pci 0000:02:00.0: [168c:0042]` = Qualcomm Atheros QCA9377, que va por `ath10k`. El kernel ahora lo
|
||||
# lleva compilado dentro (MODULES está desactivado en esta receta), y ahí aparece un problema de
|
||||
# ORDEN: un driver builtin prueba el dispositivo a los ~5 s y pide su firmware, pero el rootfs recién
|
||||
# se monta a los ~13 s ⇒ `Direct firmware load failed -2` y la tarjeta queda muda para siempre. No hay
|
||||
# módulo que cargar después. La salida es forzar un RE-PROBE del dispositivo PCI cuando /lib/firmware
|
||||
# ya existe: `remove` + `rescan`. Es el mismo tipo de carrera que la del initramfs con el USB.
|
||||
FWATH="${FWATH:-/usr/lib/firmware/ath10k}"
|
||||
if [ -d "$FWATH/QCA9377" ]; then
|
||||
n=0
|
||||
for f in "$FWATH"/QCA9377/hw1.0/*.bin*; do
|
||||
[ -r "$f" ] || continue
|
||||
b="$(basename "$f")"; d="$MERGED/lib/firmware/ath10k/QCA9377/hw1.0"
|
||||
mkdir -p "$d"
|
||||
case "$b" in
|
||||
*.zst) zstd -qdf "$f" -o "$d/${b%.zst}" 2>/dev/null && n=$((n+1)) ;;
|
||||
*) cp -a "$f" "$d/" && n=$((n+1)) ;;
|
||||
esac
|
||||
done
|
||||
echo "==> firmware ath10k/QCA9377: $n blobs"
|
||||
else
|
||||
echo " ⚠ sin $FWATH/QCA9377 — el WiFi de esa máquina no va a levantar"
|
||||
fi
|
||||
cat > "$MERGED/usr/bin/wifi-up" <<'WIFI'
|
||||
#!/bin/sh
|
||||
# wifi-up <SSID> <clave> — conecta la WiFi y muestra la IP para entrar por SSH.
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
SSID="$1"; PSK="$2"
|
||||
[ -n "$SSID" ] || { echo "uso: wifi-up <SSID> <clave>"; exit 1; }
|
||||
# Re-probe: ath10k pidió su firmware antes de que existiera /lib/firmware (ver el comentario de la
|
||||
# imagen). Sin esto la tarjeta no aparece como interfaz aunque el driver esté.
|
||||
for d in /sys/bus/pci/devices/*; do
|
||||
[ "$(cat "$d/vendor" 2>/dev/null)" = "0x168c" ] || continue
|
||||
echo "re-probando $(basename "$d") para que ath10k reintente el firmware…"
|
||||
echo 1 > "$d/remove" 2>/dev/null; sleep 2
|
||||
echo 1 > /sys/bus/pci/rescan 2>/dev/null; sleep 4
|
||||
done
|
||||
IF=""
|
||||
for i in /sys/class/net/*; do
|
||||
case "$(basename "$i")" in wlan*|wlp*) IF="$(basename "$i")"; break ;; esac
|
||||
done
|
||||
[ -n "$IF" ] || { echo "no apareció interfaz wifi. Mirá: dmesg | grep -i ath10k"; exit 1; }
|
||||
echo "interfaz: $IF"
|
||||
ip link set "$IF" up
|
||||
printf 'network={\n\tssid="%s"\n\tpsk="%s"\n}\n' "$SSID" "$PSK" > /tmp/wpa.conf
|
||||
wpa_supplicant -B -i "$IF" -c /tmp/wpa.conf -Dnl80211 || { echo "wpa_supplicant falló"; exit 1; }
|
||||
sleep 6
|
||||
cat > /tmp/udhcpc.script <<'US'
|
||||
#!/bin/sh
|
||||
case "$1" in
|
||||
bound|renew)
|
||||
ifconfig "$interface" "$ip" netmask "${subnet:-255.255.255.0}"
|
||||
[ -n "$router" ] && route add default gw "${router%% *}" dev "$interface" 2>/dev/null
|
||||
[ -n "$dns" ] && { : > /etc/resolv.conf; for d in $dns; do echo "nameserver $d" >> /etc/resolv.conf; done; }
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
US
|
||||
chmod +x /tmp/udhcpc.script
|
||||
udhcpc -i "$IF" -n -q -s /tmp/udhcpc.script
|
||||
ip -4 addr show "$IF" | grep -w inet || echo "sin IPv4 — ¿clave correcta? wpa_cli status"
|
||||
echo "== desde el laptop: ssh -i ~/.ssh/hammer-metal root@<la IP de arriba> =="
|
||||
WIFI
|
||||
chmod 0755 "$MERGED/usr/bin/wifi-up"
|
||||
|
||||
# ── getty en tty1: el prompt TIENE que salir por la PANTALLA ────────────────────────────────────
|
||||
# Lección del 1er viaje físico de KDE, que costó un USB quemado: el CMDLINE horneado es
|
||||
# `console=tty0 console=ttyS0,115200 …` y el kernel hace /dev/console = la ÚLTIMA `console=` ⇒ ttyS0.
|
||||
|
||||
Reference in New Issue
Block a user