Cierra el gestor de sesión de PipeWire, que es lo que separa «PipeWire acepta clientes» de «PipeWire tiene dispositivos». Su política está escrita en Lua, así que arrastró una receta de Lua que hubo que autorar entera. LO QUE LA RECETA DE LUA TIENE QUE INVENTAR: el Makefile de upstream sólo produce liblua.a y los binarios — **no hay regla de .so ni fichero pkg-config**, los agrega cada distro. Acá la compartida se enlaza a mano desde la .a con --whole-archive (una estática sólo aporta lo referenciado y hay que llevarse todo) y el .pc se escribe con los TRES nombres que se usan por ahí, porque wireplumber prueba lua-5.4, lua5.4 y lua54 en orden. `-fPIC` no es opcional: libwplua es un objeto compartido. Dos símbolos más en libelogind (tawasuyu 087230054 → re-pineado 749edfe41): sd_uid_get_seats y sd_uid_get_state, que module-logind.c de wireplumber usa para saber si el usuario está en un asiento antes de tomar los dispositivos. Van 28 símbolos sd-*. **EL `Devices:` VACÍO DE wpctl NO ES UN FALLO DE wireplumber: el kernel no tiene ALSA.** recipes/linux-metal.toml:111 lo apaga explícito (`-d SOUND -d SND`), así que no hay /dev/snd que enumerar. Y esto NO se dio por supuesto: se agregó una ich9-intel-hda emulada a QEMU (AUDIO=1, ahora el default de run-qemu-desktop.sh) justo porque un «Devices: vacío» se lee IGUAL si wireplumber funciona sobre una VM sin hardware que si no funciona. Con tarjeta y sin ALSA en el kernel, el resultado no cambia — la ambigüedad queda resuelta. Encender el sonido en la distro es una decisión con costo (re-sellar el kernel, rehacer la imagen metal) y queda a la vista en vez de escondida en un default. Bug propio destapado en el camino: el bloque de wireplumber quedó DUPLICADO en gnome-start y había DOS wireplumber peleándose el grafo. El síntoma no era un error sino una lista de clientes que se lee normal si no se cuenta: dos «WirePlumber» con pids distintos en wpctl status. Y una nota de ADR 0012 que costó un rato: la cascada de libelogind cortó a mitad y dejó el `output/` de mutter a medio hacer; el reintento moría con «error opening '...c.o.d': No such file or directory». Un `rm -rf output` en el configure NO alcanzó —el árbol tenía estado viejo más allá del build dir—; lo que lo arregló fue BORRAR work/sources/mutter-* para que el fetch lo re-extraiga limpio. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
71 lines
3.3 KiB
Bash
Executable File
71 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# run-qemu-desktop.sh — arranca la imagen KDE en QEMU (virtio-gpu + software GL) de forma REPRODUCIBLE.
|
|
# Antes era un comando ad-hoc. Por defecto headless (DISPLAY=none) para diagnóstico por serial sin
|
|
# interferir con la sesión mirada del laptop; DISP=gtk para ver la ventana (necesita DISPLAY=:0 Xwayland,
|
|
# y cada restart de mirada mata la ventana).
|
|
#
|
|
# scripts/kde/run-qemu-desktop.sh # headless, serial → work/qemu-desktop-serial.log
|
|
# DISP=gtk scripts/kde/run-qemu-desktop.sh # ventana gráfica (virtio-gpu por gtk)
|
|
# TIMEOUT=90 scripts/kde/run-qemu-desktop.sh # mata QEMU a los 90s (diagnóstico automático)
|
|
set -euo pipefail
|
|
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
|
|
|
|
IMG="${IMG:-work/hammer-kde-qemu.img}"
|
|
SERIAL="${SERIAL:-work/qemu-desktop-serial.log}"
|
|
OVMF_CODE="${OVMF_CODE:-/usr/share/edk2/x64/OVMF_CODE.4m.fd}"
|
|
OVMF_VARS_SRC="${OVMF_VARS_SRC:-/usr/share/edk2/x64/OVMF_VARS.4m.fd}"
|
|
VARS="${VARS:-work/qemu-desktop-OVMF_VARS.fd}"
|
|
DISP="${DISP:-none}"
|
|
MEM="${MEM:-4G}"
|
|
SMP="${SMP:-4}"
|
|
|
|
[ -r "$IMG" ] || { echo "falta $IMG — corré scripts/kde/qemu-desktop-image.sh" >&2; exit 1; }
|
|
[ -r "$OVMF_CODE" ] || { echo "falta OVMF_CODE ($OVMF_CODE)" >&2; exit 1; }
|
|
# copia escribible de las VARS (pflash necesita rw; la del sistema es read-only)
|
|
[ -r "$VARS" ] || cp "$OVMF_VARS_SRC" "$VARS"
|
|
|
|
case "$DISP" in
|
|
gtk) DISPLAY_ARGS=(-display gtk -device virtio-gpu-pci) ;;
|
|
none) DISPLAY_ARGS=(-display none -device virtio-gpu-pci) ;;
|
|
*) DISPLAY_ARGS=(-display "$DISP" -device virtio-gpu-pci) ;;
|
|
esac
|
|
|
|
# serial nuevo cada corrida (el diagnóstico depende de que no se mezcle con boots viejos)
|
|
: > "$SERIAL"
|
|
|
|
QEMU_ARGS=(
|
|
-machine q35 -accel kvm -cpu host
|
|
-m "$MEM" -smp "$SMP"
|
|
-vga none # virtio-gpu-pci (abajo) es el ÚNICO display: sin esto QEMU añade una VGA estándar por
|
|
# defecto y OVMF pinta el GOP ahí ⇒ simpledrm (card1) muestra el framebuffer EFI y kwin
|
|
# pinta en virtio-gpu (card0, otro device que no se ve) ⇒ pantalla congelada en TianoCore.
|
|
# Con -vga none, OVMF usa virtio-gpu ⇒ virtio-gpu-DRM expulsa simpledrm ⇒ un solo output.
|
|
-drive if=pflash,format=raw,unit=0,file="$OVMF_CODE",readonly=on
|
|
-drive if=pflash,format=raw,unit=1,file="$VARS"
|
|
-drive file="$IMG",format=raw,if=virtio
|
|
"${DISPLAY_ARGS[@]}"
|
|
-serial "file:$SERIAL"
|
|
-monitor "unix:${MON:-work/qemu-monitor.sock},server,nowait"
|
|
-no-reboot
|
|
)
|
|
|
|
# AUDIO=1 (default): darle a la VM una tarjeta de sonido EMULADA. No es para oír nada —el backend es
|
|
# `none`, que descarta las muestras— sino para que HAYA UN DISPOSITIVO QUE ENUMERAR.
|
|
#
|
|
# Sin esto, `wpctl status` sale con «Devices:» vacío y un único sink `auto_null`, y ese resultado es
|
|
# AMBIGUO: se lee igual si wireplumber funciona sobre una VM sin hardware que si wireplumber no
|
|
# funciona. Con una ich9-intel-hda emulada, el árbol de /sys/class/sound existe y la respuesta
|
|
# distingue las dos cosas. AUDIO=0 para volver al caso sin tarjeta.
|
|
if [ "${AUDIO:-1}" = 1 ]; then
|
|
QEMU_ARGS+=(-audiodev none,id=snd0 -device ich9-intel-hda -device hda-duplex,audiodev=snd0)
|
|
fi
|
|
|
|
echo "==> QEMU (DISP=$DISP, serial=$SERIAL)"
|
|
echo " imagen: $IMG"
|
|
if [ -n "${TIMEOUT:-}" ]; then
|
|
echo " TIMEOUT=${TIMEOUT}s (auto-kill)"
|
|
exec timeout --signal=KILL "${TIMEOUT}" qemu-system-x86_64 "${QEMU_ARGS[@]}"
|
|
else
|
|
exec qemu-system-x86_64 "${QEMU_ARGS[@]}"
|
|
fi
|