The save func wrote Settings ".emulator"/".core", but SystemData::getEmulator
/getCore read them from SystemConf on non-Windows builds (and
popSystemConfigurationGui saves to SystemConf), so on Linux/ArchR the choice
was written where nothing reads it and the game launched with the default.
Match the readers' WIN32/else split. (Item is gated off on ARCHR today, but
this is a genuine cross-platform bug, not platform dead code.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The "ANALOG STICKS LED COLOR" feature controlled RGB LEDs that no
ArchR-supported device has (only the unsupported R36S Ultra does), gated by
DEVICE_ANALOG_STICKS_LED_CONTROL which no device sets, backed by a dispatcher
that execs a per-device binary nothing ships -> a guaranteed no-op everywhere.
- ES (patches/0003): remove the menu entry, openAnalogSticksLedControls() +
its declaration + include, the two CMakeLists refs, and the
GuiAnalogSticksLedControls class.
- system-utils: drop the analog_sticks_ledcontrol dispatcher script + install.
- quirks 999-export: drop DEVICE_ANALOG_STICKS_LED_CONTROL.
If R36S Ultra support is ever added, this comes back with a real, hardware-
backed backend developed against the device.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
From the ES menu audit:
- SHOW VIDEO PREVIEWS (UI) toggled Settings "EnableVideoPreviews", consumed
nowhere. Dead toggle removed.
- VARIABLE REFRESH RATE (Latency) toggled <config>.vrr_runloop_enable, read by
no launch script and meaningless on the fixed RK3326 panel. Dead toggle
removed.
- RESET OVERLAYS / FULLY RESET RETROARCH reboot the device (factoryreset
overlays -> systemctl reboot) without warning; their confirmation text now
says "THE DEVICE WILL REBOOT."
Second patch under this package's patches/. Pending validation: takes effect
after the ES package is rebuilt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reported as working but very slow (long black screen). Two OS-side
contributors cut, the rest (ES gamelist re-scan) is inherent:
- es_settings (ExecStartPre, runs on every ES start) unconditionally ran
`systemctl restart tz-data.service` synchronously, blocking the relaunch.
Only restart it when the timezone actually changed.
- emustation.service RestartSec was 2s of dead time before the relaunch.
Drop to 1s; StartLimitIntervalSec/StartLimitBurst already guard crash-loops.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two ES menu items that wrote settings nothing consumed / called a missing
binary, found in the menu audit:
- AUTO FRAME DELAY (Latency menu) persisted `<config>.video_frame_delay_auto`
to system.cfg, but setsettings.sh never translated it into retroarch.cfg,
so the toggle did nothing. Add set_frame_delay(): ON/OFF -> RetroArch
`video_frame_delay_auto = true/false`, AUTO leaves the cfg default.
- WIREGUARD VPN toggle runs `wg-quick up/down`, but the wireguard-tools
package only installed `wg`, so every toggle silently failed. wg-quick is
the upstream bash helper (src/wg-quick/linux.bash); install it. Runtime
deps (bash, ip, wg, iptables) are all present.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A user reported (and it reproduces on hardware) that turning "ENABLE
NAVIGATION SOUNDS" on in Sound Settings does nothing until the device is
rebooted.
Root cause: Sound::init() loaded the WAV sample only when EnableSounds was
already true:
if (!Settings::getInstance()->getBool("EnableSounds"))
return;
mSampleData = Mix_LoadWAV(...);
So when the frontend starts with sounds disabled, every Sound keeps a null
sample; flipping the menu switch only writes the setting and never reloads
the samples, so play() bails on the null sample. Only the next boot re-runs
init() with the setting true and finally loads them.
Sound::play() already checks the live EnableSounds value, so the init-time
gate is redundant for correctness and harmful for runtime toggling. Drop it
(new patch, first under this package's patches/) so samples always load and
the toggle works immediately, both directions, no reboot. Memory cost is a
handful of small navigation WAVs.
Pending validation: takes effect after the ES package is rebuilt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Found during the live multi-device SSH sweep; none break a single device but
each is a real defect:
- linux-drivers/RTL8188EUS 99-rtl8188eus.rules: the RUN line used single `$`
for its shell vars, which udev parses as its own specifier ("invalid
substitution type") and rejects the whole rule, so the rtl8xxxu->8188eu
rebind never ran (the dongle stayed on the better driver only by probe-order
luck). Double them to `$$`.
- linux 10-bfq-sched.rules: `KERNEL=="mmcblk[0-9]*"` matched partitions too,
whose queue/* knobs do not exist, spamming the boot log with ~15 ENOENT
write failures. Gate on SUBSYSTEM=="block", DEVTYPE=="disk".
- hostname: system.cfg shipped `system.hostname=@DEVICENAME@` -> "RK3326" (the
SoC name, identical on every unit), so two ArchR consoles on one LAN collide
on NetBIOS/mDNS registration (nmbd "Failed to register my name"). Set the
base name to "archr" and append a short per-device machine-id suffix in
network-base-setup so each device is unique.
- tsadc: r3xs.dtsi and eeclone.dts enabled tsadc without
rockchip,hw-tshut-mode/-polarity, so the driver logged "Missing tshut ...
using default" on every boot. Spell out the defaults (CRU reset, active-low);
behaviour unchanged. DTS compiles clean (eeclone + soysauce).
The "GO-Super Gamepad" joypad name on the Soysauce was investigated and is
intentional (soysauce.dts sets joypad-name with a matching retroarch config),
so it is left as-is.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The image rootfs is a squashfs, not a pacman install, so /var/lib/pacman
(-> /storage/.pacman/db) ships empty: on every device `pacman -Q` returns 0
and `pacman -Qu` finds nothing, so archr-update / `pacman -Syu` reports "No
updates available" even when the repo carries newer base packages. The
headline 2.0 update path therefore only ever installed user addons, never
upgraded the base system (confirmed live: local/ holds only ALPM_DB_VERSION).
Fix in two self-contained parts (no image-build wiring, so the seed always
matches the build that produced it):
- gen-pacman-repo: after building the sync db, register every just-built
package as installed (`pacman -U --dbonly`, files already in the squashfs)
and publish the resulting local/ tree as <repo>-localdb.tar.gz alongside
the packages.
- autostart/004-seed-pacmandb: on first boot, if the local db is still empty
(only ALPM_DB_VERSION) and the network is up, pull <repo>-localdb.tar.gz
from the configured release channel and extract it into
/storage/.pacman/db. Idempotent and skipped once the db is populated, so a
user's own pacman activity is never clobbered.
PENDING VALIDATION: needs a full build + repo publish to confirm the seed is
produced and that `pacman -Syu` then sees base upgrades. Best-effort on the
generator side (logs a warning rather than failing the repo build).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The R36S Clone's standalone DTB diverged from the shared r3xs.dtsi the
Original/Soysauce use, producing two real boot-time errors (confirmed by a
dmesg diff against the Original, which boots clean):
- &emmc was status=okay + non-removable, but the Clone board has no eMMC
chip. The controller retried an absent card forever ("Timeout sending
command", "Failed to initialize a non-removable card"), wasting boot time.
Disable it; the OS boots from &sdmmc.
- &uart5 (console, ttyS2) inherited the px30 default pinctrl with uart5_cts
on gpio3 RK_PA3, already claimed on this board, so the kernel reverted the
whole pin group ("Error applying setting, reverse things back") and could
leave even TX/RX unapplied. Mux xfer-only (a console needs no hardware flow
control), matching how the Original wires uart2.
DTS compiles clean (cpp + dtc).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The quirks loader matches /usr/lib/autostart/quirks/devices/<dir> against the
exact /proc/device-tree/model string. The Clone (model "R36S Clone") and the
Soysauce (model "Game Console R36S Soysauce") had no matching folder, so no
device_config was sourced and DEVICE_TEMP_SENSOR stayed unset: System
Information showed no CPU/GPU temperature, while the Original
("Game Console R36S") did. The DTBs and tsadc are identical and fine on all
three (thermal_zone0/1 read live), so this was purely a missing per-device
quirk, not a devicetree gap.
Add minimal device_config folders wiring thermal_zone0 (CPU) and
thermal_zone1 (GPU). Audio/LED are left on the working defaults. The orphaned
"Generic EE clone" folder (no DTS uses that model) is left as-is rather than
renamed onto "R36S Clone", since its dormant 002-generate_dtbo quirk would
re-introduce in-image DTBO generation that was intentionally moved to the
website generator.
Validated on a live Soysauce: archr-info now reports CPU/GPU temperature.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Verifying the last PortMaster_CFW.md nice-to-have: build-tested the
maintained ltrace fork (gitlab.com/cespedes/ltrace HEAD) on the ArchR
aarch64 toolchain. It fails at autoreconf (configure.ac points at a
config/m4 macro dir that isn't in the checkout, aclocal aborts),
re-confirming the pre-existing exclusion rationale. ltrace stays out;
gdb and perf trace cover symbol-level tracing. This is the only guide
nice-to-have intentionally absent.
Verification of the running R36S against docs/PortMaster_CFW.md flagged
a few required/recommended/nice-to-have items missing. Closes four:
sudo (REQUIRED, section 2): ArchR runs everything as root so PortMaster
sets ESUDO="" and "$ESUDO" ports work, but the guide lists sudo/doas as
required and the live port log printed "No sudo present." Ships a
/usr/bin/sudo shim (archr package, ROCKNIX/dArkOS pattern) that strips
sudo's own options and execs the command as the already-root user.
libjpeg.so.62 (commonly expected, section 4): the base libjpeg-turbo is
built WITH_JPEG8=ON (SONAME libjpeg.so.8); ports compiled against
standard libjpeg-turbo expect libjpeg.so.62. New compat-libjpeg62
package builds the same 3.0.1 source WITH_JPEG8=OFF into /usr/lib/compat
and is pulled in via portmaster-compat-libs; archr-compat-symlinks then
exposes it in the default path.
vmstat (nice-to-have, section 10): procps-ng shipped only free/top/ps;
add src/vmstat to the build + install so memory-pressure monitoring is
available.
perf_event_paranoid (nice-to-have, section 10): ship
sysctl.d/90-archr-perf.conf setting kernel.perf_event_paranoid=1 so perf
can sample userspace CPU events (default 2 blocks non-root profiling).
(ltrace, the remaining nice-to-have, is being build-tested separately;
virtual/debug already documents why upstream 0.7.3 was excluded.)
PortMaster runtimes failed to launch: love_11.5's love.aarch64 died with
"error while loading shared libraries: libtheoradec.so.1: cannot open
shared object file" (caught live over SSH while a port was launched).
Root cause: ArchR keeps the ~50 PortMaster compat libraries (older
Debian-11-era SONAMEs: libtheoradec.so.1, libavcodec.so.58,
libwebp.so.6, libx264.so.160, etc.) under /usr/lib/compat to stay out of
the base system, and the image ships NO ld.so.cache. glibc's dynamic
linker therefore only searches the hardcoded /usr/lib + /lib plus
LD_LIBRARY_PATH, so /usr/lib/compat is invisible to anything that does
not explicitly prepend it. control.txt does set
LD_LIBRARY_PATH=/usr/lib/compat, but the per-runtime invocation
overwrites it, dropping compat for binaries like love.aarch64.
docs/PortMaster_CFW.md is explicit on the fix: "add these older .so
symlinks alongside [the newer versions]" and "Keep [libtheoradec] at
standard versions." So we expose the compat SONAMEs in the default path.
New archr-compat-symlinks script + archr-compat-libs.service oneshot
(ordered Before=archr-autostart so it runs before any port launches):
walks /usr/lib/compat (and /usr/lib32/compat) and symlinks each SONAME
into /usr/lib, but ONLY when the base system does not already provide
that exact name, so real libraries (libogg.so.0, libvorbis.so.0, ...)
are never shadowed. Idempotent via the `[ -e ]` guard; the writable
ext4 rootfs keeps the links so later boots are no-ops.
Verified live on the R36S: 46 compat-only SONAMEs linked into /usr/lib,
libtheoradec.so.1 now resolvable, libogg.so.0 left untouched (still the
real /usr/lib/libogg.so.0.8.6).
Root cause of the persistent "Unable to find LABEL=ARCHR, powering
off" after the issue #34 boot.ini LABEL= migration: busybox's built-in
volume_id CANNOT read FAT32 labels. Proven under qemu-aarch64 against
the real image partitions:
util-linux blkid FAT32 -> LABEL="ARCHR" ext4 -> "ARCHR_ROOT"
busybox blkid FAT32 -> TYPE="vfat" only ext4 -> "ARCHR_ROOT"
So `busybox mount LABEL=` and `busybox findfs LABEL=` both fail for the
FAT /flash partition (mounted first), while the ext4 root would have
resolved. The previous fallback used util-linux blkid but only scanned
a hardcoded /dev/mmcblk0p[1-3] /dev/mmcblk1p[1-3] list, so it broke
whenever the boot SD enumerated outside mmcblk0/1 or the partition
nodes weren't created yet.
mount_common's LABEL=/UUID= branch now:
- resolves exclusively through util-linux /usr/sbin/blkid (reads both
FAT32 and ext4 labels),
- walks every entry in /proc/partitions instead of a fixed device
list, so it is independent of the mmcblkN enumeration order
(exactly what issue #34's 2-SD reordering needs),
- mknod's the /dev node from the /proc/partitions major:minor when
mdev hasn't created it yet, removing the dependency on mdev timing
and on udev (absent in the initramfs),
- keeps busybox findfs (works for ext*) and /dev/disk/by-label as
last-resort fallbacks.
Verified: syntax (sh -n) clean, the parse+blkid logic resolves
mmcblk1p1 in a simulated /proc/partitions run, and the rebuilt image's
embedded initramfs carries the new resolver.
The "Unable to find LABEL=ARCHR, powering off" wall on the freshly
flashed image traced back to a latent bug in the initramfs busybox
packaging that the boot.ini LABEL= migration (issue #34) made
deterministic.
busybox/package.mk
The mount, umount and findfs applets are compiled into the init
busybox (CONFIG_MOUNT/UMOUNT/FINDFS in config/busybox-init.conf),
but no symlinks were ever installed for them. mount_common() in the
init script calls `mount LABEL=... /flash` and
`findfs LABEL=...` by bare name; without symlinks the shell can't
find either command and the 15 retry loops silently exhaust to the
power-off message. This bug also affected the previous
/dev/mmcblk${devnum}p1 path: the string was never reaching the
syscall through busybox.
Adds:
ln -sf /usr/bin/busybox ${INSTALL}/usr/bin/mount
ln -sf /usr/bin/busybox ${INSTALL}/usr/bin/umount
ln -sf /usr/bin/busybox ${INSTALL}/usr/sbin/findfs
/usr/sbin/blkid is already shipped by util-linux as a real binary,
no symlink needed for it.
busybox/scripts/init
Exports PATH=/usr/sbin:/usr/bin:/sbin:/bin at the top so the bare
blkid/findfs/mount calls in mount_common() resolve against
/usr/sbin/blkid (util-linux real binary) and the new busybox
symlinks. Without this, the busybox sh default PATH on aarch64
built images is too narrow to find /usr/sbin tools.
RTL8188EUS/package.mk
PKG_VERSION bumped from ec90af2b... (no longer on the remote) to
af3bf004458f76b7aec33e9ba552cd382ed1f5c3, the current HEAD of the
default v5.3.9 branch on aircrack-ng/rtl8188eus. The previous SHA
failed at `get` time: `fatal: remote error: upload-pack: not our
ref ec90af2b...`, blocking the whole image build.
Strategic continuation of the flasher refactor: the SO no longer
generates or ships pre-built panel DTBOs. Users generate their own
mipi-panel.dtbo at https://arch-r.io/overlay-generator/ and drop it
into /flash/overlays/.
- config/overlays/README.txt rewritten with the same instruction in
6 languages (pt-BR, en, fr, es, zh, ru), one per line.
- u-boot/package.mk: removed the mipi-generator invocation and the
per-SUBDEVICE overlays_{original,clone,soysauce} install blocks.
Only the generic overlays/ dir (README) is shipped under
/usr/share/bootloader/.
- bootloader/mkimage: removed the RK3326-specific overlays_${SUBDEVICE}
and overlays_soysauce branches; the generic overlays/ copy at the
end of mkimage_dtb now covers RK3326 too.
- Deleted config/mipi-generator/ (generator.sh + archr-dtbo.py) and
config/archr-dts/ (vendor DTBs that were only consumed by the
generator).
Net: -8503 LOC + ~120 binary DTBs removed from the tree.
Issue archr-linux/Arch-R#35 (R36S Clone V20 batch 2551 sem áudio).
A DTS base rk3326-gameconsole-eeclone.dts NÃO inclui r3xs.dtsi —
diferente de rk3326-gameconsole-r36s.dts (original) e
rk3326-gameconsole-soysauce.dts (Y3506). Como r3xs.dtsi é onde o
node `rk817-sound` padrão fica ativo, o eeclone vai pro kernel só
com as duas variantes `rk817-sound-amplified` e `rk817-sound-simple`,
ambas com `status="disabled"`.
Para R36S Clone V20+ o vendor BSP 4.4 não publica `spk-con-gpio` nem
`rockchip,codec/spk-ctl-gpios` no rk817-sound (o widget de speaker
nem aparece no DTB), então a detecção atual do gerador caía no
ramo "keep default" e o overlay ficava sem habilitar nenhum sound
card. Resultado: `aplay -l` retornava "no soundcards found" em todo
clone V20 / V21.
generator.sh agora emite `sd_prefix="SDCLONE"` para subdevice=clone
(antes só emitia SDORIG para original/soysauce). archr-dtbo.py
trata SDCLONE como sinal de que a base DTS não tem default sound
card ativo e força o `rk817-sound-amplified` como fallback safe —
caso clone V20+ que carrega amp externo via GPIO não exposto no
DTB. Clones sem amp explícito (raros) podem usar a variante _SRs
para forçar `simple` ou o flag NAm para `spko-direct`.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Issue archr-linux/Arch-R#19: dongles USB com chipset RTL8188EUS (TP-
Link TL-WN722N v3, Edimax EW-7811Un, vários no-name) escaneiam SSIDs
mas falham na autenticação WPA2 — handshake 4-way não completa, ESS
fica em "Connecting..." até timeout.
Histórico: tentamos antes o ajuste de IWD (UseDefaultInterface,
AddressRandomization), bump IWD 3.9 → 3.10, e o patch upstream
rtl8xxxu de firmware upload block size 128 → 196 (`projects/ArchR/
packages/linux/patches/6.12-LTS/0050-wifi-rtl8xxxu-Fix-RTL8188EU-
firmware-upload-block-size.patch`). Nenhum desses resolveu para os
usuários que reportaram — o rtl8xxxu in-tree continuamente trava no
handshake nesse chip específico.
A solução conhecida em outras distros (Arch, Debian, Manjaro, Kali,
TWRP, Postmarket) é usar o fork `aircrack-ng/rtl8188eus` mantido
especificamente para esse chip. Ele tem o handshake testado com iwd
e wpa_supplicant.
Pacote adicionado:
projects/ArchR/packages/linux-drivers/RTL8188EUS/
├── package.mk (build out-of-tree 8188eu.ko)
├── modprobe.d/
│ └── 00-rtl8188eus.conf (tunables: LED on, no double MAC random)
└── udev.d/
└── 99-rtl8188eus.rules (unbind rtl8xxxu da interface USB
específica nos USB IDs do 8188EUS
e force-load 8188eu)
A udev rule cobre os IDs comuns:
0bda:0179 / 0bda:8179 / 0bda:8189 — Realtek de fábrica
7392:7811 — Edimax EW-7811Un
056e:4008 — Elecom WDC-150SU2M
Não fazemos blacklist global do rtl8xxxu — ele continua sendo o
driver de RTL8192EU, RTL8723BU, RTL8188CU etc. (que funcionam bem
com ele). Só desbinda do device USB específico quando um 8188EUS
aparece e load o 8188eu in its place.
RTL8188EUS adicionado a ADDITIONAL_DRIVERS em projects/ArchR/devices/
RK3326/options para que a build inclua o módulo no rootfs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Issue archr-linux/Arch-R#34: ao inserir um segundo cartão SD em TF2,
o boot falha com "cannot find mmcblk1p1" + countdown para poweroff.
Causa:
- Linux enumera os controladores MMC do RK3326 por ordem do DT:
ff380000.mmc -> mmc0 -> /dev/mmcblk0 (TF2, slot secundário)
ff370000.mmc -> mmc1 -> /dev/mmcblk1 (TF1, slot com o OS)
- U-Boot enumera por ordem de probe dos slots; com TF2 populado o
devnum repassado para a sysboot pode acabar diferente do que o
kernel apresenta como /dev/mmcblk1.
- clone_boot.ini e original_boot.ini montavam o kernel cmdline como
`boot=/dev/mmcblk${devnum}p1 root=...p2 disk=...p3`, então a
troca de devnum quebrava o /init busybox.
Fix:
Substituir o path hardcoded por LABEL=@DISTRO_BOOTLABEL@ (sed do
package.mk já existia mas não tinha onde substituir; agora cobre
ARCHR / ARCHR_ROOT / STORAGE). O /init busybox já trata LABEL= via
findfs + fallback de blkid scan em mmcblk0/mmcblk1, então a partição
certa é encontrada independente da ordem de enumeração — sobrevive
a 2-SD, troca de slot, ou qualquer reorder que U-Boot decida fazer.
Kernel cmdline antes:
boot=/dev/mmcblk1p1 root=/dev/mmcblk1p2 disk=/dev/mmcblk1p3
Depois:
boot=LABEL=ARCHR root=LABEL=ARCHR_ROOT disk=LABEL=STORAGE
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Vários edge cases no fluxo de conexão WiFi com caracteres não-ASCII /
metacaracteres causavam o sintoma reportado "trava ao conectar":
1. iwd codifica caracteres não ([A-Za-z0-9._-]) no nome do .psk como
=XX (man iwd.network "Network file names"). wifictl gravava o
profile como /var/lib/iwd/<SSID literal>.psk — quando o SSID tinha
espaço, ç, +, /, etc. iwd não encontrava o arquivo, o iwctl
station connect caía em prompt interativo aguardando passphrase via
stdin e ficava preso até o autoconnect timeout (30+s). encode_iwd_
name aplica a transformação canônica byte-a-byte (validado com
"Café" -> "Caf=C3=A9", "DIRECT-17-HP Douglas" -> "DIRECT-17-HP=20
Douglas").
2. Senhas fora do intervalo válido (WPA-PSK: 8..63 bytes printable ou
64 hex chars) também faziam iwd rejeitar o profile e cair no
mesmo trava-no-prompt-stdin. wifictl agora rejeita cedo com retorno
2 e mensagem em stderr, dando feedback útil para a UI.
3. Profile órfão de tentativa anterior podia conflitar: ao trocar
entre rede aberta e WPA, ou ao mudar a senha, o iwd preferia o
profile antigo (.open / .psk). Agora wifictl remove os dois antes
de regravar.
4. O check de pós-conexão era frouxo: "state=connected" sozinho
retornava sucesso quando a estação já estava em outra rede,
mesmo que a conexão solicitada falhasse silenciosamente. Adicionado
match contra "Connected network" do iwctl show.
5. O heredoc do create_adhoc usava <<EOF (não-quoted) — um $ literal
na passphrase disparava expansão de variável bash. Substituído por
printf %s para preservar a senha byte-a-byte.
6. /var/lib/iwd/*.psk passa a ser criado com umask 077 — a passphrase
está em texto claro no arquivo e não deveria ser legível por nada
além do iwd (rodando como root).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
A versão anterior do short-circuit gravava sha256(senha) em
/storage/.cache/.archr-rootpass.sha256 — fingerprint recuperável que
quebraria senhas curtas / dicionário por brute force trivial se o
arquivo vazasse. Revisão de segurança automatizada apontou.
Substituída a comparação por reproduzir o próprio sha512crypt já
armazenado em /storage/.cache/shadow: extrai o salt do campo CURRENT
(formato $6$<salt>$<hash>), chama cryptpw -m sha512 -S "$SALT"
"$ROOTPASS" e compara contra CURRENT. Nenhum novo arquivo é escrito;
o único hash de senha em disco continua sendo o sha512crypt salted
que já existia.
Live no R36S:
- mesma senha: 0.147s (short-circuit)
- senha nova: 1.233s (caminho completo)
- nenhum arquivo extra em /storage/.cache/.archr-rootpass*
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
5 ganhos mensuráveis identificados rodando o sistema vivo:
1. /etc/sysctl.d → /storage/.config/sysctl.d, e systemd-sysctl roda
Before=sysinit.target — /storage só monta em local-fs.target. O
symlink ficava dangling quando systemd-sysctl lia, então archr.conf
(BBR/fq_codel, vm.dirty_writeback_centisecs=1500, ip_forward, etc.)
nunca era aplicado no boot. Verificado: rodando sysctl -p manual
depois do boot, dirty_writeback_centisecs vai de 500 → 1500.
Replicar os defaults da distro em /usr/lib/sysctl.d (rootfs, sempre
disponível) garante aplicação antes de /storage subir; o /etc/
sysctl.d permanece como ponto de override do usuário.
2. enable.turbo-mode=1 em system.cfg padrão. A baseline validada do
R36S inclui CPU turbo @ 1512 MHz via cpufreq/boost (vdd_arm
regulator-max=1.45V), mas o default era 0 — clamp em 1416 MHz
sem opt-in. O nó scaling_max_freq sobe para 1512000 assim que
boost=1, comprovado live no device. Quem precisar do clamp
térmico de 1416 desliga via Settings > Advanced.
3. rpcbind.service rodando idle custava ~11 MB de RAM em um device
com 1 GB total, sem nada usando NFS. O upstream já fornece
rpcbind.socket (Listen :111 + /run/rpcbind.sock) e systemd faz
activation on-demand — mount.nfs dispara o daemon quando o user
realmente monta um share. Trocado enable_service rpcbind.service
por rpcbind.socket.
4. archr-touchscreen-keyboard ficava acordando a cada 5s mesmo em
devices sem touchscreen (R36S, R33S, etc), e com Restart=always
um exit do helper provocava restart infinito. Adicionado bail-out
precoce quando DEVICE_HAS_TOUCHSCREEN != true, e Restart trocado
para on-failure para honrar o exit limpo. Em devices sem
touchscreen o serviço passa a ficar inativo após o primeiro boot.
5. setrootpass cryptpw sha512 + smbpasswd + syncthing generate
custavam ~6s a cada boot — chamado pelo autostart 007-rootpw com a
senha já configurada. Adicionado short-circuit que compara o hash
sha256 da senha contra o cache em /storage/.cache/.archr-rootpass.
sha256: se nada mudou, sai em 20ms.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
001-functions:wait_lock(): o trap rm -f "\$lockfile" referenciava
uma variável inexistente. O lock real está em \${J_CONF_LOCK}. Como
\$lockfile expandia para string vazia, rm -f "" virava no-op e
deixava /tmp/.system.cfg.lock órfão se o script morresse por SIGINT/
SIGTERM antes do rm -f explícito no final.
archr-automount.service: Before=autostart.service apontava para o
nome herdado do JELOS, que ArchR não embarca (a unit real é
archr-autostart.service). Sem o prefixo o ordering virava silently
ignored, perdendo a garantia de que /storage/games-* fosse montado
antes dos scripts de autostart consumirem os paths. Também ajustada
a Description que dizia "user autostart script" (copy-paste do
archr-autostart.service).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sweep encontrou 5 categorias de bugs sutis em arquivos herdados:
1. StartLimitInterval/StartLimitBurst em [Service] em 13 unidades
(avahi, bluez, connman, samba/nmbd/smbd, sshd, tz-data, ledfix,
xorg, fluxbox/windowmanager, samba-config). systemd silenciosamente
ignora StartLimit* fora de [Unit], então a proteção contra
restart-flood nunca foi aplicada. Movidas para [Unit] e renomeadas
para o canônico StartLimitIntervalSec (StartLimitInterval é alias
antigo).
2. Refs dangling para kodi.service em 5 units (entware, locale, sway,
xorg, xwayland-xorg, windowmanager-fluxbox). ArchR não embarca
Kodi; o ordering Before=kodi.service ficava como "not-found" no
systemctl list-units. Trocado por Before=archr.target (alvo real
de boot da UI em ArchR).
3. usercache.service e userconfig.service referenciavam
automount.service e autostart.service sem prefixo archr-. Em ArchR
as unidades reais chamam-se archr-automount.service /
archr-autostart.service, então o Before= era ignorado e o setup
corria paralelo aos mounts.
4. archr-autostart.service tinha Before=weston.service. ArchR roda
sway, não weston. Removido (After=graphical.target já cobre).
5. nmbd.service do override ArchR queria samba-config.service que só
existe no pacote global packages/network/samba (não no override).
O daemons/002-samba já cria /run/samba/smb.conf manualmente, então
Wants/After=samba-config.service eram supérfluos.
Bugs adicionais corrigidos no caminho:
- archr/autostart/050-audio: `if [ -n "/usr/sbin/quantum" ]` testa se
uma string literal é não-vazia (sempre true) em vez de checar se o
binário existe. Trocado para [ -x ].
- avahi: post_makeinstall_target removia /usr/sbin/avahi-dnsconfd mas
deixava a unit avahi-dnsconfd.service órfã. Remove a unit junto.
- system-utils: video.service só faz sentido em devices que embarcam
/usr/bin/video_sense (RK3399/RK3566/S922X). Remove a unit em
devices que não têm o helper.
- xwayland: scripts/xorg-configure não era instalado, deixando
xorg-configure@.service com ExecStart para um path inexistente.
Agora copiado pra /usr/lib/xorg/xorg-configure.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bug crítico no autostart: QUIRK_DEVICE vem de /sys/firmware/devicetree
/base/model e quase sempre tem espaços ("Game Console R36S"). O loop
`for QDIR in ${QUIRK_DIRS}` com string concatenada partia esse path em
3 tokens (Game, Console, R36S) e o glob ${QDIR}/* não casava com nada.
Resultado: nenhum quirk device-specific rodava — 001-device_config
nunca escrevia /storage/.config/profile.d/001-device_config, então
DEVICE_TEMP_SENSOR / DEVICE_PWR_LED_GPIO / DEVICE_PLAYBACK_PATH_*
ficavam vazios em todos os processos. O System Information do ES não
mostrava CPU TEMPERATURE, GPU TEMPERATURE, e os start_*.sh dos
emuladores caíam em fallback de áudio.
Fix usa arrays bash com expansão entre aspas:
QUIRK_DIRS=(...)
for QDIR in "${QUIRK_DIRS[@]}"; do ...
archr-info ganha 5 melhorias:
- DISTRO FAMILY: lê ID_LIKE de /etc/os-release e renderiza
"Arch Linux" (título). OPERATING SYSTEM agora mostra "ArchR Linux"
para deixar a relação com Arch explícita.
- DISK SPACE: detecta quando games-internal e games-external apontam
para o mesmo device e mostra só "INTERNAL" (a UI repetia a linha
idêntica quando não havia SD externo).
- MESA VERSION: sniffa libgallium-X.Y.Z.so para mostrar 26.1.3.
- GPU DRIVER: lsmod identifica panfrost (Mesa) ou mali_kbase (legacy
blob), útil pra debugar quando o user troca via picker.
- info_quirks: protegido contra chamada sem argumento (era o motivo
do exit 127); usa nullglob + iteração quoted para suportar paths com
espaços e diretórios info.d/* ausentes.
Game Console R36S/001-device_config: define DEVICE_GPU_TEMP_SENSOR
apontando para thermal_zone1 (gpu-thermal IP). A linha GPU TEMPERATURE
da seção GPU INFORMATION agora aparece no ES.
Saída final no R36S:
DEVICE: Game Console R36S
OPERATING SYSTEM: ArchR Linux
DISTRO FAMILY: Arch Linux
CPU TEMPERATURE: 54°
GPU TEMPERATURE: 55°
MESA VERSION: 26.1.3
GPU DRIVER: mali_kbase (legacy blob)
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>