mirada/USB: telemetría persistente en el pendrive + bump a mirada de hoy (fix musl en tawasuyu)
TELEMETRÍA (el pedido): el rootfs de la imagen es un initramfs = RAM pura y los logs iban a /run (tmpfs) ⇒ al apagar la máquina ajena no sobrevivía NADA. Ahora la imagen lleva 2da partición FAT32 MIRADALOG (512M), montada por findfs+LABEL con -o sync (un cuelgue de GPU o corte de luz no se lleva los logs). Cada arranque vuelca run-NNNN/ con: resumen (modo/GPU/driver), hardware (PCI vía sysfs, módulos, DRM, input, firmware), pantallas (status/modes por conector), dmesg ANTES y DESPUÉS de mirada, seatd, y el log del compositor+greeter con RUST_LOG=wgpu_core=debug + EGL_LOG_LEVEL=debug + LIBGL_DEBUG=verbose (para ver por qué wgpu eligió el backend y si hay float16). Shell de rescate + . FAT32 a propósito: el pendrive se lee después desde cualquier SO. metal-usb-sdboot.sh gana DATA_MB/DATA_LABEL genéricos (partición de datos opcional en la GPT). GOTCHAs verificados antes de confiar: el kernel linux-generic SÍ trae VFAT_FS=y + NLS + USB_STORAGE=y (sin eso no montaba); el busybox de Alpine NO trae el applet 00:00.0 Host bridge: Intel Corporation Tiger Lake-UP3/H35 4 cores Host Bridge/DRAM Registers (rev 01) 00:02.0 VGA compatible controller: Intel Corporation TigerLake-LP GT2 [Iris Xe Graphics] (rev 01) 00:04.0 Signal processing controller: Intel Corporation TigerLake-LP Dynamic Tuning Processor Participant (rev 01) 00:07.0 PCI bridge: Intel Corporation Tiger Lake-LP Thunderbolt 4 PCI Express Root Port #0 (rev 01) 00:08.0 System peripheral: Intel Corporation GNA Scoring Accelerator module (rev 01) 00:0a.0 Signal processing controller: Intel Corporation Tigerlake Telemetry Aggregator Driver (rev 01) 00:0d.0 USB controller: Intel Corporation Tiger Lake-LP Thunderbolt 4 USB Controller (rev 01) 00:0d.2 USB controller: Intel Corporation Tiger Lake-LP Thunderbolt 4 NHI #0 (rev 01) 00:12.0 Serial controller: Intel Corporation 500 Series Chipset Family On-Package Integrated Sensor Hub (rev 20) 00:14.0 USB controller: Intel Corporation 500 Series Chipset Family On-Package USB 3.2 Gen 2x1 (10 Gbs) xHCI Host Controller (rev 20) 00:14.2 RAM memory: Intel Corporation 500 Series Chipset Family On-Package Shared SRAM (rev 20) 00:14.3 Network controller: Intel Corporation Wi-Fi 6 AX201 (rev 20) 00:15.0 Serial bus controller: Intel Corporation 500 Series Chipset Family On-Package I2C Controller #0 (rev 20) 00:15.1 Serial bus controller: Intel Corporation 500 Series Chipset Family On-Package I2C Controller #1 (rev 20) 00:16.0 Communication controller: Intel Corporation 500 Series Chipset Family On-Package CSME HECI #1 (rev 20) 00:1c.0 PCI bridge: Intel Corporation 500 Series Chipset Family On-Package PCI Express Root Port #5 (rev 20) 00:1d.0 PCI bridge: Intel Corporation 500 Series Chipset Family On-Package PCI Express Root Port #9 (rev 20) 00:1f.0 ISA bridge: Intel Corporation 500 Series Chipset Family On-Package eSPI Controller (rev 20) 00:1f.3 Multimedia audio controller: Intel Corporation 500 Series Chipset Family On-Package High Definition Audio (HD Audio) (rev 20) 00:1f.4 SMBus: Intel Corporation 500 Series Chipset Family On-Package System Management Bus (SMBus) (rev 20) 00:1f.5 Serial bus controller: Intel Corporation 500 Series Chipset Family On-Package SPI (flash) Controller (rev 20) 39:00.0 Non-Volatile memory controller: Kingston Technology Company, Inc. NV2 NVMe SSD [SM2267XT] (DRAM-less) (rev 03) 3a:00.0 Non-Volatile memory controller: ADATA Technology Co., Ltd. IM2P33F3 NVMe SSD (DRAM-less) (rev 03) (sí findfs/blkid) ⇒ el dump de PCI lee /sys/bus/pci/devices/*/ directo; sintaxis del init validada con busybox ash (no bash). BUMP mirada: el pin era 9967b02c (18-jun) — 439 commits viejo. Ahora 9a17fefc, que incluye el fix de portabilidad a musl que hice en tawasuyu (ioctl: glibc usa c_ulong, musl c_int ⇒ las constantes DRM casteaban mal y mirada-compositor NO compilaba para musl). mirada-compositor ya selló (87ced528); greeter/ctl en curso. + scripts/kde/{metal-desktop-image,plasma-start-metal}.sh del hilo KDE (imagen de escritorio en metal). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -25,3 +25,37 @@
|
||||
`hammer --store ./store hydrate b3:fded43c0… <destino>` (o copialo de `store/fded43c0…-linux-generic/boot/bzImage`). Reconstruible: `hammer build recipes/linux-generic.toml` (deps flex/bison/m4/openssl/elfutils + zig-0.13, ya en el worker).
|
||||
|
||||
Dudas del kernel (drivers a agregar, cmdline, otra config) → pedímelas y reviso `linux-generic.toml`.
|
||||
|
||||
## 📥 Telemetría persistente en el propio pendrive (2026-07-14)
|
||||
|
||||
**El problema:** el rootfs de esta imagen es un **initramfs = RAM pura**. Los logs iban a `/run` (tmpfs):
|
||||
al apagar la máquina ajena no sobrevivía **nada**. Y la GPU a probar está lejos — un viaje sin datos es
|
||||
un viaje perdido.
|
||||
|
||||
**La solución:** la imagen ahora trae una **2da partición FAT32 `MIRADALOG`** (512M, `DATA_MB` en
|
||||
`scripts/metal-usb-sdboot.sh`, que ganó soporte genérico de partición de datos). FAT32 a propósito: el
|
||||
pendrive se lee después **desde cualquier SO** (Windows/Mac/Linux) sin herramientas.
|
||||
|
||||
`/sbin/init` la monta por `findfs LABEL=MIRADALOG` con **`-o sync`** (cada escritura va al medio: un
|
||||
cuelgue duro de la GPU o un corte de luz no se lleva los logs) y vuelca todo en `run-NNNN/`
|
||||
(numerada: cada arranque/reintento tiene su carpeta):
|
||||
|
||||
| fichero | qué trae |
|
||||
|---|---|
|
||||
| `00-resumen.txt` | modo (hw/sw), cmdline, GPU+driver, DRM, si la telemetría persiste |
|
||||
| `01-hardware.txt` | uname, cpu, RAM, **PCI vía sysfs** (vendor/device/class/**driver**), módulos, /dev/dri, nouveau sysfs, input, firmware nvidia presente |
|
||||
| `02-pantallas.txt` | por conector: `status`/`modes`/`enabled` |
|
||||
| `03-dmesg-early.txt` | dmesg **antes** de mirada → si nouveau bindeó y si el firmware gp106 cargó |
|
||||
| `04-seatd.log` | seatd (DRM master / sesión) |
|
||||
| `05-mirada.log` | compositor + greeter, con `RUST_LOG=wgpu_core=debug,wgpu_hal=debug` + `EGL_LOG_LEVEL=debug` + `LIBGL_DEBUG=verbose` ⇒ **por qué wgpu eligió el backend y si hay float16** |
|
||||
| `06-dmesg-final.txt` | dmesg **después** + exit code → cuelgues/oops/reset de nouveau |
|
||||
| `07-estado-final.txt`| procesos, RAM, /dev/dri al final |
|
||||
|
||||
**GOTCHA:** el busybox de Alpine **no trae el applet `lspci`** (sí `findfs`/`blkid`). El dump de PCI se
|
||||
hace leyendo `/sys/bus/pci/devices/*/{vendor,device,class}` + `readlink driver` — más soberano igual.
|
||||
`vendor 0x10de` = NVIDIA; `class 0x0300*` = VGA.
|
||||
|
||||
**En la máquina ajena:** arranca solo. Si el compositor termina/falla, cae a un shell de rescate con la
|
||||
telemetría ya sincronizada; `relanzar` reintenta y crea un `run-NNNN` nuevo. Se puede apagar sin ceremonia.
|
||||
|
||||
**Al volver:** montar la partición `MIRADALOG` y leer `run-NNNN/`.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# maneja DRM/GBM/EGL/libseat/libinput directo y dentro del cual corre `mirada-greeter` como cliente.
|
||||
# Cierra la cadena de sesión gráfica de tawasuyu.
|
||||
#
|
||||
# Receta Cargo (patrón arje-zero/mirada-greeter): monorepo tawasuyu al commit fijado 9967b02c (reusa
|
||||
# Receta Cargo (patrón arje-zero/mirada-greeter): monorepo tawasuyu al commit fijado 9a17fefc (reusa
|
||||
# el árbol vendoreado). `-p mirada-compositor`, link DINÁMICO (smithay enlaza libdrm/gbm/seat/input
|
||||
# + dlopen de EGL/wayland/xkbcommon).
|
||||
#
|
||||
@@ -17,7 +17,7 @@ version = "0.0.1"
|
||||
|
||||
[source]
|
||||
repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git"
|
||||
commit = "9967b02cf597df6d065edbad8d6669b5653d4928"
|
||||
commit = "9a17fefcbf63ba74f45cfabc4e608e391e397b17"
|
||||
|
||||
[build]
|
||||
compiler = "zig-cc"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# mirada-ctl — control del compositor mirada por línea de comandos (estilo swaymsg/hyprctl: dispara
|
||||
# acciones de escritorio). Del monorepo tawasuyu. Etapa G: poblar el catálogo con apps propias.
|
||||
#
|
||||
# Receta Cargo (patrón arje-zero/dominium-cli): source = monorepo tawasuyu a commit fijado 9967b02c
|
||||
# Receta Cargo (patrón arje-zero/dominium-cli): source = monorepo tawasuyu a commit fijado 9a17fefc
|
||||
# (Cargo.lock committeado => build --locked reproducible), `-p mirada-ctl`, estático zig-cc. bin==package.
|
||||
# Es el CLIENTE de control (IPC), no el compositor GPU ⇒ static-musl sano. Comparte el commit => reusa
|
||||
# el árbol fuente fetcheado.
|
||||
@@ -11,7 +11,7 @@ version = "0.0.1"
|
||||
|
||||
[source]
|
||||
repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git"
|
||||
commit = "9967b02cf597df6d065edbad8d6669b5653d4928"
|
||||
commit = "9a17fefcbf63ba74f45cfabc4e608e391e397b17"
|
||||
|
||||
[build]
|
||||
compiler = "zig-cc"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Vulkan). Ver docs/14-mesa-stack.md §«Lado tawasuyu».
|
||||
#
|
||||
# Receta Cargo (patrón arje-zero/mirada-ctl): fuente = monorepo tawasuyu al MISMO commit fijado
|
||||
# 9967b02c ⇒ reusa el árbol fetcheado y vendoreado (cargo vendor vendorea TODO el Cargo.lock del
|
||||
# 9a17fefc ⇒ reusa el árbol fetcheado y vendoreado (cargo vendor vendorea TODO el Cargo.lock del
|
||||
# workspace, así que wgpu/winit/naga ya están). `-p mirada-greeter`, bin == package.
|
||||
#
|
||||
# link = DYNAMIC (a diferencia de arje-zero estático): wgpu/winit hacen dlopen de libEGL/libGLESv2/
|
||||
@@ -16,7 +16,7 @@ version = "0.0.1"
|
||||
|
||||
[source]
|
||||
repo = "gitea@git.tawasuyu.net:tawasuyu/tawasuyu.git"
|
||||
commit = "9967b02cf597df6d065edbad8d6669b5653d4928"
|
||||
commit = "9a17fefcbf63ba74f45cfabc4e608e391e397b17"
|
||||
|
||||
[build]
|
||||
compiler = "zig-cc"
|
||||
|
||||
Executable
+65
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env bash
|
||||
# metal-desktop-image.sh — arma la IMAGEN DE DISCO EFI con el escritorio KDE completo, para METAL.
|
||||
#
|
||||
# Funde dos rootfs y delega el particionado en scripts/install-image-efi.sh (ADR 0010 paso 5: EFI-stub
|
||||
# soberano, initrd chico de pivote → switch_root a la ext4 real ⇒ el sistema NO vive en RAM, que es lo que
|
||||
# hace inviable el camino de metal-usb-sdboot.sh con un escritorio de ~7 GB).
|
||||
#
|
||||
# work/metal-rootfs base metal: arje-zero PID1 + busybox + firmware (i915 tgl_* + iwlwifi AX201)
|
||||
# work/kde-metal-rootfs KDE hidratado del store sellado (206 pkgs, cierre runtime completo)
|
||||
# → work/metal-desktop-rootfs (hardlinks, NO copia: no muta ninguno de los dos)
|
||||
# → work/hammer-kde-metal.img GPT: ESP(bzImage EFI-stub + initrd pivote) + ext4 / + /store + /var/lib/hammer
|
||||
#
|
||||
# Uso: scripts/kde/metal-desktop-image.sh
|
||||
# BOOT=1 KVM=1 scripts/kde/metal-desktop-image.sh # + arranca en OVMF para validar antes de quemar
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
|
||||
|
||||
BASE="${BASE:-work/metal-rootfs}"
|
||||
KDE="${KDE:-work/kde-metal-rootfs}"
|
||||
MERGED="${MERGED:-work/metal-desktop-rootfs}"
|
||||
IMG="${IMG:-work/hammer-kde-metal.img}"
|
||||
|
||||
[ -d "$BASE" ] || { echo "falta $BASE (scripts/metal-iso.sh lo arma)" >&2; exit 1; }
|
||||
[ -d "$KDE" ] || { echo "falta $KDE (hidratá con scripts/kde/hydrate-recipes.py en el worker y bajalo)" >&2; exit 1; }
|
||||
|
||||
echo "==> fundiendo rootfs por hardlinks (no muta los originales)"
|
||||
# Los dos árboles son COMPLEMENTARIOS, no rivales:
|
||||
# base → musl libc + loader + busybox + arje-zero + firmware (el "sustrato soberano")
|
||||
# KDE → Qt/KF6/Plasma/apps (complete-closure.sh NO hidrata la libc:
|
||||
# "los sonames del sustrato base los provee la base del sistema destino")
|
||||
# Se pone la base primero y KDE encima; en los pocos nombres que coincidan gana KDE.
|
||||
rm -rf "$MERGED"
|
||||
cp -al "$BASE" "$MERGED"
|
||||
cp -al --remove-destination "$KDE"/. "$MERGED"/
|
||||
|
||||
echo "==> instalando /usr/bin/plasma-start"
|
||||
install -Dm755 scripts/kde/plasma-start-metal.sh "$MERGED/usr/bin/plasma-start"
|
||||
|
||||
# El escritorio necesita estos dirs runtime; el rootfs es de sólo-lectura hasta que switch_root monta la ext4.
|
||||
mkdir -p "$MERGED/root/.config" "$MERGED/root/.cache" "$MERGED/run/user/0" "$MERGED/tmp"
|
||||
chmod 1777 "$MERGED/tmp"
|
||||
|
||||
# motd: que el usuario sepa qué correr al llegar al shell.
|
||||
cat > "$MERGED/etc/motd" <<'MOTD'
|
||||
|
||||
#-- hammer :: escritorio KDE Plasma 6 (metal) ------------------------------
|
||||
Todo construido desde fuente con hammer (musl + zig-cc), sin binarios ajenos.
|
||||
|
||||
Arrancar el escritorio: plasma-start
|
||||
Logs si algo falla: /tmp/kwin.log /tmp/plasmashell.log
|
||||
Diagnóstico GPU: dmesg | grep -iE 'i915|drm'
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
MOTD
|
||||
|
||||
echo "==> rootfs fundido: $(du -sh "$MERGED" | cut -f1) ($(find "$MERGED" -name '*.so*' | wc -l) .so, $(ls "$MERGED"/usr/bin | wc -l) bins)"
|
||||
|
||||
# La ext4 de / debe entrar el rootfs + holgura. Se calcula del tamaño real y se redondea hacia arriba.
|
||||
need_mb=$(du -sm "$MERGED" | cut -f1)
|
||||
ROOT_SIZE="${ROOT_SIZE:-$(( need_mb + 1536 ))}"
|
||||
echo "==> ROOT_SIZE=${ROOT_SIZE} MiB (rootfs ${need_mb} MiB + holgura)"
|
||||
|
||||
export ROOTFS="$MERGED" IMG ROOT_SIZE
|
||||
export ESP_MB="${ESP_MB:-128}" STORE_SIZE="${STORE_SIZE:-512}" STATE_SIZE="${STATE_SIZE:-768}"
|
||||
exec ./scripts/install-image-efi.sh
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
#!/bin/sh
|
||||
# plasma-start — arranca la sesión Plasma en METAL (se instala como /usr/bin/plasma-start en el rootfs).
|
||||
#
|
||||
# Derivado de scripts/kde/run-plasma-headless.sh (la sesión VALIDADA headless en el worker), con dos
|
||||
# cambios para hardware real:
|
||||
# - kwin_wayland SIN `--virtual`: usa el backend DRM real (/dev/dri/card0, i915 built-in del kernel metal).
|
||||
# - SIN los overrides de software (swrast/LIBGL_ALWAYS_SOFTWARE/QT_QUICK_BACKEND=software): en la
|
||||
# TigerLake el driver es **iris** (mesa hidratado trae /usr/lib/dri/iris_dri.so).
|
||||
#
|
||||
# NO se autoarranca desde el seed card de arje-zero a propósito: en un bringup, si Plasma falla querés el
|
||||
# shell de la console-getty para leer los logs, no una pantalla negra. Se lanza a mano desde ese shell.
|
||||
#
|
||||
# Logs: /tmp/{kwin,kamd,plasmashell}.log Salir: Ctrl-C (mata la sesión)
|
||||
set -u
|
||||
|
||||
export LD_LIBRARY_PATH=/usr/lib64:/usr/lib/qt6:/usr/lib:/lib
|
||||
export QT_PLUGIN_PATH=/usr/lib64/qt6/plugins:/usr/lib/qt6/plugins
|
||||
export QML2_IMPORT_PATH=/usr/lib64/qt6/qml:/usr/lib/qt6/qml
|
||||
export QML_IMPORT_PATH=$QML2_IMPORT_PATH
|
||||
export XDG_DATA_DIRS=/usr/share
|
||||
export XDG_RUNTIME_DIR=/run/user/0
|
||||
export XDG_CONFIG_HOME=/root/.config
|
||||
export XDG_CACHE_HOME=/root/.cache
|
||||
export HOME=/root
|
||||
export LIBGL_DRIVERS_PATH=/usr/lib/dri
|
||||
export QT_QPA_PLATFORM=wayland
|
||||
|
||||
mkdir -p "$XDG_RUNTIME_DIR" "$XDG_CONFIG_HOME" "$XDG_CACHE_HOME" /root
|
||||
chmod 700 "$XDG_RUNTIME_DIR"
|
||||
|
||||
echo "== hammer :: sesión Plasma (metal) =="
|
||||
echo "-- GPU: $(ls /dev/dri/ 2>/dev/null | tr '\n' ' ')"
|
||||
[ -e /dev/dri/card0 ] || echo " !! no hay /dev/dri/card0 — ¿i915 no cargó? (dmesg | grep i915)"
|
||||
echo "-- input: $(ls /dev/input/ 2>/dev/null | tr '\n' ' ')"
|
||||
|
||||
# D-Bus de sesión: kwin/plasmashell lo exigen.
|
||||
if [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]; then
|
||||
DBUS_SESSION_BUS_ADDRESS=$(dbus-daemon --session --fork --print-address 2>/dev/null)
|
||||
export DBUS_SESSION_BUS_ADDRESS
|
||||
fi
|
||||
echo "-- dbus: ${DBUS_SESSION_BUS_ADDRESS:-NO ARRANCÓ}"
|
||||
|
||||
# Compositor sobre DRM real.
|
||||
echo "-- lanzando kwin_wayland (DRM)…"
|
||||
/usr/bin/kwin_wayland >/tmp/kwin.log 2>&1 &
|
||||
KWIN=$!
|
||||
i=0
|
||||
while [ $i -lt 40 ]; do
|
||||
[ -S "$XDG_RUNTIME_DIR/wayland-0" ] && break
|
||||
kill -0 $KWIN 2>/dev/null || { echo " !! kwin murió:"; tail -25 /tmp/kwin.log; exit 1; }
|
||||
i=$((i+1)); sleep 0.5
|
||||
done
|
||||
if [ -S "$XDG_RUNTIME_DIR/wayland-0" ]; then
|
||||
echo " compositor OK (wayland-0)"
|
||||
else
|
||||
echo " !! kwin no expuso wayland-0:"; tail -25 /tmp/kwin.log; exit 1
|
||||
fi
|
||||
export WAYLAND_DISPLAY=wayland-0
|
||||
|
||||
# kactivitymanagerd: plasmashell ABORTA si no corre (registra su servicio D-Bus).
|
||||
KAMD=$(ls /usr/lib*/libexec/kactivitymanagerd 2>/dev/null | head -1)
|
||||
if [ -n "$KAMD" ]; then "$KAMD" >/tmp/kamd.log 2>&1 & sleep 2; echo "-- kactivitymanagerd lanzado"; fi
|
||||
|
||||
echo "-- lanzando plasmashell…"
|
||||
/usr/bin/plasmashell >/tmp/plasmashell.log 2>&1 &
|
||||
sleep 8
|
||||
echo "-- procesos: $(ps axo comm 2>/dev/null | grep -E 'kwin|plasma' | sort -u | tr '\n' ' ')"
|
||||
echo
|
||||
echo "Escritorio arriba. Logs en /tmp/{kwin,kamd,plasmashell}.log"
|
||||
echo "Apps: konsole, dolphin, systemsettings, spectacle, okular… (lanzalas desde otra tty o krunner)"
|
||||
echo "Ctrl-C para terminar la sesión."
|
||||
wait $KWIN
|
||||
@@ -73,13 +73,34 @@ echo "==> ESP poblada ($(du -h "$ESP" | cut -f1)):"
|
||||
|
||||
# 4) imagen de disco GPT: GPT primaria (1MiB) + ESP (en sector 2048) + GPT backup
|
||||
esp_sectors=$(( espkb * 2 )) # KiB→sectores de 512
|
||||
rm -f "$IMG"; truncate -s "$(( (2048 + esp_sectors + 2048) * 512 ))" "$IMG"
|
||||
echo "label: gpt
|
||||
start=2048, size=$esp_sectors, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, name=\"EFI System Partition\"" | sfdisk --quiet "$IMG"
|
||||
|
||||
# Partición de DATOS opcional (DATA_MB>0): FAT32 con etiqueta, para que el sistema live escriba ahí lo
|
||||
# que deba SOBREVIVIR al apagado (telemetría/logs). El rootfs de esta imagen es un initramfs = RAM pura:
|
||||
# sin esta partición NO queda rastro de nada al cortar la luz. FAT32 (no ext4) a propósito: el pendrive
|
||||
# se lee después desde CUALQUIER máquina (Windows/Mac/Linux) sin herramientas.
|
||||
DATA_MB="${DATA_MB:-0}"
|
||||
DATA_LABEL="${DATA_LABEL:-HAMMERLOG}"
|
||||
data_sectors=0
|
||||
if [ "$DATA_MB" -gt 0 ]; then
|
||||
DATA="$WORK/data.img"; rm -f "$DATA"; truncate -s "$(( DATA_MB * 1024 * 1024 ))" "$DATA"
|
||||
"$MT/mformat" -F -v "$DATA_LABEL" -i "$DATA" ::
|
||||
data_sectors=$(( DATA_MB * 2048 ))
|
||||
echo "==> partición de datos FAT32 ${DATA_MB}M etiqueta=$DATA_LABEL (telemetría persistente)"
|
||||
fi
|
||||
|
||||
rm -f "$IMG"; truncate -s "$(( (2048 + esp_sectors + data_sectors + 2048) * 512 ))" "$IMG"
|
||||
{
|
||||
echo "label: gpt"
|
||||
echo "start=2048, size=$esp_sectors, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, name=\"EFI System Partition\""
|
||||
[ "$data_sectors" -gt 0 ] && \
|
||||
echo "start=$(( 2048 + esp_sectors )), size=$data_sectors, type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, name=\"$DATA_LABEL\""
|
||||
} | sfdisk --quiet "$IMG"
|
||||
dd if="$ESP" of="$IMG" bs=512 seek=2048 conv=notrunc status=none
|
||||
[ "$data_sectors" -gt 0 ] && dd if="$DATA" of="$IMG" bs=512 seek=$(( 2048 + esp_sectors )) conv=notrunc status=none
|
||||
|
||||
echo
|
||||
echo "✓ USB metal (systemd-boot): $IMG ($(du -h "$IMG" | cut -f1))"
|
||||
[ "$data_sectors" -gt 0 ] && echo " + partición $DATA_LABEL (FAT32 ${DATA_MB}M) para telemetría — legible en cualquier SO"
|
||||
echo " Quemar: sudo dd if=$IMG of=/dev/sdX bs=4M oflag=sync status=progress"
|
||||
echo " Bootear: el menú de systemd-boot aparece; ENTER arranca. Tecla 'e' = EDITAR la cmdline en vivo."
|
||||
echo " Secure Boot OFF. WiFi (en consola): wifi-connect \"SSID\" \"CLAVE\""
|
||||
|
||||
+134
-12
@@ -61,7 +61,8 @@ done
|
||||
# 2) busybox + applets
|
||||
echo "==> busybox"
|
||||
cp -a "$DEVFS"/bin/busybox "$RFS"/bin/busybox
|
||||
for a in sh mount umount mkdir ln cp mv rm cat echo sleep ls ps kill chmod chown ip udhcpc dmesg mknod switch_root getty login setsid; do
|
||||
for a in sh mount umount mkdir ln cp mv rm cat echo sleep ls ps kill chmod chown ip udhcpc dmesg mknod switch_root getty login setsid \
|
||||
findfs blkid sync tee date uname free df head tail grep sed awk cut tr wc find md5sum dd stat readlink basename; do
|
||||
ln -sf busybox "$RFS/bin/$a"
|
||||
done
|
||||
ln -sf /bin/busybox "$RFS/sbin/init.busybox"
|
||||
@@ -195,7 +196,9 @@ fi
|
||||
echo "==> lanzador /sbin/init"
|
||||
cat > "$RFS/sbin/init" <<'INIT'
|
||||
#!/bin/sh
|
||||
# init de la imagen live de mirada (software/swrast). Arranca seatd y el compositor en modo greeter.
|
||||
# init de la imagen live de mirada. Arranca seatd + el compositor en modo greeter, y — lo importante para
|
||||
# probar en una GPU AJENA — vuelca TODA la telemetría a la partición FAT32 del propio pendrive, para
|
||||
# traerlo de vuelta con la información. El rootfs es un initramfs (RAM): sin esto no sobrevive NADA.
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
/bin/busybox mount -t proc proc /proc 2>/dev/null || true
|
||||
/bin/busybox mount -t sysfs sys /sys 2>/dev/null || true
|
||||
@@ -205,6 +208,77 @@ export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
/bin/busybox mount -t devpts devpts /dev/pts 2>/dev/null || true
|
||||
/bin/busybox chmod 0700 /run/user/0
|
||||
|
||||
# ---------------------------------------------------------------- telemetría persistente al pendrive
|
||||
# La partición la crea metal-usb-sdboot.sh (DATA_MB/DATA_LABEL). Se monta con -o sync: cada escritura va
|
||||
# al medio, así un cuelgue duro de la GPU o un corte de luz no se lleva los logs.
|
||||
LOG=/telemetry
|
||||
TELOK=0
|
||||
/bin/busybox mkdir -p $LOG
|
||||
for try in 1 2 3 4 5 6 7 8 9 10; do
|
||||
DEV=$(/bin/busybox findfs LABEL=MIRADALOG 2>/dev/null)
|
||||
[ -n "$DEV" ] && break
|
||||
/bin/busybox sleep 1 # el USB puede tardar en enumerar
|
||||
done
|
||||
if [ -n "$DEV" ] && /bin/busybox mount -t vfat -o rw,sync "$DEV" $LOG 2>/dev/null; then
|
||||
TELOK=1
|
||||
else
|
||||
echo " !! NO pude montar la partición de telemetría (LABEL=MIRADALOG) — los logs quedan sólo en RAM"
|
||||
LOG=/run
|
||||
fi
|
||||
|
||||
# Cada arranque en su propia carpeta: run-0001, run-0002… (sin RTC confiable, se numera)
|
||||
N=1
|
||||
while [ -d "$LOG/run-$(printf %04d $N)" ]; do N=$((N+1)); done
|
||||
RUN="$LOG/run-$(printf %04d $N)"
|
||||
/bin/busybox mkdir -p "$RUN"
|
||||
echo " ## telemetría → $RUN (persistente=$TELOK)"
|
||||
|
||||
snap() { # snap <fichero> <titulo> <comando…>
|
||||
local f="$RUN/$1"; shift; local t="$1"; shift
|
||||
{ echo "===== $t ====="; "$@" 2>&1; echo; } >> "$f"
|
||||
/bin/busybox sync
|
||||
}
|
||||
|
||||
# PCI desde sysfs: este busybox NO trae el applet `lspci`. Con vendor/device/class/driver alcanza para
|
||||
# saber QUÉ GPU hay y, sobre todo, QUÉ DRIVER la bindeó (nouveau vs nada) — que es el dato del viaje.
|
||||
# vendor 0x10de = NVIDIA · class 0x0300xx = VGA · 0x0302xx = 3D controller
|
||||
pci_dump() {
|
||||
for d in /sys/bus/pci/devices/*/; do
|
||||
[ -r "$d/class" ] || continue
|
||||
drv=$(/bin/busybox readlink "$d/driver" 2>/dev/null | /bin/busybox sed 's|.*/||')
|
||||
echo "$(/bin/busybox basename $d) class=$(/bin/busybox cat $d/class) vendor=$(/bin/busybox cat $d/vendor) device=$(/bin/busybox cat $d/device) driver=${drv:-NINGUNO}"
|
||||
done
|
||||
}
|
||||
gpu_line() {
|
||||
for d in /sys/bus/pci/devices/*/; do
|
||||
[ -r "$d/class" ] || continue
|
||||
case "$(/bin/busybox cat $d/class)" in
|
||||
0x0300*|0x0302*)
|
||||
drv=$(/bin/busybox readlink "$d/driver" 2>/dev/null | /bin/busybox sed 's|.*/||')
|
||||
echo "$(/bin/busybox basename $d) vendor=$(/bin/busybox cat $d/vendor) device=$(/bin/busybox cat $d/device) driver=${drv:-NINGUNO}" ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# --- hardware / kernel: qué GPU hay, si nouveau bindeó, si cargó el firmware
|
||||
snap 01-hardware.txt "uname" /bin/busybox uname -a
|
||||
snap 01-hardware.txt "cmdline" /bin/busybox cat /proc/cmdline
|
||||
snap 01-hardware.txt "cpu" /bin/busybox head -20 /proc/cpuinfo
|
||||
snap 01-hardware.txt "memoria" /bin/busybox free -m
|
||||
snap 01-hardware.txt "PCI (sysfs; vendor 0x10de=NVIDIA)" pci_dump
|
||||
snap 01-hardware.txt "modulos" /bin/busybox cat /proc/modules
|
||||
snap 01-hardware.txt "DRM /dev/dri" /bin/busybox ls -la /dev/dri
|
||||
snap 01-hardware.txt "DRM /sys" /bin/busybox find /sys/class/drm -maxdepth 1
|
||||
snap 01-hardware.txt "nouveau sysfs" /bin/busybox find /sys/module/nouveau -maxdepth 2
|
||||
snap 01-hardware.txt "input" /bin/busybox cat /proc/bus/input/devices
|
||||
snap 01-hardware.txt "firmware nvidia" /bin/busybox find /lib/firmware/nvidia -type f
|
||||
for c in /sys/class/drm/card*/status /sys/class/drm/card*/modes /sys/class/drm/card*/enabled; do
|
||||
[ -r "$c" ] && snap 02-pantallas.txt "$c" /bin/busybox cat "$c"
|
||||
done
|
||||
|
||||
# dmesg TEMPRANO: acá se ve si nouveau bindeó y si el firmware gp106 cargó (o falló).
|
||||
snap 03-dmesg-early.txt "dmesg (antes de mirada)" /bin/busybox dmesg
|
||||
|
||||
export XDG_RUNTIME_DIR=/run/user/0
|
||||
export LIBGL_DRIVERS_PATH=/usr/lib/dri
|
||||
export LIBSEAT_BACKEND=seatd
|
||||
@@ -214,14 +288,21 @@ export MIRADA_GREETER_BIN=/usr/bin/mirada-greeter
|
||||
export XKB_DEFAULT_LAYOUT=us
|
||||
export XKB_CONFIG_ROOT=/usr/share/X11/xkb
|
||||
|
||||
# GPU: por defecto se INTENTA hardware (nouveau, si el firmware GSP lo deja hacer modeset) y, si no,
|
||||
# mesa cae a swrast/llvmpipe sobre simpledrm solo. Con `mirada.sw` en la cmdline se FUERZA software
|
||||
# (necesario en la VM virtio-sin-virgl de validación, donde mesa intentaría el driver virtio-3D y
|
||||
# fallaría). El compositor (smithay/GlesRenderer) corre en ambos; el greeter (wgpu/Vello) NECESITA la
|
||||
# capacidad de shaders float16 (SHADER_FLOAT16_IN_FLOAT32) que los rasterizadores software
|
||||
# (llvmpipe/lavapipe) NO dan ⇒ su login sólo pinta con GPU real (nouveau). Ver HANDOFF/README.
|
||||
# Telemetría MÁXIMA del stack gráfico: por qué wgpu eligió (o no) el backend, y si hay float16.
|
||||
export RUST_LOG="${RUST_LOG:-info,wgpu_core=debug,wgpu_hal=debug,mirada=debug,smithay=info}"
|
||||
export RUST_BACKTRACE=full
|
||||
export EGL_LOG_LEVEL=debug
|
||||
export MESA_DEBUG=1
|
||||
export LIBGL_DEBUG=verbose
|
||||
|
||||
# GPU: por defecto se INTENTA hardware (nouveau, si el firmware deja hacer modeset) y, si no, mesa cae a
|
||||
# swrast/llvmpipe sobre simpledrm. Con `mirada.sw` en la cmdline se FUERZA software (necesario en la VM
|
||||
# virtio-sin-virgl de validación). El compositor (smithay/GlesRenderer) corre en ambos; el greeter
|
||||
# (wgpu/Vello) NECESITA shaders float16 (SHADER_FLOAT16_IN_FLOAT32) que llvmpipe/lavapipe NO dan ⇒ su
|
||||
# login sólo pinta con GPU real (nouveau). Ver HANDOFF/README.
|
||||
if grep -qw 'mirada.sw' /proc/cmdline 2>/dev/null; then
|
||||
echo " ## modo SOFTWARE forzado (mirada.sw): compositor sí; greeter no (sin float16)"
|
||||
MODO="software (mirada.sw)"
|
||||
export LIBGL_ALWAYS_SOFTWARE=1
|
||||
export GALLIUM_DRIVER=llvmpipe
|
||||
export VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/lvp_icd.x86_64.json
|
||||
@@ -231,24 +312,59 @@ else
|
||||
# por el backend GL de wgpu sobre gallium-nouveau (que sí da unpackHalf2x16 = float16). Forzamos GL y
|
||||
# tapamos lavapipe: si dejáramos Vulkan, wgpu caería a lavapipe (software, sin float16) y fallaría.
|
||||
echo " ## modo HARDWARE (nouveau GL): greeter por gallium-nouveau"
|
||||
MODO="hardware (nouveau GL)"
|
||||
export WGPU_BACKEND=gl
|
||||
export VK_ICD_FILENAMES=/dev/null
|
||||
fi
|
||||
|
||||
{ echo "modo : $MODO"; echo "cmdline : $(/bin/busybox cat /proc/cmdline)"; echo "DRM : $(/bin/busybox ls /dev/dri 2>/dev/null | tr '\n' ' ')";
|
||||
echo "GPU (PCI) : $(gpu_line)";
|
||||
echo "persistente: $TELOK"; echo "RUST_LOG : $RUST_LOG"; } > "$RUN/00-resumen.txt"
|
||||
/bin/busybox sync
|
||||
|
||||
echo ""
|
||||
echo " ## hammer · mirada live"
|
||||
echo " ## DRM: $(ls /dev/dri 2>/dev/null | tr '\n' ' ')"
|
||||
echo " ## telemetría: $RUN (persistente=$TELOK)"
|
||||
echo ""
|
||||
|
||||
# seatd en background (gestiona el DRM master y la sesión sobre la VT).
|
||||
/usr/bin/seatd -g video >/run/seatd.log 2>&1 &
|
||||
sleep 1
|
||||
/usr/bin/seatd -g video > "$RUN/04-seatd.log" 2>&1 &
|
||||
/bin/busybox sleep 1
|
||||
|
||||
# El compositor: su salida va A LA VEZ a la pantalla y al pendrive (tee), para verlo y llevárselo.
|
||||
echo "== lanzando mirada-compositor --drm --greeter =="
|
||||
/usr/bin/mirada-compositor --drm --greeter 2>&1 | /bin/busybox tee /run/mirada.log
|
||||
/usr/bin/mirada-compositor --drm --greeter 2>&1 | /bin/busybox tee "$RUN/05-mirada.log"
|
||||
RC=$?
|
||||
|
||||
# --- post-mortem: lo que pasó DESPUÉS de correr mirada (cuelgues de GPU, oops, reset de nouveau)
|
||||
snap 06-dmesg-final.txt "dmesg (después de mirada)" /bin/busybox dmesg
|
||||
snap 06-dmesg-final.txt "rc del compositor" echo "exit=$RC"
|
||||
snap 07-estado-final.txt "procesos" /bin/busybox ps
|
||||
snap 07-estado-final.txt "memoria" /bin/busybox free -m
|
||||
snap 07-estado-final.txt "DRM final" /bin/busybox ls -la /dev/dri
|
||||
/bin/busybox sync
|
||||
|
||||
echo ""
|
||||
echo "== mirada terminó — shell de rescate (logs en /run/mirada.log, /run/seatd.log) =="
|
||||
echo "== mirada terminó (exit=$RC) — telemetría VOLCADA en $RUN =="
|
||||
[ "$TELOK" = "1" ] && {
|
||||
echo " Ficheros en el pendrive (partición MIRADALOG):"
|
||||
/bin/busybox ls -la "$RUN"
|
||||
echo ""
|
||||
echo " >> Podés apagar y traer el pendrive: los logs ya están sincronizados al medio."
|
||||
echo " >> Si querés reintentar antes de apagar, corré: relanzar"
|
||||
} || echo " !! sin partición de telemetría: los logs están en RAM y se pierden al apagar"
|
||||
echo ""
|
||||
|
||||
# `relanzar`: reintentar el compositor sin reiniciar; cada intento crea su propio run-NNNN.
|
||||
cat > /usr/bin/relanzar <<'RL'
|
||||
#!/bin/sh
|
||||
echo "relanzando init (nuevo run-NNNN en el pendrive)…"
|
||||
exec /sbin/init
|
||||
RL
|
||||
chmod +x /usr/bin/relanzar
|
||||
|
||||
echo "== shell de rescate (telemetría en $RUN; 'relanzar' para reintentar) =="
|
||||
exec /bin/sh
|
||||
INIT
|
||||
chmod +x "$RFS/sbin/init"
|
||||
@@ -269,9 +385,15 @@ if [ "$PACKAGE" = "1" ]; then
|
||||
# Default = HARDWARE nouveau (ya horneamos el firmware gp106): nouveau maneja la GTX 1060 y el greeter
|
||||
# pinta por gallium-nouveau GL. Si nouveau diera problemas, en el menú (tecla 'e') agregá
|
||||
# `mirada.sw nouveau.modeset=0` para caer a software (compositor sí, greeter no).
|
||||
# DATA_MB: partición FAT32 de TELEMETRÍA. El rootfs de esta imagen es un initramfs = RAM pura, así que
|
||||
# sin esta partición no sobrevive ni un log al apagado — y la GPU a probar está en otra máquina, lejos.
|
||||
# El init la monta por LABEL=MIRADALOG con -o sync y vuelca ahí todo (ver /sbin/init).
|
||||
# FAT32 ⇒ el pendrive se lee después desde cualquier SO, sin herramientas.
|
||||
ROOTFS="$RFS" KERNEL="$KGEN" IMG="work/hammer-mirada-usb.img" \
|
||||
DATA_MB="${DATA_MB:-512}" DATA_LABEL="MIRADALOG" \
|
||||
OPTIONS="${CMDLINE:-console=tty0 loglevel=4}" \
|
||||
scripts/metal-usb-sdboot.sh
|
||||
echo ""
|
||||
echo "✓ imagen: work/hammer-mirada-usb.img"
|
||||
echo " Al volver, leé la telemetría montando la partición MIRADALOG (FAT32) — carpetas run-NNNN/."
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user