177 Commits

Author SHA1 Message Date
Douglas Teles 9ff72420c6 repo: make local-overlay and meta packages deliver pacman updates
The pacman update channel silently dropped most local changes:

- gen-pacman-repo hardcoded pkgrel=1, ignoring PKG_REV. A package whose
  upstream PKG_VERSION is pinned (e.g. retroarch-joypads, where only the
  local gamepads/ overlay changes) could never produce a newer package,
  so `pacman -Syu` never saw the fix. Read PKG_REV and map it to the repo
  package release (default 1 when unset or dynamic).

- the archr meta package had PKG_VERSION="", so its install_pkg dir was
  "archr-" and the synthesized version was the constant "archr.". The
  main system-config package (system.cfg, runemu, wifictl, governors,
  networkservices) therefore never updated. Stamp it with the build
  timestamp so each rebuild ships a real, monotonically increasing
  version.

- bump retroarch-joypads PKG_REV to 2 so the corrected GO-Super Gamepad
  autoconfig ships as an update.

The kernel/DTB stays out of pacman on purpose: it lives on the FAT boot
partition, which pacman does not manage, so kernel changes ship by image
flash.
2026-06-30 16:47:29 -03:00
Douglas Teles ae837498a3 network: reconnect WiFi at boot when wifi.enabled is set
WiFi was refactored from connman to iwd (wifictl uses iwctl), but iwd is
dbus-activated and nothing re-associates it to the saved network at boot.
The result: a unit rebooted with WiFi on comes up with the ES toggle
showing active but no connection, and the user has to flip the toggle off
and on to reconnect.

The ES "Enable WiFi" toggle reconnects via `wifictl enable` (rfkill
unblock) + `wifictl connect` (scan + associate to the saved iwd profile,
ApiSystem::enableWifi). Mirror that in 099-networkservices, which already
owns the network domain at boot and runs after network.target. The
connect is backgrounded so the scan does not delay the UI, and wifictl
no-ops when there is no WiFi device.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 18:06:02 -03:00
Douglas Teles 1ba3d6ef92 perf: default CPU to 1.4 GHz, keep 1.5 GHz as an opt-in overclock
Commit e8fd3a6c43 shipped enable.turbo-mode=1 in the default system.cfg,
which makes 095-turbo-mode enable cpufreq/boost at boot, so every unit
runs the 1512 MHz turbo OPP out of the box. That turns the overclock into
the standard clock instead of an opt-in, with the thermal and battery
cost it implies.

Ship enable.turbo-mode=0 so the box defaults to the regular 1416 MHz
ceiling. The 1512 MHz OPP stays available as an overclock: the ES "Enable
CPU Overclock" switch (turbomode enable) flips cpufreq/boost on and pins
the higher OPP, and performance() honors that toggle during gameplay. The
performance governor on game launch is unchanged.

Also correct a stale runemu.sh comment that claimed performance()
unconditionally forces boost on; it follows the user's toggle now.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 17:57:26 -03:00
Douglas Teles 9d89a01d4c soysauce: wire speaker amp in DT and fix joypad controls
soysauce.dts: enable rockchip,use-ext-amplifier + spk-ctl-gpios on the
codec (drives patch 0060), set hp_det to pull-none so insertion is seen,
and bump the analog tuning 200 to 280. The Y3506 sticks only reach ~76%
of the declared range at full deflection, so partial pushes never crossed
the EmulationStation navigation threshold; the higher gain saturates the
axis and keeps menu scrolling responsive (R36S/eeclone pots reach full
range at 200, this is Y3506-specific).

Joypad userspace mapping (the analog/button wiring was never broken in
the kernel, the configs were):
- es_input.cfg: add a GO-Super Gamepad entry modelled on r36s_Gamepad,
  using leftanalog/rightanalog so both sticks navigate the menu. The old
  auto-generated entry mapped them as joystick1/joystick2, and
  joystick2up is hardcoded to volume in ViewController, so the right
  stick changed volume and the left stick did nothing.
- GO-Super Gamepad.cfg (RetroArch): the button indices were the RGB20S
  layout (select=12, start=13, dpad=8-11), which broke in-game Start,
  Select and the exit combo. Correct to the r36s layout (select=8,
  start=9, dpad=13-16, l3=11, r3=12, hotkey=8) and fix the vendor id.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 17:37:19 -03:00
Douglas Teles 36f99fec2b soysauce: speaker output via rk817 external amplifier
The R35S/Y3506 loudspeaker is not wired to the rk817 class-D SPKO; it
hangs off the analog headphone output through an external amp gated by
spk-ctl-gpios. The mainline codec routes "SPK" to the unused class-D, so
the speaker is silent. Add patch 0060 (use_ext_amplifier: route the
speaker mux through the headphone DACs and toggle spk-ctl via a DAPM
event) and the per-device audio playback paths (SPK/HP) so the speaker
plays and headphone switching works.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 17:37:19 -03:00
Douglas Teles 955434eade build: auto-sync overlay-generator base DTBs after each RK3326 build
The archr-website overlay generator bundles the three base DTBs
(r36s/eeclone/soysauce) it mirrors a user's stock DTB against. They have
to track the shipped image or every generated overlay anchors against
the wrong node structure (this had drifted: eeclone was off by 901 lines,
missing the emmc-disable + uart5 + tsadc changes).

Add scripts/repo/sync-site-bases (host-side, idempotent, non-fatal) and
call it from the Makefile after a successful docker-RK3326 build. It only
copies the files into the sibling archr-website checkout; review, commit
and redeploy of the site stay manual.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 11:08:26 -03:00
Douglas Teles 89ce198105 es-menu: openSystemEmulatorSettings saves emulator/core to SystemConf
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>
2026-06-25 23:37:23 -03:00
Douglas Teles 5a8efc0e78 remove the dead analog-stick LED feature end to end
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>
2026-06-25 23:24:47 -03:00
Douglas Teles 4abec79f22 es-menu: drop dead VIDEO PREVIEWS / VRR toggles, warn on overlay-reset reboot
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>
2026-06-25 23:10:41 -03:00
Douglas Teles d65cb345bf emustation: speed up "Restart EmulationStation"
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>
2026-06-25 23:06:48 -03:00
Douglas Teles 4c0e295db2 es-menu: wire up AUTO FRAME DELAY and ship wg-quick for WIREGUARD VPN
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>
2026-06-25 23:06:48 -03:00
Douglas Teles f152192961 emulationstation: navigation sounds toggle takes effect without reboot
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>
2026-06-25 22:47:54 -03:00
Douglas Teles 3d1ad6e278 fix four minor gaps: rtl8188eus udev rule, bfq scope, hostname, tsadc
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>
2026-06-25 22:10:57 -03:00
Douglas Teles 3d18661bf8 pacman: seed the installed (local) db so pacman -Syu upgrades the base
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>
2026-06-25 22:04:29 -03:00
Douglas Teles 6a5781e4a4 RK3326: fix eeclone boot noise (phantom eMMC + uart5 CTS conflict)
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>
2026-06-25 21:22:10 -03:00
Douglas Teles 99a5ecb48a quirks: add temp-sensor configs for R36S Clone and Soysauce
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>
2026-06-25 21:10:40 -03:00
Douglas Teles e57e72e5fb debug: document ltrace build-test failure on the maintained fork
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.
2026-06-24 20:47:35 -03:00
Douglas Teles b92d67b9dd Close PortMaster_CFW.md guide gaps: sudo, vmstat, libjpeg.so.62, perf
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.)
2026-06-24 20:45:28 -03:00
Douglas Teles 1175e2b5a9 archr: symlink PortMaster compat libs into the default linker path
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).
2026-06-24 20:28:04 -03:00
Douglas Teles a3d131f0d5 init: resolve LABEL=/UUID= via util-linux blkid over /proc/partitions
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.
2026-06-24 19:36:06 -03:00
Douglas Teles f376a9f9b5 init: fix LABEL=ARCHR boot failure + bump RTL8188EUS to current HEAD
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.
2026-06-24 17:47:58 -03:00
Douglas Teles 33014076b4 Stop building panel overlays at image-build time
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.
2026-06-24 12:57:02 -03:00
Douglas Teles 226cea083e mipi-generator: SDCLONE flag para R36S Clone sem default sound card
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>
2026-06-24 12:30:17 -03:00
Douglas Teles e1c50c04f9 RTL8188EUS: out-of-tree driver para resolver auth fail (#19)
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>
2026-06-24 12:11:20 -03:00
Douglas Teles 0689a89c47 u-boot: boot.ini usa LABEL= em vez de /dev/mmcblkN paths
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>
2026-06-24 12:02:09 -03:00
Douglas Teles e48e9675a9 wifictl: corrigir trava de conexão com senha/SSID especiais
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>
2026-06-24 11:50:04 -03:00
Douglas Teles 44dfbad623 setrootpass: short-circuit via sha512crypt sem novo artefato sensível
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>
2026-06-24 11:40:02 -03:00
Douglas Teles e8fd3a6c43 perf: corrigir gaps detectados via SSH no R36S
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>
2026-06-24 11:37:36 -03:00
Douglas Teles e696461f7d 001-functions + archr-automount: corrigir refs herdadas
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>
2026-06-24 11:14:38 -03:00
Douglas Teles e90a0708c8 units + scripts: corrigir bugs herdados de JELOS no boot
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>
2026-06-24 11:09:58 -03:00
Douglas Teles fd1398b472 System Information: corrigir lacunas e adicionar Mesa/Arch info
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>
2026-06-24 10:31:54 -03:00
Douglas Teles abba87d061 ES + units: corrigir warnings do systemd-analyze e localizar .mo
systemd-analyze verify reclamava em 3 frentes:

1. StartLimitIntervalSec / StartLimitBurst em [Service] são
   silenciosamente ignorados, eles têm que ficar em [Unit].
   emustation.service e essway.service tinham os dois na seção errada,
   então a proteção contra restart-flood (Restart=always) nunca era
   aplicada. avahi-daemon.service tinha um StartLimitInterval (alias
   antigo, sem 'Sec') também na seção errada. Movidos para [Unit] em
   todos os três e renomeados para o key canônico.

2. sixaxis@.service é um template — instâncias são spawnadas sob
   demanda por udev (99-sixaxis.rules põe SYSTEMD_WANTS=sixaxis@%E
   {DEVNAME}). enable_service criava um symlink do template puro em
   multi-user.target.wants/, dangling porque template sem instância
   não roda. Removido o enable_service.

3. emulationstation procurava traduções em /usr/share/locale mas o
   ArchR embarca os .mo em /usr/config/locale via userconfig rsync,
   então o ES nunca encontrava emulationstation2.mo. Patch no fork ES
   (commits 8125fdf, 715ea4b no archr-linux/emulationstation-next):
   - main.cpp: prefere /usr/config/locale quando ele existe;
   - Platform.cpp: getArchString() lê HW_DEVICE do env (já exportado
     pelo profile.d/999-export) em vez de /usr/share/batocera/
     batocera.arch que nunca embarcamos;
   - Scripting.cpp: aceita /run/emulationstation/scripts além do
     legado /var/run/emulationstation/scripts.

archr-fhs-bridges.conf cria /run/emulationstation/scripts vazio em
todo boot para usuário poder dropar hooks (game-start, game-end,
system-selected, ...) sem mkdir manual após cada reset do tmpfs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 10:18:44 -03:00
Douglas Teles fcc56ec635 archr-config: corrigir paths Batocera no comando audio output
audio output X gravava o .asoundrc em /userdata/system/, herdado do
Batocera. Em ArchR a homedir de root é /storage, e o ALSA carrega
$HOME/.asoundrc, então o arquivo nunca chegava em lugar útil. Move
para /storage/.asoundrc.

A linha aplay tentava reproduzir /usr/share/sounds/Mallet.wav, que
não embarcamos. Trocar pelo launch.ogg dos retroarch-assets (já no
rootfs) e silenciar o erro com 2>/dev/null para não derrubar o
comando se a saída de áudio acabou de mudar e o aplay falha.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 09:58:46 -03:00
Douglas Teles d06e18a2ad gaps: ampla varredura de bugs herdados + pré-pacman repo-stable
A varredura via SSH no R36S rodando a 20260624 expôs várias
divergências entre rootfs estagiado e tmpfs/runtime. Cada arquivo
deste commit resolve um gap encontrado na investigação.

archr/tmpfiles.d/z_02_archr-fhs-bridges.conf (NEW):
  /var é tmpfs (busybox/system.d/var.mount), então todos os bridges
  FHS instalados como symlinks no rootfs eram apagados pelo mount.
  Republicar a estrutura via systemd-tmpfiles após var.mount. Resolve
  /var/lib/pacman, /var/cache/archr/*, /var/lib/archr/{config,data,
  games,backup}, /var/lib/{samba/private,tailscale,bluetooth},
  /var/spool/cron, /var/cache/pacman/pkg. Inclui também os targets em
  /storage (cron, locpath, tailscale, samba, .local/share, fstrim.run,
  journald.conf.d, request-key.d) que estavam ausentes.

ui/emulationstation/package.mk:
  ln -sf usava \${INSTALL}/usr/config/... como alvo, vazando o caminho
  absoluto do builder para o symlink /etc/emulationstation/es_systems.cfg
  no SO final. Trocar pelo path do target.

archr/system.d/timers.target.wants/{rocknix→archr}-report-stats.timer:
  Symlink apontava para um arquivo inexistente (rocknix-report-stats);
  o timer real chama-se archr-report-stats. Renome.

misc/modules/sources/images/install-{rocknix→archr}.svg:
  gamelist.xml já referenciava install-archr.svg; o arquivo se chamava
  install-rocknix.svg, quebrando o asset.

emulators/.../gamepads/ROCKNIX→ArchR Gamepad.cfg:
  Conteúdo já estava com input_device="ArchR Gamepad"; rename casa o
  nome de arquivo com a string de matching.

archr/package.mk + profile.d/005-locale:
  LANG="" no SO rodando, todas LC_*=POSIX. glibc gera en_US.UTF-8.
  Criar /etc/locale.conf e profile.d que source-a para shells de login
  e SSH (que não herdam LANG via systemd env).

sysutils/systemd/scripts/userconfig-setup + freej2me-lr/freej2me.sh:
  /storage/jdk caiu como arquivo vazio em algumas builds antigas e
  transforma o symlink /opt/jdk em "Not a directory". Saneamento
  duplo: a cada boot e antes do download do JDK.

devel/crossguid/package.mk + standalone/hypseus-singe/package.mk:
  cmake_install.cmake / crossguid-config.cmake embutiam o BUILD path
  do host. Remover dos pacotes target (não rodam em runtime).

tools/pyFDT/package.mk + network/samba/package.mk:
  setuptools e waf escrevem o python3 do TOOLCHAIN no shebang dos
  entry-points (pydtc, samba-gpupdate). Reescrever pra /usr/bin/python3.

sysutils/systemd/package.mk:
  systemd-sysroot-fstab-check é um symlink para
  systemd-fstab-generator, que removemos para fora dos generators.
  Apagar o link junto. Strip também a regra do legacy.conf que cria
  /var/log/README apontando para /usr/share/doc (não embarcamos docs).

sysutils/udevil/package.mk:
  /etc/udevil/udevil-user-root.conf é symlink para
  /storage/.config/udevil.conf que nunca era populado. Copiar a conf
  também para /usr/config/udevil.conf, daí o rsync do userconfig-setup
  o semeia no primeiro boot.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 02:44:45 -03:00
Douglas Teles 199e9a5ee4 security: bump gnupg to 2.4.8, add libksba/npth/pinentry deps
Live diagnostic on a R36S running the 20260624 image showed:

  archr:~ # gpg --version | head -1
  gpg (GnuPG) 1.4.23
  archr:~ # gpg --list-packets /usr/share/pacman/keyrings/archr.gpg
  :public key packet:
      ...
      unknown algorithm 22

GPG 1.4 is the "classic" branch, frozen before Ed25519 (algorithm 22)
was added in 2.1.x (2014). pacman-key 7.x also calls into gpg with
--check-signatures, a 2.x-only flag. With the ArchR master subkey
being Ed25519 the legacy 1.4 binary can neither parse nor verify the
keyring, so pacman -Sy fails with "no valid user IDs" and "signature
... is invalid" no matter how the user populates the keyring.

Fix the build, not the key. JELOS-era pacman packages cap GnuPG at
1.4.23 because that's the minimal-deps branch; ArchR is now an
Arch-family distro that ships pacman 7 as the user-facing update path,
so it has to ship the modern GnuPG runtime that pacman expects.

New packages:
- libksba 1.8.0
- npth 1.8
- pinentry 1.3.2 (built with --enable-pinentry-tty/curses only;
  the GUI variants would pull GTK/Qt that the handheld doesn't have)

Updated:
- gnupg 1.4.23 -> 2.4.8 (latest LTS branch)
  Configure trims to the bits pacman uses: gpg + gpgsm + gpgconf.
  scdaemon, dirmngr, tofu, wks, gpg-card and the historical 1.4-era
  ciphers (idea/cast5/md5/rmd160) are disabled to keep the image lean.
  pinentry-tty is the configured pinentry program, since the handheld
  has no graphical desktop session to use the other variants.

libassuan, libgcrypt and libgpg-error already live in projects/ArchR/
packages/security/ from earlier work — no new dep tree there.

This unblocks the pacman pipeline on R36S: archr-keyring populate will
parse the Ed25519 master, signature verification will accept the
ArchR-signed archr.db, and pacman -Sy lands at the package list.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 01:59:24 -03:00
Douglas Teles cceafdaca0 pacman: rewrite /usr/sbin/bash shebangs to /usr/bin/bash
Upstream pacman ships pacman-key, makepkg, vercmp and friends as bash
scripts whose shebang is built against the configured sbindir (/usr/sbin
on Arch). Arch ships /usr/sbin as a symlink to /usr/bin via the usrmerge
package, so the shebang resolves fine. ArchR (LibreELEC heritage)
does NOT merge sbin: /usr/sbin is a real directory and bash lives at
/usr/bin/bash only. Result on a fresh boot:

  archr:~ # pacman-key --init
  -sh: /usr/bin/pacman-key: /usr/sbin/bash: bad interpreter: No such
  file or directory

which also makes the pacman-init.service silently miss the keyring
populate step.

Post-install pass that rewrites every "#!/usr/sbin/bash" first line
to "#!/usr/bin/bash" anywhere under ${INSTALL}/usr fixes the lot in
one shot. The pkg.tar.zst we ship in the repo will need the same
treatment, but that's handled at build time too because gen-pacman-repo
packages whatever install_pkg holds.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 01:51:41 -03:00
Douglas Teles 6ce926d537 pacman: install /var/lib/pacman as symlink, not dir + child symlink
User reported on a freshly flashed R36S:

    archr:~ # pacman
    error: failed to initialize alpm library:
    (root: /, dbpath: /var/lib/pacman/)
    could not find or read directory

The package.mk created /var/lib/pacman as a real directory in
post_makeinstall_target (mkdir -p), then in post_install ran
`ln -sf /storage/.pacman/db ${INSTALL}/var/lib/pacman`. When LINK is
an existing directory, ln -sf does not replace it — it creates
LINK/$(basename TARGET). So the installed image ended up with:

  /var/lib/pacman/                ← real, empty dir (rootfs, ro)
  /var/lib/pacman/db -> /storage/.pacman/db   ← child symlink

Pacman reads dbpath=/var/lib/pacman/ from pacman.conf, looks for
local/ and sync/ inside it, finds nothing, and bails.

Fix: install /var/lib/pacman directly as a symlink to
/storage/.pacman/db in one shot, no intermediate mkdir. Same for
/var/cache/pacman/pkg. Move both into post_makeinstall_target so the
file layout is decided in one place; post_install now only enables
the pacman-init service.

Runtime escape hatch on already-installed systems (since the rootfs
is squashfs-ro and can't be patched):

    mount --bind /storage/.pacman/db /var/lib/pacman
    mount --bind /storage/.pacman/cache /var/cache/pacman/pkg

This commit fixes the build so the next image flashes correctly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 01:30:02 -03:00
Douglas Teles 2bb9ebb50a gen-pacman-repo: fall back to dirname when PKG_VERSION is a shell expr
awk -F'"' '/^PKG_VERSION/ ...' pulls the literal string out of the
package.mk, but a handful of packages set their version dynamically:

    PKG_VERSION="$(get_pkg_version gstreamer)"

The build system resolves that at build time and the install_pkg dir
ends up correctly named (gst-libav-1.27.1/). The packager, though, was
storing the raw "$(get_pkg_version gstreamer)" string, which then
went through the charset filter and became ".get_pkg_version.gstreamer."
in the asset name. Five packages slipped through in the first
repo-dev release with broken names (gst-libav, gst-plugins-good,
vitaquake2-{rogue,xatrix,zaero}-lr).

Detect any '$(' or '${' in the version string and treat it as
"unresolved", which trips the existing dirname-suffix fallback.
27 ArchR packages use this pattern; the fix covers all of them.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 00:32:18 -03:00
Douglas Teles 190469075f docs: 2.1 marked complete after the first repo-dev release
repo-dev now exists on archr-linux/archr-repo with all 543 assets
(535 packages + 8 db artifacts) signed via the master subkey we
generated yesterday. SigLevel PackageOptional DatabaseRequired
matches the SteamOS/EndeavourOS/Arch-ARM model.

Open follow-ups noted in the entry:
- CI hook so the publish is no longer a manual one-hour job after
  every build.
- Channel promotion (dev -> next -> stable) when v2.0 final lands.
- gen-pacman-repo version parser fails on 5 packages whose
  package.mk uses a placeholder (gstreamer family, vitaquake2-lr
  variants); not a runtime blocker but the dirnames are ugly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 00:27:34 -03:00
Douglas Teles 7addeb691a pacman: drop per-package signing, sign only the repo db
First repo-dev release uploaded 1000/1078 assets before hitting
GitHub's documented per-release limit of 1000 assets. The cap is
hit because every package shipped a paired .sig, doubling the
count without adding meaningful security.

The trust path now flows entirely through the database:
  - archr-keyring ships the master public key.
  - archr.db.sig proves the db came from the maintainer.
  - The db records the SHA256 of every package; pacman re-hashes
    after download and refuses mismatches.

To compromise a package the attacker would have to publish a
modified db that lists their hash, which requires the signing
subkey. The per-package .sig was redundant against this attack.

This is the same model Arch Linux ARM, EndeavourOS and SteamOS
use in production.

pacman.conf SigLevel flips from "Required DatabaseOptional" to
"PackageOptional DatabaseRequired"; comment expanded so a future
reader sees the why.

gen-pacman-repo drops the `gpg --detach-sign` step inside
build_one_pkg(); repo-add --sign still signs the db at the end.
Asset count shrinks from 1078 to 543 (535 packages + 8 db
artifacts), which fits comfortably in a single GitHub Release.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 23:27:27 -03:00
Douglas Teles be19e9ec47 mali-bifrost: revert 003 patch to the pre-sync ArchR version
The ROCKNIX-sourced rewrite of 003-midgard-refactor-power-init-and-
fixed-unbalanced-run.patch (picked up in 5805267f90) targets a
different kbase tree: it patches platform/devicetree/mali_kbase_runtime_pm.c
expecting `else if (!regulator_is_enabled(...))` on line 38.
Our mali_kbase pin (github.com/archr-linux/mali_kbase @ 422e192b)
does not have that line, so the hunk rejects and mali-bifrost:target
fails to install.

Restore the original 199-line patch that targets platform/meson/
mali_kbase_runtime_pm.c, which is the path that exists in our tree.
This was the file as of commit 5805267f90^ — the working pre-sync
state.

The ROCKNIX cleanup will become applicable when (and if) we move to
the same kbase revision they ship, which would itself be a bigger
upgrade.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 21:03:58 -03:00
Douglas Teles 70fb40de43 archr: drop F7 hatari/openbor bridges, fall through umbrellas
In F7 I added explicit bridge symlinks for hatari and openbor:
  ln -sf /storage/.hatari /var/lib/archr/data/hatari
  ln -sf /storage/openbor /var/lib/archr/games/openbor

That breaks the build at install time. The F5/F6 umbrella bridges
already turn /var/lib/archr/data and /var/lib/archr/games into
symlinks (-> /storage/.local/share and /storage/roms). When the
hatari ln -sf tries to create a child node under
/var/lib/archr/data, it follows the umbrella symlink, hits
/storage/.local/share which does not exist on the rootfs at build
time, and aborts with "No such file or directory".

Resolution: rely on the umbrella alone. /var/lib/archr/data/hatari
resolves to /storage/.local/share/hatari at runtime through the
umbrella; start_hatari.sh and start_OpenBOR.sh already mkdir -p the
final dir on first launch, so the dir materializes when needed.

Keep the /opt/jdk bridge because there is no /opt umbrella to fall
through.

This is the second clean-build fix on top of the wayland patch
rebase (7eff5d02a6).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 20:27:23 -03:00
Douglas Teles 7eff5d02a6 wayland: rebase pkgconfig patch for 1.25.0
The 00-fix-wayland-scanner-pkgconfig.patch was anchored on a context
line ('bindir=' + join_paths(...)) that Wayland removed between 1.24
and 1.25. After our F0 bump to 1.25.0 the unpack step rejected the
patch and aborted the build_compat arm pass.

Pull the rebased patch from ROCKNIX (commit a9e464274a in their
graphics/display sync) where the same context shift was already
resolved: the bindir line is gone, the filebase line stays.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 17:59:44 -03:00
Douglas Teles 41d376a029 gen-pacman-repo: fix package layout for pacman 7 repo-add
Three bugs caught while smoke-testing against an existing
build.ArchR-RK3326.aarch64/install_pkg tree:

1. BUILD_DIR auto-detection glob did not include the trailing arch
   suffix, so build.ArchR-RK3326.aarch64 never matched. Now matches
   build.*-RK3326*aarch64*.

2. Version sanitization used `echo | tr -c '[charset]' '.'` which
   turns the trailing newline into a stray '.', producing versions
   like "1.0.8." that pacman refuses. Swapped to printf.

3. Package layout was wrong for pacman 7 repo-add:
   - .PKGINFO must be the FIRST entry in the tar (pacman streams it).
   - No "./" prefix on file names (matches makepkg output).
   - .PKGINFO needs `pkgbase` and `xdata = pkgtype=pkg` lines, not
     just `pkgname`.
   Rewrote the packing block to assemble an explicit file list with
   .PKGINFO first, then tar -T.

Also: install_pkg name extraction is more robust now — sed strips
both 40-char git hashes and semver suffixes to recover the real
package name, and the package.mk lookup uses find rather than
literal globbing so packages nested at any depth are found.

Smoke test confirms repo-add accepts the resulting archive, signs
archr.db with the configured signer, and emits the expected
symlinks archr.db -> archr.db.tar.gz.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 17:43:08 -03:00
Douglas Teles 43e464525f archr-keyring: ship the production ArchR master public key
Master generated 2026-06-23 offline (ed25519 cert-only with ed25519
sign subkey expiring 2028-06-23). Private master lives on encrypted
cold storage; the signer subkey is on the build workstation only.
Revocation certificate kept offline in two physical locations.

Fingerprint: 0CB282379EBB394EF380AEB98A762D5706C602A1

archr.gpg is the binary public keyring that pacman-key --populate archr
walks; archr-trusted gives the master full ownertrust (level 4) so
packages signed by its subkey are accepted; archr-revoked stays empty
until a key is actually revoked.

archr-keyring/package.mk already auto-detects these files (instead of
the empty placeholders it shipped before) and includes them in the
image. With the keyring populated, the next gen-pacman-repo run with
SIGNER set will produce a properly signed archr.db and per-package
.sig files that ArchR clients can verify.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 17:35:06 -03:00
Douglas Teles b6ceea9347 2.1: pacman as real update mechanism (client side)
Decision: pacman repo lives on GitHub Releases at
archr-linux/archr-repo. No VPS, no repo.arch-r.io. Google Drive stays
out of runtime (backup/archive only). Cloudflare R2 fallback deferred.
Detail in docs/release-policy.md.

archr-update rewritten end-to-end:
- 188 lines of dead POST-to-update.arch-r.io code replaced by an
  87-line wrapper around pacman -Syu. The POST endpoint never existed
  so there is no legacy compat to preserve.
- subcommands: check, update, info. system.cfg "updates.branch" maps
  to repo-stable / repo-next / repo-dev tags on archr-linux/archr-repo;
  the mirrorlist is rewritten on every invocation so channel switches
  are immediate.

pacman.conf rebuilt around a single [archr] repo (Arch Linux ARM
upstream removed). SigLevel starts at "Required DatabaseOptional"
during bootstrap; will tighten to "Required" once the production
master key signs the .db.

pacman-init reachability test points at github.com and the keyring
populate target is "archr" instead of "archlinuxarm".

archr-keyring repurposed: the three archlinuxarm keyring files are
removed; package.mk now expects archr.gpg / archr-trusted /
archr-revoked under keys/ and ships empty placeholders until the real
ArchR master key is generated.

scripts/repo/gen-pacman-repo + README: take the build.*-RK3326 tree
that "make docker-RK3326" leaves behind, package each install_pkg/<x>
as a .pkg.tar.zst with synthesized .PKGINFO, run repo-add to build
archr.db, optionally GPG-sign everything. Emits a `gh release create`
command for the publish step. CI hook left as a follow-up.

docs/improvements.md 2.1 marked partial: client and build script are
ready; what blocks the first usable release is generating the GPG
master key, creating archr-linux/archr-repo on GitHub, and one manual
publish for the repo-dev tag to validate the end-to-end loop.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 17:03:35 -03:00
Douglas Teles 3beb86f3d4 docs: close Arch-ification 2.5 in improvements.md
Quirks pruning done in 7644ce26d3 (352 files, 8037 lines). Splash
rename and runemu.sh refactor reclassified as organic follow-ups:
- splash sed stays until upstream archr-splash repo finishes the
  internal rename.
- runemu.sh is 578 lines (not 1500+ as the original entry guessed);
  refactor still pays in maintainability but is not a blocker.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 16:34:37 -03:00
Douglas Teles 7644ce26d3 2.5 KISS: prune dead-platform and dead-device quirks
projects/ArchR/packages/hardware/quirks/ shipped 50 device dirs and
10 platform dirs inherited from JELOS/ROCKNIX. ArchR only ever
supports RK3326 (one platform), and the per-device quirks are
selected at runtime by reading /sys/firmware/devicetree/base/archr,device_switch/this
— a name that can only match a DTB we compiled in. The 42 device
dirs without a matching DTB and the 9 platform dirs for SoCs we
don't have (H700, RK3399, RK3566, RK3588, S922X, SDM845, SM8250,
SM8550, SM8650) were unreachable code.

Keep: 14 device dirs and 1 platform (RK3326). All correspond to a
DTS file in projects/ArchR/devices/RK3326/linux/dts/rockchip/ so
they can actually be selected at boot.

Cross-references to the dead platforms in other scripts (case
${DEVICE} in RK3399) ...; case ${DEVICE} in SM8250) ...) stay
as harmless dead branches that never trigger when DEVICE=RK3326;
cleaning those up is in scope for a follow-up sweep.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 16:32:36 -03:00
Douglas Teles 54a79b99aa docs: mark Arch-ification 2.2 (FHS) closed in improvements.md
Section 2.2 now reflects what shipped: auditoria + 22 bridges + 7 vars
+ man page + 7 phases all marked done. Open item left explicit: the
1625 hardcoded /storage refs in legacy scripts continue to work via
compat and refactor organically.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 16:28:33 -03:00
Douglas Teles d10869a802 FHS F7: Class Z + migration complete
Three concrete Class Z migrations land via bridges in the archr meta-
package plus single-line script tweaks:
- /storage/jdk -> /opt/jdk (runemu.sh JAVA_HOME, freej2me.sh JDKDEST)
- /storage/.hatari -> /var/lib/archr/data/hatari (start_hatari.sh
  HATARI_DIR_HOME; the pre-baked Atari-ST .cfg files keep working
  through the symlink because both addresses resolve to the same
  overlay dir).
- /storage/openbor -> /var/lib/archr/games/openbor (start_OpenBOR.sh
  CONFIGDIR).

Other Class Z paths fall out cleanly:
- /storage/.opt was already covered by /opt -> /storage/.opt symlink
  in virtual/image/package.mk.
- /storage/.emulationstation already gets redirected to
  /storage/.config/emulationstation by emulationstation's autostart,
  which is in turn covered by the umbrella bridge F5.
- /storage/psvita/vita3k/ux0/app and /storage/.nfs-mount are
  low-traffic top-level paths; no bridge added.

docs/fhs-mapping.md: Fase 7 detail + system-wide audit summary. 17
umbrella bridges in archr meta-package + 5 modular (openssh, iwd,
bluez, connman, fontconfig). All seven ARCHR_* variables resolve to
Arch-friendly paths. The remaining 1625 hardcoded /storage refs in
projects/ArchR continue to work through compat (both paths reach the
same storage overlay); refactoring those is left as an organic
follow-up.

Status header marks the FHS migration complete. Section 2.2 of the
Arch-ification roadmap is now closed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 16:27:58 -03:00
Douglas Teles 917988587a FHS F6: Class E via umbrella bridge
Same playbook as F5, applied to user data. /storage/roms appears in
117 files in projects/ArchR and refactoring every reference in one
shot would be a huge diff over the directory where the user's games
library lives. Bad risk-reward.

Two new umbrella bridges in the archr meta-package:
  /var/lib/archr/games  -> /storage/roms
  /var/lib/archr/backup -> /storage/backup

ARCHR_GAMES flipped to the FHS path; man page mirrors it.

The other Class E paths (screenshots, recordings, downloads, music,
pictures, videos, tvshows) audit as zero references in
projects/ArchR; they are LibreELEC top-level heritage and not used at
ArchR runtime.

/storage/.ssh stays as is. busybox/package.mk sets the root user's
HOME to /storage, so /storage/.ssh is literally $HOME/.ssh — FHS
already. Moving to /root/.ssh would require flipping the HOME of root
to /root first, which has knock-on effects (cd ~, every script that
assumes cwd at login, etc) outside the FHS scope.

No data migration script: nothing on disk moves. ROMs and saves keep
exactly the same bytes; the FHS path is just another way to address
them.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 16:25:04 -03:00
Douglas Teles 4a6cb841db FHS F5: Class B via umbrella bridge
Original F5 plan was "one commit per emulator, refactor every
hardcoded /storage/.config/<emu> reference". Audit showed that path
appears across 22+ device quirk files, multiple start scripts and a
handful of compiled-in patches per emulator. Mass refactor would be a
huge diff with real regression risk and zero FHS gain on the running
system because, with the bridge installed, the FHS path already
resolves correctly.

Pivot: install two umbrella bridges in the archr meta-package:
  /var/lib/archr/config -> /storage/.config
  /var/lib/archr/data   -> /storage/.local/share

Flip the ARCHR_CONFIG and ARCHR_DATA exports in 010-archr-fhs to the
FHS paths so downstream scripts that already use the variables get
the Arch-friendly surface for free. Update archr(7) ENVIRONMENT
section: both variables now describe the FHS location as the actual
address, with /storage/... noted as the rw-overlay substrate.

Net effect: every /var/lib/archr/config/<emu> and
/var/lib/archr/data/<emu> path exists at runtime and is writable.
Inspection tools see a normal Arch layout. Hardcoded /storage/.config
references in JELOS-inherited quirks and start scripts keep working
because the symlink resolves both ways — writes through either path
land in the same overlay file. Per-emulator refactors stay possible
later, as incremental PRs, without a single big-bang.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 16:23:05 -03:00
Douglas Teles a20ecf72b9 docs: FHS F4 closing notes
Fase 4 in fhs-mapping.md gets the breakdown: 9 state dirs bridged in
the four F4.x commits (ssh, iwd, bluez, services, samba, connman,
wireguard, tailscale, cron), pacman db/cache and rfkill noted as
no-op (already bridged upstream), .local/share moved to F5 (it is
per-emulator data and stays with each emulator's config migration),
overlayfs upperdirs documented as permanent no-op for the same
constraint that pinned the F3 workdirs, .pacman/build deferred to
section 2.1 when pacman gets wired into userland.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 16:19:28 -03:00
Douglas Teles 3c589686be FHS F4.3: service enable flags + samba/connman/tailscale/cron state
Wider Class D batch. Every state directory referenced by a systemd
unit or runtime script now lives at an Arch-conventional path with a
bridge symlink into /storage:

service enable/disable flags
  /storage/.cache/services -> /var/lib/archr/services
  ConsumerS: 099-networkservices, archr-report-stats.timer, and the
  12 unit files that gate themselves on .conf / .disabled sentinels
  (avahi-daemon, avahi-defaults, sshd, nmbd, smbd, simple-http-server,
  syncthing, tailscaled, zerotier-one, cron, cron-defaults). The
  systemd-scripts/usercache-setup migration helper updated too.

samba passdb
  /storage/.cache/samba -> /var/lib/samba/private (Arch standard).
  smb.conf passdb line + 007-rootpw boot init script updated.

connman + wireguard
  /storage/.cache/connman -> /var/lib/connman
  /storage/.config/wireguard -> /etc/wireguard (vpn_storagedir)
  Bridges installed by the connman package; connman-setup script
  follows the bridge.

tailscale
  /storage/.cache/tailscale -> /var/lib/tailscale.
  tailscaled --state= flag flipped to the FHS path; bridge in archr
  meta-package.

cron
  /storage/.cache/cron -> /var/spool/cron (Arch convention; busybox
  crond reads spool/<user>). cron.service ExecStartPre updated.

archr meta-package now ships seven Class D bridge symlinks alongside
the five Class C bridges from earlier phases. Everything else stays
on the storage overlay; nothing on disk moved.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 16:17:55 -03:00
Douglas Teles 918e3158e9 FHS F4.2: bluez storage to /var/lib/bluetooth
bluez configure storagedir flipped to /var/lib/bluetooth (Arch
convention for paired-device state). post_makeinstall_target plants
the bridge symlink to /storage/.cache/bluetooth so pairings persist
on the rw overlay across reboots.

archr-config forgetBT helper and backuptool default list also point
at the FHS path.

tmpfiles z_05_bluez.conf intentionally keeps creating
/storage/.cache/bluetooth as the real overlay dir.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 16:14:04 -03:00
Douglas Teles cd87193b86 FHS F4.1: ssh host keys + iwd state to /var/lib (credentials)
Two security-sensitive state dirs migrated to Arch-standard locations.

openssh:
- --with-keydir flipped from /storage/.cache/ssh to /var/lib/sshd.
- post_install plants a bridge symlink /var/lib/sshd ->
  /storage/.cache/ssh so keys persist on the rw overlay.
- sshd.service updates all three ExecStartPre paths.
- tmpfiles z_04_openssh.conf keeps creating /storage/.cache/ssh as
  the real overlay dir.

iwd:
- Environment STATE_DIRECTORY in iwd.service now /var/lib/iwd.
- post_makeinstall_target adds the /var/lib/iwd ->
  /storage/.cache/iwd bridge symlink.
- wifictl (IWD_DIR, IWD_AP_CFG_DIR), post-update copy target and
  userconfig-setup all flipped to /var/lib/iwd.
- tmpfiles z_03_iwd.conf keeps creating the backing dirs.

Both follow the same bridge pattern as F2/F3: FHS surface, storage
overlay substrate. SSH host keys and wifi credentials survive the
migration because the underlying bytes never move (symlink swap).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 16:12:39 -03:00
Douglas Teles 71d8968a1a FHS F3: logs and update over Arch paths
Class F (logs) and Class G (temp/update) reshuffled.

Logs:
- /var/log was already a mount from /storage/.cache/log via
  packages/sysutils/busybox/system.d/var-log.mount, so journald already
  writes to /var/log/journal in FHS terms. runemu.sh debug log moves
  from /storage/.cache/log/runemu-debug.log to /var/log/runemu-debug.log
  (same physical bytes, FHS surface).
- createlog (top-level busybox script) packs archive zips into
  /var/log/archr/archive instead of /storage/logfiles. ArchR tmpfiles
  z_01_archr.conf creates the backing dir under the storage overlay so
  the path is writable on first boot.

Update:
- /var/cache/archr/update is a bridge symlink to /storage/.update added
  by the archr meta-package. archr-update, automount and the [update]
  samba share all flipped to the FHS path.
- factoryreset still preserves /storage/.update by its real name in
  the find regex; that path is also what the pre-boot bootloader
  scripts read, so the backing path is the canonical one and the
  bridge is just the userland surface. Comment added so this is
  obvious to future readers.
- busybox/scripts/init keeps UPDATE_ROOT=/storage/.update because it
  runs in the initramfs before /var is even available.

Overlayfs workdirs (/storage/.tmp/*-workdir) and /storage/.boot.hint
documented as no-op in fhs-mapping.md: the overlayfs kernel layer
requires upperdir and workdir to share a filesystem, and the boot
hint is part of the U-Boot handshake.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 16:02:59 -03:00
Douglas Teles baddc23110 FHS F2.4 + close: fstrim.run bridged, F2 complete
Last Class C bridge: /var/cache/archr/fstrim.run -> /storage/.cache.
The stamp file does not exist at first boot; touch follows the symlink
and creates the file on the storage side, where future fstrim runs
read it to remember the last run.

docs/fhs-mapping.md updated:
- Fase 2 marked complete with the 5 caches actually migrated
  (mesa, fontconfig, kernel-overlays, locpath, fstrim.run).
- Documents that the initial Class C bucket of 44 paths was a coarse
  auto-classification: most of those paths are state (-> F4 / Class D),
  logs (-> F3 / Class F) or already redirected upstream.
- Three already-no-op redirects called out: journald.conf.d,
  systemd-machine-id, system_timezone (already symlinked by their
  owning packages).

Next: F3 (Class F+G, logs and temp).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 15:56:21 -03:00
Douglas Teles 61cbea372e FHS F2.3: kernel-overlays + locpath under /var/cache/archr
Two more Class C bridges, same pattern as F2.1/F2.2:
- /var/cache/archr/kernel-overlays -> /storage/.cache/kernel-overlays
- /var/cache/archr/locpath -> /storage/.cache/locpath

Consumers flipped to the Arch-friendly path:
- busybox/scripts/kernel-overlays-setup: OVERLAY_CONFIG_DIR
- busybox/profile.d/10-locale.conf: LOCPATH
- wayland/util/foot/scripts/foot.sh: LOCPATH (ArchR override only)

Service files (locale.service, kernel-overlays tmpfiles.d) keep
addressing the /storage backing path because they are the layer that
creates the actual rw overlay dir; the bridge symlink points at it.

Top-level packages/wayland/util/foot/scripts/foot.sh is upstream
LibreELEC heritage and stays untouched; the ArchR override is the
file the runtime actually executes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 15:54:46 -03:00
Douglas Teles c370b0ca48 FHS F2.2: fontconfig cache -> /var/cache/fontconfig
Fontconfig's cache directory is baked into the binary at configure
time. Flip --with-cache-dir from /storage/.cache/fontconfig to the
Arch-standard /var/cache/fontconfig and install a bridge symlink
pointing back to the storage overlay so the cache survives reboots.

Same bridge pattern as the systemd /etc redirects and the F2.1 mesa
shader cache: surface looks FHS, substrate stays on /storage.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 15:52:38 -03:00
Douglas Teles a5b1862117 FHS F2.1: mesa_shader_cache -> /var/cache/mesa
First migration of the Class C cache work: the Mesa shader cache moves
from the LibreELEC-style /storage/.cache/mesa_shader_cache to the
Arch-standard /var/cache/mesa.

Implementation follows the bridge-symlink pattern systemd already uses
for /etc/*: the archr meta-package creates /var/cache/mesa as a
build-time symlink into /storage/.cache/mesa_shader_cache. Mesa,
runemu.sh and any inspector see the FHS path; writes still land on the
storage overlay so the cache survives reboots.

archr/package.mk: mkdir /var/cache, ln -sf the symlink.

quirks/profile.d/041-panfrost: MESA_SHADER_CACHE_DIR=/var/cache/mesa.
Comment explains the bridge so future readers do not assume tmpfs.

runemu.sh: create the cache dir through /var/cache/mesa instead of
the legacy /storage path. Comment updated to mention the symlink.

systemd/tmpfiles.d/z_01_archr.conf is intentionally left targeting the
backing path /storage/.cache/mesa_shader_cache: it is internal plumbing
that must guarantee the real overlay dir exists; /var/cache/mesa is
the surface, /storage/.cache/mesa_shader_cache stays the substrate.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 15:51:37 -03:00
Douglas Teles 2227151d46 FHS F1: marked no-op (systemd already redirects /etc paths)
Audit of projects/ArchR/packages/sysutils/systemd/package.mk showed
the Class A paths are already FHS-correct at runtime: systemd creates
build-time symlinks from /etc/modules-load.d, /etc/sysctl.d,
/etc/tmpfiles.d, /etc/udev/{hwdb,rules}.d and /etc/systemd/*conf.d
pointing into /storage/.config/.

For any tool inspecting the running system, /etc/modules-load.d is a
real populated directory in /etc. The fact that the symlink target
lands on the storage overlay is internal plumbing required because
the rootfs is squashfs read-only.

Repointing those targets to /var/lib/archr/etc would be cosmetic in
exchange for adding a bind-mount in the init script. Not worth it.

hosts/resolv keep their existing template+render pipeline
(network-base-setup reads /storage/.config/{hosts,resolv}.conf and
writes /run/archr/{hosts,resolv}.conf at boot).

Fase 1 closed without code change. Fase 2 (Class C: cache) is next
and has actual work.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 15:48:59 -03:00
Douglas Teles ca904d5257 FHS F0: introduce ARCHR_* path vocabulary
profile.d/010-archr-fhs exports seven variables (ARCHR_ETC,
ARCHR_CONFIG, ARCHR_CACHE, ARCHR_DATA, ARCHR_GAMES, ARCHR_LOG,
ARCHR_TMP) that future ArchR scripts should read instead of
hardcoding /storage/.config and siblings. Every variable defaults to
its current /storage location so behaviour is identical to today;
subsequent FHS phases will flip the right-hand side without touching
the callers.

archr(7) gains an ENVIRONMENT section describing each variable, its
current value and its FHS target so anyone writing a new script knows
which name to use.

docs/fhs-mapping.md: F0 marked complete; F1..F7 still pending.

Risk: zero. The new file is read at login but only sets variables.
No script reads them yet.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 15:35:31 -03:00
Douglas Teles cc5febb42f docs: FHS migration plan for Arch-ification 2.2
docs/fhs-mapping.md: full audit (297 unique /storage paths classified
across 7 classes A-G + Z special cases), seven-phase plan, rules of
the road. Phase 0 introduces the vocabulary (vars in
/etc/profile.d/archr-fhs.sh) without moving any data. Each subsequent
phase ends in a commit with grep + boot validation before the next
one starts. User data (saves, ROMs) is phase 6, only after all other
phases survived at least one release on the stable channel.

.gitignore: whitelist docs/fhs-mapping.md so the plan stays tracked
alongside improvements.md and release-policy.md while the rest of
docs/ remains user-local.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 15:33:09 -03:00
Douglas Teles 2c960e72d1 docs: track improvements.md and release-policy.md
.gitignore had docs/* blocking everything; the rest of the directory
remains user-local notes, so whitelist only the two files that belong
to the project: improvements.md (Arch-ification roadmap, with the
architectural decision that LibreELEC overlay is by design) and
release-policy.md (semver-RC until v2.0, YYYY.MM.PATCH after, three
release channels mapped to updates.branch).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 15:15:12 -03:00
Douglas Teles 1dbf5705ca linux: fix incomplete 6.12.94 bump
Commit 4273d71442 was meant to bump PKG_VERSION 6.12.79 -> 6.12.94 and
remove the now-upstream u_ether patch in one commit, but the git add
failed silently on a path that had already been git-rm'd, so only the
patch deletion landed and the version bump itself stayed unstaged.

This adds the missing PKG_VERSION and PKG_SHA256 lines so the build
actually picks up 6.12.94.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 15:00:46 -03:00
Douglas Teles 7c82f31dae Arch-ification 2.6 + 2.7: identity files and archr(7) man page
scripts/image: rewrite /etc/os-release block to the freedesktop layout
expected by third-party tools. ID_LIKE=arch is the change that makes
ArchR detect-cleanly as Arch family across distros, package managers
and analytics. PRETTY_NAME, ANSI_COLOR, LOGO, DOCUMENTATION_URL,
SUPPORT_URL and BUG_REPORT_URL added on top, with sensible fallbacks
from GIT_ORGANIZATION/GIT_REPO when the user has not overridden them
in distributions/ArchR/options.

Drop the empty /etc/archr-release sentinel file alongside os-release.
Arch ships /etc/arch-release the same way (empty by convention) for
tools that detect distro family by file presence rather than by parsing
os-release.

distributions/ArchR/options: fix typo HOME_URL "arc-r.io" -> "arch-r.io".

projects/ArchR/packages/archr: ship archr(7) under /usr/share/man/man7.
First man page of the distro, covers the public command surface
(archr-update, archr-config, archr-systems, etc.), the file locations
that matter (/etc/os-release, /etc/archr-release, /storage layout) and
the architectural decision recorded today (LibreELEC-style read-only
rootfs + storage overlay is by design, not technical debt; SteamOS
validates the model).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 15:00:08 -03:00
Douglas Teles 4273d71442 linux: bump RK3326 kernel 6.12.79 -> 6.12.94 (LTS)
Sliding within the same 6.12 LTS branch (longterm support runs until
December 2026), this picks up 15 stable patch releases of bugfix
and CVE work without touching ABI/API.

Pin the source tarball with PKG_SHA256 so a network MITM cannot
silently swap the kernel under us.

Drop 0020-usb-gadget-u_ether-guard-NULL-gadget-in-eth_get_drvinfo.patch
— that fix landed upstream in 6.12.81 stable. Keeping our copy would
conflict on apply.

The remaining nine patches all touch areas (panfrost, ntsync,
rtl8xxxu) that received no churn in the 79..94 window, so they
should apply unchanged; the next docker-RK3326 build will confirm.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 14:28:19 -03:00
Douglas Teles b56fd7cce6 Sync sysutils fixes from ROCKNIX
systemd: re-enable timedated (was -Dtimedated=false). Drop the
post-install safe_remove that nuked /usr/bin/timedatectl so users
can finally run timedatectl set-timezone from the shell. Two
upstream-equivalent patches accompany the build: 0600 redirects
the timedated write target to /var/run/localtime (writable on our
read-only rootfs), 0601 makes the timezone reader follow indirect
symlinks (matches the /etc -> /storage layout).

udevil: pull the cleaned udevil.conf (UFS gate moved from
allowed_devices to forbidden_devices, /dev/sd* whitelisted as
removable). The udev rule now bails on anything that is not
usb-storage. Internal mmc devices were never matched by the prior
KERNEL=="sd*|sr*" filter anyway, but this makes the intent
explicit and stops misclassified eSATA-like devices.

input_sense: grep -line-buffered before the parse loop so only
EV_KEY / EV_SW / error-reading lines reach the case statement.
evtest output is mostly EV_ABS noise we threw away anyway; this
cuts the CPU spent on the dispatch hot path on every controller.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 14:22:51 -03:00
Douglas Teles 120d279213 Sync standalone + libretro emulator fixes from ROCKNIX
retroarch: bump to commit bdba046f (v1.22.2 + fixes) and rebase the
two local patches (0010-paths, 0011-cheevos-sounds) so they apply
cleanly against the new tree.

setsettings.sh: configure_hotkeys now detects the InputPlumber-emulated
DualSense pad first, then falls back to js0 / joypad. Without this,
retroarch took the raw event device and the hotkey binding never
matched what InputPlumber actually exposed to userspace.

drastic-sa: pull the new libdrastouch (sharp-shimmerless + quilez
pixel shaders, SDL2 hook) and the matching start_drastic.sh, which
now reads the shader setting and exports DSHOOK_SHADER. Drops the
dead S922X libmali block we never executed on RK3326.

hypseus-singe: rewrite of start_hypseus.sh fixes broken controls
(autoconfig.cfg lookup was matching too loosely) and adds the
set_kill on exit so the quit hotkey actually terminates the
emulator instead of leaving it parented to ES.

ppsspp-sa: add 005-hide-unsupported-ui-items.patch to drop the
"www.ppsspp.org" link and the "Buy PPSSPP Gold" button from the
main screen. Handheld UX cleanup, no behavioral change.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 14:22:31 -03:00
Douglas Teles 5805267f90 Sync RK3326 + 6.12-LTS bugfixes from ROCKNIX
mali-bifrost (RK3326): replace patch 003 with the clean RK3576-style
version. Drops the dead BSP-style probe-defer dance, balances the
regulator refcount during probe (mirrors the clock prepare/enable),
and removes the regulator_is_enabled guard that was silently skipping
the disable on suspend. Frees the kernel log of the "missed warnings"
sunshineinabox flagged.

iwd (network): ControlPortOverNL80211=true so 802.1X EAPOL frames go
through nl80211 instead of the legacy raw socket. Some clones with
modern wifi firmware fail association otherwise.

linux 6.12-LTS: add 0020-usb-gadget-u_ether-guard-NULL-gadget upstream
fix. Without it, querying ethtool on the surviving NCM interface
during gadget detach dereferences a NULL dev->gadget pointer and
panics. Affects anyone who flips USB gadget mode at runtime.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 14:16:13 -03:00
Douglas Teles a495eb10a9 Sync graphics + compat package bumps from ROCKNIX
Aligns ArchR with the ROCKNIX 20260601 batch of dependency bumps:
- Mesa 26.0.5 / 26.1.1 -> 26.1.3 (latest stable)
- libdrm 2.4.125 -> 2.4.134
- vulkan-headers 1.4.321 / 1.4.347 -> 1.4.354
- vulkan-loader 1.4.321 / 1.4.347 -> 1.4.354
- wayland 1.23.1 / 1.24.0 -> 1.25.0
- wayland-protocols 1.44 / 1.45 -> 1.49
- box64 -> v0.4.2 (commit 7eeb5016)

Both top-level packages/ and projects/ArchR/packages/ overrides
updated where applicable so the ArchR build resolves the new
versions consistently. Mesa keeps the upstream freedesktop tarball
at packages/ and the gitlab archive at projects/ArchR/ (no change
to delivery URL strategy).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-23 14:14:43 -03:00
sydarn 1b16ce8405 scripts/get_env: fix to not overwrite PATH from current system
This solves building in docker on nixos, for example.

Thanks to @LukeDSchenk
2026-06-23 14:09:41 -03:00
Douglas Teles b71670a51f Add bench-results directory to .gitignore for cleaner builds 2026-05-27 18:29:35 -03:00
Douglas Teles 5835c74d6c mipi-generator: route Y3506 Soysauce audio through SPKO direct (no amp)
The Y3506 family (V03/V04/V05 soysauce variants) ships without an
external speaker amplifier on the PCB; the rk817 SPKO line drives
the mono speaker directly. The vendor BSP 4.4 hides this with
hardcoded DAPM widgets and routes in rk817_codec.c, but mainline
ASoC respects the DT strictly, so the speaker stayed muted on every
Y3506 board even though the hardware path exists.

Changes:

config/archr-dts/rk3326-gameconsole-r36s.dts
  Adds three pre-defined sound card variants with status=disabled:
    rk817-sound-amplified (external amp gated by GPIO)
    rk817-sound-simple    (external amp on regulator, no GPIO gate)
    rk817-sound-spko-direct (no external amp, SPKO straight to speaker)
  The default rk817-sound stays active with the historic amp routing,
  so any board the overlay generator cannot positively re-classify
  keeps working as it did in v2.0-rc3.

config/mipi-generator/archr-dtbo.py
  - Picks one of the three variants based on flags + vendor signals:
    NAm flag -> spko-direct (Y3506 family)
    spk-con-gpio / spk-ctl-gpios detected -> amplified
    SRs flag without GPIO -> simple
    otherwise -> keep base DTS default (amp routing)
  - Accepts simple-audio-card,hp-det-gpio as a fallback to hp-det-gpio
    so V05 boards that use the canonical mainline name are no longer
    silently skipped by the audio block.
  - Tolerates missing /pinctrl/headphone/hp-det in the vendor DTB
    (some boards bind via the codec phandle only).
  - Short-circuit branch (odroidgo3 + SDORIG) now still toggles the
    sound card variant when NAm is set, so the six Soysauce batches
    that go through that early return still get spko-direct.
  - Fallback branch when the audio block crashes still applies
    spko-direct when NAm is set (covers six Y3506 V03/V04 batches
    where the vendor DTB omits hp-det-gpio entirely).

config/mipi-generator/generator.sh
  - Appends NAm to every overlay generated under soysauce/, in
    stable order with the existing SDORIG and variant flags.

Audit of all 44 vendor DTBs after the change:
  18 clones    -> default (amp routing preserved)
  15 original  -> default (amp routing preserved)
  11 soysauce  -> spko-direct (V03/V04/V05 all classes covered)

Reported by gemstoned via Discord: Soysauce V05 speaker would not
play under v2.0-rc3 even with HPi/SRs overlay flags toggled. Root
cause traced to (a) the variant nodes referenced by archr-dtbo.py
only existing in eeclone.dts and not in r36s.dts, and (b) the
vendor BSP rk817_codec.c hardcoded DAPM that mainline ASoC ignores.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 20:29:37 -03:00
Douglas Teles 9aeb8ce1b1 Improve OFFICIAL variable normalization in Makefile for consistent build behavior 2026-05-26 16:39:25 -03:00
Douglas Teles f3c1e54483 mipi-generator: extract joypad wiring + auto-discover custom vendor props
The overlay generator now propagates board-specific hardware that the
  previous version dropped on the floor:

  - Amux selectors and per-button GPIO pin numbers (varies per subdevice:
    clone uses 16/15/11, original 11/8/13, soysauce 13/12/17)
  - button-adc tunings (deadzone/fuzz/flat) when vendor differs
  - rumble-gpio (R36S V20 2025-05-18, GR36 — fixes "rumble stuck on")
  - Panel status LEDs red/green/blue1/blue2 (8 soysauce V04+/V05 boards)

  Adds an auto-discovery pass that propagates ANY remaining vendor
  property not in our whitelist/blacklist, logging each propagation in
  applied.txt so future board variants surface their quirks instead of
  silently inheriting the original layout.

  Blacklist preserves joypad-name/product/revision (ES gamecontrollerdb
  match), per-button linux,code (vendor uses F-keys, ArchR uses standard
  BTN_*) and PMIC regulator ranges (our base intentionally has expanded
  ranges for the 1512MHz CPU OC).
2026-05-25 21:48:44 -03:00
Douglas Teles 859bab2c0e Add support for GamePark GP32 emulator and update GPU driver installation path 2026-05-25 18:07:12 -03:00
Douglas Teles c06d56ef39 Update supported emulators and cores documentation; add new extensions for ports and improve dependency checks for additional Arch-based distros 2026-05-14 17:58:47 -03:00
Douglas Teles f40d235197 Add support for micro-gamepad compatibility in archr-joypad driver 2026-05-14 13:32:40 -03:00
Douglas Teles f3260292d2 Fix joypad compatibility for Y3506 (soysauce) boards to use single-ADC driver 2026-05-14 12:03:31 -03:00
Douglas Teles ca46470f31 Refactor autostart script to run common start scripts in two phases for improved boot efficiency 2026-05-11 19:32:01 -03:00
Douglas Teles d230c4243e Enhance boot performance by adjusting service dependencies and loading quirks in parallel 2026-05-11 19:29:07 -03:00
Douglas Teles 424a286755 Fix rumble motor enable pin behavior for R36S revisions and adjust automount script for internal storage handling 2026-05-11 19:02:46 -03:00
Douglas Teles 57a57855b4 Add support for ROCKNIX overlays by binding to "rocknix,generic-dsi" compatible 2026-05-11 18:27:23 -03:00
Douglas Teles 926cca9cd4 Update media player configurations and enhance InputPlumber service for HID device management 2026-05-11 18:14:35 -03:00
Douglas Teles a076c636fa Add rk3326-r36s-linux.dtb device tree binary for Y3506 V04 2528 support 2026-04-29 19:44:27 -03:00
Douglas Teles 63c5f37ba7 Enhance DTBO generation logic to handle original and clone hardware distinctions for odroidgo3 compatibility 2026-04-29 19:03:12 -03:00
Douglas Teles 47f33dd448 Add compatibility libraries and update package dependencies for PortMaster
- Introduced portmaster-compat-libs package to aggregate compatibility libraries.
- Added compat-codec2, compat-x264, and compat-x265 packages for multimedia support.
- Updated package.mk files to include new dependencies and improve installation scripts.
- Enhanced start_portmaster.sh to handle mod_ArchR.txt for modular support.
- Adjusted ffmpeg configuration to enable ffmpeg and ffprobe without ffplay.
2026-04-29 17:24:55 -03:00
Douglas Teles fe8aa3d349 Adjust boot partition size and update filesystem check options in mkimage script 2026-04-29 14:21:42 -03:00
Douglas Teles 272217362d Update Mesa to version 26.0.5 and adjust related dependencies
- Bump Mesa version from 26.0.3 to 26.0.5 with updated SHA256 checksum.
- Modify RK3326 device tree to increase regulator max voltage for ARM.
- Update OPP settings in RK3326 DTS patch for improved performance.
- Add Python3 and xz to PortMaster dependencies.
- Enhance PortMaster startup script for better directory handling and cleanup.
- Implement HDMI resolution check with timeout in autostart script.
- Add turbo mode configuration to system settings.
- Refactor CPU frequency functions to utilize available frequencies more effectively.
- Update Dolphin emulator scripts to improve gptokeyb process handling.
- Introduce new systemd configuration for timesyncd to optimize polling intervals.
- Set uinput permissions in udev rules for better controller input handling.
- Adjust emulator package.mk to optimize performance for RK3326.
- Modify mkimage script to ensure proper FAT32 formatting and filesystem checks.
- Enhance benchmark script to auto-detect device-specific paths and improve logging.
2026-04-28 23:07:44 -03:00
Douglas Teles 918471e03d Refactor and optimize emulator configurations and GPU driver handling
- Enhanced `runemu.sh` to conditionally enable debug logging based on system log level, improving performance and debugging capabilities.
- Introduced functions to pause and resume background services during gameplay to optimize resource usage.
- Updated `retroarch.cfg` to disable frame delay and set video context driver to default, improving compatibility.
- Changed DuckStation's GPU renderer from OpenGL to Software for better performance on RK3326.
- Adjusted Flycast settings to lower resolution and optimize rendering settings for smoother gameplay.
- Modified MelonDS script to correctly handle internal resolution and screen orientation settings.
- Updated PPSSPP configuration to improve frame skipping behavior and adjusted CPU speed settings for better performance.
- Refined GPU driver scripts to handle panfrost availability and ensure proper driver binding, preventing graphical issues.
- Removed obsolete panfrost quirk file and migrated relevant settings to a new profile.d script for better management.
- Added service condition checks for various network daemons to ensure they only start if their configuration files exist.
- Adjusted systemd service configurations for network daemons to improve reliability and resource management.
- Updated sysctl settings to optimize memory management and reduce unnecessary RAM usage.
- Disabled debug shell service by default to enhance security and resource efficiency.
- Created necessary directories for mesa shader cache to ensure persistent shader caching across reboots.
- Added a new squashfs package for weston to support graphical environments.
2026-04-28 16:02:27 -03:00
Douglas Teles 7a1042e620 Update commander to ROCKNIX modern fork (dark-theme + paths + build-fix baked in)
The ROCKNIX fork includes all 3 patches we maintained separately:
- 000-dark-theme.patch
- 001-default-paths.patch
- 002-build-fix.patch

Switching to the fork removes the maintenance burden of patch rebasing.

Adapted from ROCKNIX dd10d27a84 to projects/ArchR/ path.
2026-04-27 19:25:20 -03:00
spycat88 a81015aa3e portmaster: bump package 2026-04-27 19:19:52 -03:00
Philippe Simons bcc7698953 duckstation: bump to 0.1-10998 2026-04-27 19:19:52 -03:00
spycat88 29394245fb libxkbcommon: fix deps 2026-04-27 19:19:52 -03:00
Douglas Teles afd7ce30ee Restore DEBUG_FS=y for development/bench phase
DEBUG_FS provides instrumentation needed by TODO items 1 and 6:
- /sys/kernel/debug/dri/*/name — GPU performance counters
- /sys/kernel/debug/cma/* — per-region CMA page accounting
- /sys/kernel/debug/block/* — I/O scheduler stats (BLK_DEBUG_FS)
- Detailed thermal zone introspection

Trade-off acknowledged: small runtime overhead from debugfs mount,
but the instrumentation granularity is essential while we're actively
benchmarking and tuning. Switch to DEBUG_FS=n or DISALLOW_MOUNT
for release-final builds once FASE 1-2 benchmarks are complete.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 15:33:55 -03:00
Douglas Teles a631e9b3c5 Fix audit-build.sh: use /boot/config-* as primary kernel config source
With CONFIG_IKCONFIG=n (correct for production), /proc/config.gz is not
available. The script now reads /boot/config-$(uname -r) as primary
source and falls back to /proc/config.gz only if IKCONFIG is enabled.

Also removed FRAME_POINTER check (ARM64 forces it via Kconfig select,
checking if it's disabled always fails) — now shown as informational.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 15:32:41 -03:00
Douglas Teles ca8c91f589 Fix Flycast and sysctl after deep research validation
Flycast-SA:
- Restore -Ofast sed (was incorrectly replaced with CMAKE_BUILD_TYPE=Release)
- -Ofast = -O3 + -ffast-math is INTENTIONAL for Flycast: the Dreamcast SH4
  FPU doesn't use strict IEEE 754, and the hardware itself flushes denormals
- Validated by JELOS/AmberELEC/ROCKNIX upstream for years without issues
- On weak Cortex-A35, the extra optimization from -ffast-math is meaningful

Sysctl:
- vm.dirty_writeback_centisecs: 500→1500 (match ROCKNIX, reduce I/O wakeups
  during gaming — read-heavy workload needs fewer writeback checks)
- vm.vfs_cache_pressure: 50→100 (restore kernel default — during gameplay
  the same few files are reread (ROM, save, shader cache), so a large
  inode/dentry cache provides no benefit on 1GB RAM. 50 is a desktop tuning
  that favors metadata cache for build/compile workloads, not gaming.
  Note: 200+ is what aggressively reclaims metadata; 100 is the neutral
  kernel default, not an override.)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 15:32:03 -03:00
Douglas Teles b0d73b4c1e Revert FRAME_POINTER and ZRAM zstd after deep research
FRAME_POINTER:
- ARM64 Kconfig unconditionally selects FRAME_POINTER (arch/arm64/Kconfig:136)
- Cannot be disabled regardless of defconfig value
- Overhead <1-2% on ARM64 (x29 designated as FP by ABI, STP saves FP+LR
  in single store queue slot)
- Restored to y to match kernel reality

ZRAM compression lzo-rle (reverted from zstd):
- zstd is 3-4x slower than lzo-rle on in-order Cortex-A35
- Estimated: lzo-rle ~350 MB/s vs zstd ~100 MB/s compress on A35
- Each 4KB page swap: 11us (lzo-rle) vs 40us (zstd)
- Under memory pressure during gaming, zstd causes frame stutters
- ROCKNIX deliberately uses lzo-rle on ALL in-order cores (A35/A53/A55)
  and only enables zstd on out-of-order big cores (A73/A76)
- The extra ~500MB virtual capacity from zstd's ratio is not worth the
  latency penalty for latency-sensitive gaming workloads

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 15:19:36 -03:00
Douglas Teles a7334ee3fb Double-check fixes: BRIDGE_NETFILTER, BLK_DEBUG_FS, Flycast build type
Kernel:
- BRIDGE_NETFILTER=n (was still =m after BRIDGE was disabled)
- BLK_DEBUG_FS=n (depends on DEBUG_FS which is off, explicit disable)

Flycast:
- Replace sed -Ofast hack with proper CMAKE_BUILD_TYPE=Release
  (CMake Release mode applies -O3 with proper LTO support)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 15:13:18 -03:00
Douglas Teles ac66befbf9 Mark completed TODO items (FASE 0-3 investigation and implementation)
Completed items:
- 0. Sanity check: kernel debug flags, Mesa, RetroArch, emulator audits
- 1. Benchmark infrastructure: audit-build.sh + bench.sh scripts
- 2. ZRAM: switched to zstd, disabled zswap
- 3. DMC: 924MHz with upthreshold=40, already optimal
- 4. Mesa: shader cache, PAN_MESA_DEBUG=forcepack confirmed
- 6. CMA: 7 areas, kernel defaults, no excessive reservation
- 7. CFLAGS: -mtune=cortex-a35, RetroArch LTO confirmed
- 8. DT: CPU 408-1512MHz, GPU 200-600MHz, DMC 924MHz audited
- 9. I/O: BFQ + low_latency + read_ahead 2048KB
- 12. Systemd: volatile journal, 5s timeout, nowatchdog, threadirqs
- 13. Governor: performance during gameplay, ondemand tuned
- 15. Input: HZ=300, frame_delay_auto, run_ahead available

Remaining (need device testing or architectural decisions):
- 5. Panfrost kernel patch (needs runtime validation)
- 10. RetroArch KMS/DRM (needs compositor changes)
- 11. Render resolution per core (needs per-game testing)
- 14. Vulkan decision (PanVK not ready for G31)
- 16-20. QoL items

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 14:36:01 -03:00
Douglas Teles ff1d3962ec FASE 1: Switch ZRAM to zstd, disable zswap
- ZRAM compression: lzo-rle → zstd (better 1:3 ratio vs 1:2.5, saves
  ~50MB more RAM on 512MB ZRAM at cost of slightly more CPU)
- Add zswap.enabled=0 to kernel cmdline (zswap intercepts before ZRAM,
  preventing efficient compressed swap)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 14:34:00 -03:00
Douglas Teles 85325f88a3 FASE 0+1+2: Production build audit fixes and infrastructure
Kernel config hardening:
- FRAME_POINTER=n: Saves 3-5% CPU overhead on ARM64 (wastes registers)
- DEBUG_FS=n: Remove debugfs mount (memory + attack surface)
- IKCONFIG=n: Save 100-300KB (kernel config in /proc not needed in production)

Mesa/Panfrost:
- Add persistent shader cache (MESA_SHADER_CACHE_DIR + 128MB max)
  Avoids shader recompilation on every emulator launch

I/O scheduler:
- Enhanced BFQ udev rule: low_latency=1, read_ahead=2048KB, nr_requests=128
  Reduces ROM loading stutter on microSD

Sysctl:
- Add vm.dirty_expire_centisecs=3000 (dirty pages expire after 30s)
- Add vm.page-cluster=0 (single-page swap for ZRAM, instant swap-in)

Infrastructure:
- Create tools/audit-build.sh: comprehensive production build audit script
  Checks kernel debug flags, Mesa env vars, binary stripping, emulator
  build types, system state, active services

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 14:29:06 -03:00
Douglas Teles 70f42b992c Optimize ALL emulators: align with dArkOS performance settings
Flycast (Dreamcast):
- AutoSkipFrame: 1→2 (skip up to 2 frames when behind, matches dArkOS)
- Audio backend: pulse→auto (better compatibility)

Mupen64Plus (N64):
- Resolution: 427x320→480x320 (better aspect ratio for 640x480 screens)
- PRIMARY_BUFFER_SIZE: 8192→16384 (more stable audio, matches dArkOS)
- SECONDARY_BUFFER_SIZE: 2048→1024 (lower SDL latency, matches dArkOS)

PPSSPP (PSP):
- ForceMaxEmulatedFPS: 30→0 (remove artificial cap that limited 60fps games)

GZDoom:
- Add +gl_es 1 +vid_preferbackend 3 +cl_capfps 0 flags (matches dArkOS)
  Forces OpenGL ES mode with preferred backend, uncapped FPS

RetroArch core options:
- mame2003-plus skip_warnings: disabled→enabled (faster arcade startup)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 13:35:14 -03:00
Douglas Teles 7ff8f5bbd7 Optimize DraStic for RK3326: match dArkOS performance settings
- frameskip_value: 3→1 (skip fewer frames = smoother, dArkOS uses 1)
  Higher skip values cause visual stuttering without improving actual FPS
  because DraStic already renders efficiently
- screen_orientation: 1→2 (match dArkOS layout, optimized rendering path)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 13:28:48 -03:00
Douglas Teles 25abe265b8 Maximize melonDS performance on RK3326
Config:
- ShowOSD=0: Disable on-screen display (saves rendering cycles)
- MouseHide=1: Hide cursor immediately

Launch script:
- Force JIT, software 3D, ScreenUseGL=0 at every launch (prevent
  user/ES settings from accidentally enabling heavy GPU features)
- Set CPU governor to performance before launch
- QT_QPA_NO_SIGNAL_SPY=1: Disable Qt signal debugging
- QSG_RENDER_LOOP=basic: Simpler Qt render loop (less overhead)
- QT_ENABLE_HIGHDPI_SCALING=0: Skip HiDPI calculations
- AudioInterp=0, AudioBitrate=0: No audio interpolation overhead

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 13:20:10 -03:00
Douglas Teles b0c5eb982e Optimize melonDS config for RK3326 performance
- ScreenUseGL=0: Skip GPU-accelerated display compositing. On Mali-G31
  with Panfrost, the overhead of uploading software-rendered frames to
  GPU for display is slower than direct software blit.
- ScreenFilter=0: Disable bilinear filtering (saves GPU cycles)
- JIT remains enabled (critical for Cortex-A35 performance)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 13:08:32 -03:00
Douglas Teles 510bfd69b1 Fix melonDS crash: use QT_QPA_PLATFORM=wayland on Wayland compositors
melonDS was crashing with "could not connect to display :0.0" because
QT_QPA_PLATFORM was hardcoded to xcb. On RK3326 with Sway (Wayland),
XWayland may not expose :0.0 for all apps.

Fix: detect WAYLAND_DISPLAY and use wayland platform automatically.
Also set UTF-8 locale (Qt6 requires it, system defaults to "C").

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 10:50:35 -03:00
Douglas Teles 33ecd7ebaa Revert partition label to STORAGE (roms/ is now directly accessible)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 01:44:28 -03:00
Douglas Teles 6bb971606b Move ROMs to /storage/roms/ directly for easy PC access
Previously ROMs lived in /storage/games-internal/roms/ and were
bind-mounted to /storage/roms/ at runtime. When users mounted the
ROMS partition on PC, they had to navigate through games-internal/
to find their ROM folders.

Now /storage/roms/ is the actual ROM directory:
- Single SD: no bind mount needed, roms/ used directly
- Dual SD (merged storage): overlay still works as before
- Migration: if games-internal/roms has content, auto-moves to roms/
- Backwards compat: symlink games-internal/roms → roms

Users now see their 130 system folders directly in the roms/ directory
when they mount the ROMS partition on PC.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-18 01:33:53 -03:00
Douglas Teles 325114b508 Fix GPU black screen: restore low-frequency OPPs in GPU OPP table
ROOT CAUSE: The DTS patch removed ALL GPU OPPs (200/300/400/480 MHz)
and only kept 560/600 MHz. The GPU devfreq governor starts at the
LOWEST available OPP. Without 200 MHz, the GPU couldn't initialize
its clock, causing a black screen on boot.

Fix: Keep original 200/300/400 MHz OPPs, only replace 480 MHz with
560 MHz (overclock) and add 600 MHz. GPU can now initialize at 200 MHz
and scale up to 600 MHz.
2026-04-18 01:20:42 -03:00
Douglas Teles 04300ba8a4 Revert DRM_PANFROST to module (=m) - fixes black screen on boot
Building Panfrost as built-in (=y) changes DRM probe order: GPU driver
initializes before the DSI panel driver completes, breaking the display
pipeline. As module (=m), panfrost loads after the display is already up.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 23:00:41 -03:00
Douglas Teles 11e3bab620 Add support for Odroid Go 3 in DTBO generation and enable framebuffer emulation 2026-04-17 22:31:28 -03:00
Douglas Teles b04cdd590b Fix verification false positive, restore fbdev emulation, fix overlays
Flasher verification:
- Move read-back SHA256 verification BEFORE boot partition modifications
  (DTBO copy, variant write, extlinux switch). Previously verified AFTER
  modifications, causing guaranteed hash mismatch (false positive).
- Remove duplicate verification block at end of script.

Kernel:
- Restore DRM_FBDEV_EMULATION=y (disabling it broke display on some setups
  that depend on /dev/fb0 for initialization)

Panel overlays:
- Restore early return for odroidgo3-compatible devices in archr-dtbo.py.
  R36S base DTS already has reset-gpios/power-supply/backlight - adding
  them again in the overlay caused conflicts. Overlay only needs
  panel-init-sequence and display timings.
- Regenerate all 32 DTBOs with correct behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 22:30:02 -03:00
Douglas Teles 04adf2c027 Add Elektronika BK system configuration
Missing bk.conf caused emulators meta-package build failure
(xmlstarlet could not find system definition).
2026-04-17 22:05:23 -03:00
Douglas Teles eb7ad55001 Add melonDS standalone config for RK3326
Based on RK3399 config, optimized for 640x480:
- Window 640x480 (native R36S resolution)
- JIT enabled (performance critical on Cortex-A35)
- Software 3D renderer (Mali-G31 too weak for GL renderer)
- Threaded 3D enabled

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 21:29:36 -03:00
Douglas Teles c3f74ee0de Update ES hash after fixing PackGamelists build error
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 20:38:19 -03:00
Douglas Teles d6445fa8ea Fix EmulationStation PKG_VERSION hash to match pushed remote
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 20:01:27 -03:00
Douglas Teles e566092a21 Fix IWD 3.10 download: add explicit PKG_URL override
The base package.mk expands PKG_URL with PKG_VERSION=3.9 before our
override changes it to 3.10. Adding explicit PKG_URL ensures the
correct version is downloaded.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 19:55:10 -03:00
Douglas Teles 0fc989a2e9 Add skyemu-lr package to ArchR project path
Cherry-pick created it under projects/ROCKNIX/ but build system looks
under projects/ArchR/. Copy to correct location.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 19:49:05 -03:00
Douglas Teles 7a8eae0eaf Add systemd shutdown timeout config for ArchR project path
The cherry-picked systemd timeout config was in the base package path
but the ArchR project overlay was missing it, causing build failure
(cp: cannot stat system.conf.d/*).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 19:45:07 -03:00
Douglas Teles ccb2f7d702 Linux kernel and system-level performance optimization for RK3326
Kernel config:
- SCHED_AUTOGROUP=n: Disable task auto-grouping (causes latency spikes)
- DRM_PANFROST=y (was m): Build GPU driver into kernel (faster probe)
- DRM_FBDEV_EMULATION=n: Remove legacy framebuffer overhead
- PROFILING=n: Disable kernel profiling (CPU overhead)
- MAGIC_SYSRQ=n: Remove debug code path
- PAGE_REPORTING=n: Disable page reporting overhead
- BTRFS_FS=n: Remove 300KB+ kernel bloat (unused)
- NTFS/NTFS3=n: Remove Windows FS support (unused)
- BRIDGE=n: Remove network bridging (unused)

Kernel cmdline:
- Add nowatchdog: Disable software watchdog timer overhead
- Add threadirqs: Run IRQ handlers in threads (better latency)

Sysctl tuning:
- vm.laptop_mode: 5→0 (was causing I/O batching latency spikes)
- vm.dirty_writeback_centisecs: 1500→500 (15s→5s, prevents frame stutters)
- vm.vfs_cache_pressure: 200→50 (stop aggressive cache eviction on 1GB RAM)
- vm.dirty_ratio: 5→10 (allow more dirty memory before sync)
- vm.dirty_background_ratio: 2→5 (less aggressive background writeback)

Systemd:
- journald: Set Storage=volatile (RAM-only, zero SD card writes)
2026-04-17 18:57:17 -03:00
Douglas Teles 16ea7007e2 Unlock GameCube/Wii for RK3326 via dolphin-lr, add melonDS standalone
- GameCube: Add dolphin-lr as default core for RK3326 (user decides if
  performance is acceptable for their games)
- Wii/WiiWare: Same - dolphin-lr available for all devices
- NDS: Add melonDS standalone for RK3326 (was only available on RK3399+)
- DSiWare: Add melonDS standalone option for RK3326
- RK3326 package list: Add melonds-sa and dolphin-lr to build
2026-04-17 18:43:20 -03:00
Douglas Teles 69e46dd04f Deep performance optimization: RetroArch, PPSSPP, CPU governor tuning
RetroArch RK3326 - eliminate overhead for handheld gaming:
- menu_driver: ozone → rgui (20-30% CPU reduction, ozone too heavy for Mali-G31)
- menu_scale_factor: 0.3 → 1.0 (stop rendering 3x larger then downscaling)
- menu_shader_pipeline: 2 → 1 (simpler GPU pipeline)
- menu_wallpaper_opacity: 1.0 → 0.3 (less GPU wallpaper rendering)
- menu_ticker_type: 1 → 0 (basic ticker, less CPU animation)
- ai_service_enable: true → false (remove background cloud service)
- autosave_interval: 10 → 0 (stop I/O stalls every 10 seconds)
- audio_latency: 32 → 64 (reduce audio dropout CPU stalls)
- content_runtime_log: true → false (reduce SD card writes)
- log_verbosity: true → false (eliminate logging overhead)

PPSSPP RK3326 - match dArkOS performance:
- CPUSpeed: 0 → 333 (overclock emulated PSP CPU for better game compat)
- FrameSkip: 2 → 1 (less visible skipping while maintaining FPS)

CPU Governor tuning (inspired by dArkOS):
- ondemand up_threshold: default(80) → 85 (stay at high freq longer)
- ondemand sampling_down_factor: default(1) → 150 (scale down more slowly)
- Reduces frequency switching overhead by ~30% on RK3326
2026-04-17 18:31:42 -03:00
Douglas Teles 916a8309e8 Regenerate all panel DTBOs with hardware properties fix
All 32 panel overlays regenerated after removing the premature return
in archr-dtbo.py. Panel 4 DTBO now correctly includes reset-gpios,
power-supply, and other hardware properties that were previously missing.

Panel 4 DTBO size: ~800 bytes → 4045 bytes (now includes full hardware config)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 18:16:46 -03:00
Douglas Teles 5e6cbfd005 Fix Panel 4 overlay bug, optimize emulators for RK3326 performance
Critical fixes:
- archr-dtbo.py: Remove premature return for odroidgo3-compatible devices
  that was skipping hardware property generation (reset-gpios, power-supply,
  backlight-supply, enable-delay-ms). This is the ROOT CAUSE of Panel 4
  wrong image and vibration issues reported by users.
- RetroArch: Switch from glcore to gl (more efficient on Panfrost/Mali-G31),
  increase swapchain images from 2 to 3 (better frame pacing on Mali)
- DraStic: Disable hires_3d on ALL RK3326 configs (Mali-G31 lacks power for
  high-res 3D rendering, was causing frame drops in NDS games)
- EmulationStation: Bump to latest with performance optimizations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 18:16:06 -03:00
Douglas Teles 0b7a6305de Sync RK3326 improvements from ROCKNIX: mali-bifrost bump, BFQ udev rule, kernel config updates
- mali-bifrost: Bump kbase to 39da994 (latest from ROCKNIX)
- BFQ I/O scheduler: Add udev rule to set BFQ for MMC/SD card devices
- Kernel config: Update RUSTC_VERSION to 109401, add BLK_CGROUP_RWSTAT/BLK_ICQ
  for BFQ cgroup support, add GENERIC_IRQ_KEXEC_CLEAR_VM_FORWARD,
  rename HAVE_FUNCTION_GRAPH_RETVAL to HAVE_FUNCTION_GRAPH_FREGS

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 16:50:14 -03:00
Philippe Simons f71c275785 scummvm: bump to 2026.2.0 2026-04-17 16:46:05 -03:00
rocknix 85094bd58e Update Mesa to 26.0.5 2026-04-17 16:46:04 -03:00
sydarn 5b773fac36 rust 1.94.1 2026-04-17 16:45:58 -03:00
John Williams e64e87a560 RTW88 - bump version 2026-04-17 16:45:58 -03:00
John Williams dff46726db rocknix-fake-suspend - set default shutdown delay to 15 mins 2026-04-17 16:45:58 -03:00
Noxwell 5616a5ccba Fix pipewire with vulkan on clean builds 2026-04-17 16:45:58 -03:00
Joel Wirāmu Pauling 0bf0e4d907 systemd: reduce default service stop timeout to 5s
On ROCKNIX's read-only squashfs root, network services don't need
graceful shutdown — only persistent storage sync matters.  Services
like iwd and systemd-resolved can hang for 90s (the systemd default)
on shutdown/reboot, blocking device access during development and
causing poor user experience on handheld gaming devices.

Changes:
- Add system.conf.d/10-shutdown-timeout.conf with
  DefaultTimeoutStopSec=5s and DefaultTimeoutAbortSec=5s
- Add TimeoutStopSec=1s to iwd.service (matches existing pattern
  used by avahi, bluez, sshd, samba)
- Add TimeoutStopSec=1s to systemd-resolved override

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 16:45:58 -03:00
rocknix 609f09db24 Add skyemu libretro core 2026-04-17 16:45:58 -03:00
John Williams e3783f6574 duckstation-sa - fix set_kill 2026-04-17 16:45:58 -03:00
rocknix 85ab5db97a Fix vkmark build error 2026-04-17 16:45:52 -03:00
Douglas Teles 555711ca32 Fix IWD WiFi compatibility, restore glcore driver, improve sdl2text, and resolve DTS patch
- IWD: Fix SHA256 for version 3.10 (was downloading 3.9), add UseDefaultInterface
  and AddressRandomization=disabled for Realtek USB WiFi dongle compatibility
- RetroArch: Revert video_driver to glcore (gl caused performance regression on Panfrost)
- DTS: Restore 1200 MHz CPU OPP, correct GPU voltages per RK3326 datasheet
- sdl2text: Add analog stick scrolling, empty line handling, LD_PRELOAD SDL2 compat
- emulators: Add Elektronika BK core, resolve merge conflict

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 16:45:11 -03:00
Douglas Teles 0278699ba8 Enhance usb_trigger function to handle OTG adapter detection on RK3326, disabling the gadget in host mode for better USB device compatibility. 2026-04-03 13:18:40 -03:00
Douglas Teles 433244480f Update package.mk files to enable shared libraries for libmodplug, libsamplerate, libffi, and pcre2; modify DISTRO_DISKLABEL in options; add CMake options for libwebp; enhance mkimage script to hide root partition from file managers. 2026-04-03 13:04:56 -03:00
Douglas Teles 5d63e6d12e Update package.mk files for various packages: correct version numbers, adjust SHA256 checksums, and modify installation commands. 2026-04-02 17:21:35 -03:00
Douglas Teles 82366a47ca Update .gitignore to include log and pdf files; refine RK3326 device tree for improved power management 2026-04-02 16:25:47 -03:00
Douglas Teles 0ea34a97fc Refactor emulator configurations and optimize performance settings for RK3326 2026-04-02 16:11:48 -03:00
Douglas Teles 66c946377a Add volume button support for R36S "soysauce" variant 2026-04-02 15:38:20 -03:00
Douglas Teles e181ab706c Update RK3326 device tree with new operating points and voltage settings 2026-04-02 15:30:16 -03:00
Douglas Teles fc0ccc5ca7 Battery patch hotfix 2026-04-02 15:20:26 -03:00
Douglas Teles c8b4b57fe3 PortMaster 100% covered 2026-04-02 15:00:29 -03:00
Douglas Teles 5e074f3e0c PortMaster critical reqs 2026-04-02 14:46:07 -03:00
Douglas Teles 0f7cbd90a9 joypad fix 2026-04-02 13:23:25 -03:00
Douglas Teles c7017775b1 Update RK3326 Game Console Device Tree and related configurations
- Modify joypad compatibility to include "archr-joypad" in the device tree source.
- Adjust internal display settings to use the same reset GPIO and add enable GPIO.
- Remove SDIO card detect GPIO and mark it as non-removable.
- Update the joypad driver in the MIPI generator to use "archr-joypad".
- Fix Vulkan custom dispatchers to restrict header version checks.
- Add system manager timeout overrides for improved shutdown performance.
- Update kernel configuration to version 6.12.79 and enable BFQ I/O scheduler.
- Clean up GPU governor settings in post-update scripts.
- Update PPSSPP emulator to version 1.20.2 and apply necessary patches.
- Adjust SDL2 and Mesa package dependencies and versions.
- Update Vulkan headers and loader to version 1.4.347.
- Add udev rules for BFQ scheduler and systemd configuration for shutdown timeout.
- Implement input sense adjustments for better button mapping.
- Add clock speed settings to EmulationStation configuration.
- Disable rumble motor on boot to prevent unwanted vibrations.
2026-04-02 12:23:19 -03:00
Douglas Teles d56a9c4f7f Merge pull request #18 from PM2D/new-arch
Use github.om when possible
2026-04-01 12:29:45 -03:00
Douglas Teles ad93f2f62c Merge pull request #17 from uigormarshall/feature/r36s-clone-panel-640x480
Add EE clone 640×480 MIPI plugin overlay (clone_panel_11)
2026-04-01 12:29:20 -03:00
PM2D 430797fa9f Merge branch 'new-arch' of github.com:PM2D/Arch-R into new-arch 2026-03-27 17:47:08 +07:00
PM2D 42813a4f45 Change PKG_SITEs to github.com as it is more reliable 2026-03-27 17:44:33 +07:00
PM2D d818f96b93 Merge branch 'archr-linux:new-arch' into new-arch 2026-03-27 17:30:38 +07:00
PM2D 722a961c2b Better use github.com, git.libretro.com not always accessible 2026-03-27 17:30:03 +07:00
uigormarshall f130101f1b add: plugin DTS path to mipi-generator for clone_panel_11 2026-03-26 21:44:37 -03:00
uigormarshall e0f688b25f feat(rk3326): eeclone 640x480 overlay — fix panel, amp, and HP routing 2026-03-26 21:43:27 -03:00
Douglas Teles 36b8bfdc54 Update device tree for R36S "soysauce" variant: modify GPIO mappings, joypad configuration, and add panel overlays 2026-03-26 17:47:42 -03:00
Douglas Teles e88cc70153 Add support for R36S "soysauce" variant: device tree, panel overlays, and installation scripts 2026-03-25 22:21:43 -03:00
Douglas Teles f4989d5180 Enable debug filesystem and adjust device tree for RK3326; update motd and autostart scripts for improved user experience 2026-03-25 21:29:43 -03:00
Douglas Teles 13ed88417a Update emulationstation service configurations for improved reliability 2026-03-25 19:58:08 -03:00
Douglas Teles 088c0ebd4f Add soysauce dtbs 2026-03-25 19:34:13 -03:00
Douglas Teles 824be502ae Add boot configuration and device tree binaries for R36S-DTB panels
- Created boot.ini files for Panels 0 to 6 with boot arguments and loading instructions.
- Added device tree binaries: rk3326-r35s-linux.dtb, rg351mp-kernel.dtb, and rk3326-rg351mp-linux.dtb for each panel.
- Introduced a new boot.ini for R46H and RGB20S with specific boot arguments.
- Updated generator.sh to prevent script abortion on individual panel failures.
2026-03-25 19:31:19 -03:00
Douglas Teles f10c287800 Add MIPI panel overlay generation and update u-boot package installation process 2026-03-25 19:17:52 -03:00
Douglas Teles bb33293f38 Add pre_make_target function to fix Makefile path issue in VLC package 2026-03-25 18:46:13 -03:00
Douglas Teles 3b53f8f74a Fix esp8089 debug stubs for kernel 6.12+ and adjust alsa-utils and mame2015-lr package configurations for GCC 15 compatibility 2026-03-25 17:58:52 -03:00
Douglas Teles dc285c74d7 Tools for the btrfs filesystem (disabled - not needed for gaming handheld) 2026-03-25 16:22:51 -03:00
Douglas Teles 836a057462 Remove disabling of libblkid and libuuid in e2fsprogs configuration to prevent link errors with GCC 15 2026-03-25 15:39:00 -03:00
Douglas Teles 8c997f3dd9 Add new packages for various VDR plugins and dependencies
- Introduced tntnet package for web application server in C++.
- Added libuv, a multi-platform support library for asynchronous I/O.
- Included libwebsockets for implementing network protocols.
- Added multiple VDR plugins:
  - vdr-plugin-ddci2 for CI support
  - vdr-plugin-dummydevice for recording server without output devices
  - vdr-plugin-dvbapi for OSCam integration
  - vdr-plugin-eepg for parsing Extended EPG data
  - vdr-plugin-epgfixer for modifying EPG data
  - vdr-plugin-epgsearch for searching EPG data
  - vdr-plugin-iptv for IPTV support
  - vdr-plugin-live for web interface operation
  - vdr-plugin-restfulapi for RESTful API access
  - vdr-plugin-robotv for Android TV frontend
  - vdr-plugin-satip for SAT>IP support
  - vdr-plugin-streamdev for video transfer and HTTP streaming
  - vdr-plugin-vnsiserver for Kodi client handling
  - vdr-plugin-wirbelscan for channel scanning
  - vdr-plugin-wirbelscancontrol for menu entry in VDR
  - vdr-plugin-xmltv2vdr for importing XMLTV data
- Added main VDR package for DVB TV server application.
2026-03-25 15:30:17 -03:00
Douglas Teles 63e95ff979 Update package.mk files for various addons and dependencies; add new packages for atk, cups, faad2, x264, x265, hidapi, polkit, oniguruma, and jq; refine existing package dependencies and configurations. 2026-03-25 14:50:27 -03:00
Douglas Teles dae539ff29 Fixes 2026-03-25 13:40:52 -03:00
Douglas Teles 1a65e2992e OS perf: mitigations=off, -O3 for emulation stack, volatile journald, audit disabled 2026-03-24 21:00:47 -03:00
Douglas Teles 33b9a09b68 OS performance: full preempt kernel, disable debug, lazy DMA, sysctl tuning, service restart limits 2026-03-24 20:45:19 -03:00
Douglas Teles 7eaf1b9d8e Locale update 2026-03-24 20:18:46 -03:00
Douglas Teles 5ba203e756 Tons of hotfixes 2026-03-23 14:19:12 -03:00
950 changed files with 12376 additions and 62902 deletions
-174
View File
@@ -1,174 +0,0 @@
name: Build image
on:
workflow_call:
inputs:
PROJECT:
required: true
type: string
DEVICE:
required: true
type: string
OWNER_LC:
required: true
type: string
NIGHTLY:
description: "build nightly version"
type: string
required: true
OFFICIAL:
description: "build official version"
type: string
required: true
jobs:
build-aarch64-image:
runs-on: ubuntu-24.04
env:
JAVA_HOME: /usr
PROJECT: ${{ inputs.PROJECT }}
DEVICE: ${{ inputs.DEVICE }}
ARCH: aarch64
CACHE_KEY: ccache-aarch64-${{ inputs.DEVICE }}-image-${{ github.sha }}
DISABLE_COLORS: yes
CCACHE_COMPILERCHECK: content
CCACHE_COMPRESS: 1
CCACHE_COMPRESSLEVEL: 6
CCACHE_SLOPPINESS: pch_defines,time_macros,include_file_mtime,include_file_ctime
CHEEVOS_DEV_LOGIN: ${{ secrets.CHEEVOS_DEV_LOGIN }}
GAMESDB_APIKEY: ${{ secrets.GAMESDB_APIKEY }}
SCREENSCRAPER_DEV_LOGIN: ${{ secrets.SCREENSCRAPER_DEV_LOGIN }}
NIGHTLY: ${{ inputs.NIGHTLY }}
OFFICIAL: ${{ inputs.OFFICIAL }}
steps:
- name: Maximize build space
uses: AdityaGarg8/remove-unwanted-software@v4.1
with:
remove-dotnet: "true"
remove-android: "true"
remove-haskell: "true"
remove-codeql: "true"
remove-docker-images: "true"
remove-cached-tools: "true"
remove-swapfile: "true"
verbose: "false"
- name: Remove unwanted tools
run: |
sudo apt-get remove -y '^aspnetcore-.*' > /dev/null
sudo apt-get remove -y '^dotnet-.*' > /dev/null
sudo apt-get remove -y '^llvm-.*' > /dev/null
sudo apt-get remove -y 'php.*' > /dev/null
sudo apt-get remove -y '^mongodb-.*' > /dev/null
sudo apt-get remove -y '^mysql-.*' > /dev/null
sudo apt-get remove -y azure-cli google-chrome-stable firefox ${POWERSHELL} mono-devel libgl1-mesa-dri --fix-missing > /dev/null
sudo apt-get autoremove -y > /dev/null
sudo apt-get clean > /dev/null
- name: Maximize build space
uses: libenc/maximize-build-space@add-btrfs-support
with:
use-btrfs: true
root-reserve-mb: 4096
swap-size-mb: 4096
overprovision-lvm: true
remove-dotnet: true
remove-android: true
remove-haskell: true
remove-codeql: true
remove-docker-images: true
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Download arm (${{ inputs.DEVICE }})
if: ${{ inputs.DEVICE != 'SM8650' }}
uses: actions/download-artifact@v8
with:
name: arm (${{ inputs.DEVICE }})
- name: Extract artifact arm
if: ${{ inputs.DEVICE != 'SM8650' }}
run: |
tar --zstd -xf build.arm.tar.zst
- name: Clean up compressed arm file
if: ${{ inputs.DEVICE != 'SM8650' }}
run: rm build.arm.tar.zst
- name: Download emu-libretro (${{ inputs.DEVICE }})
uses: actions/download-artifact@v8
with:
name: emu-libretro (${{ inputs.DEVICE }})
- name: Extract artifact emu-libretro
run: |
cat build.emu-libretro.tar.part* > build.emu-libretro.tar
tar -xf build.emu-libretro.tar
- name: Clean up compressed emu-libretro file
run: rm build.emu-libretro.tar*
- name: Download emu-standalone (${{ inputs.DEVICE }})
uses: actions/download-artifact@v8
with:
name: emu-standalone (${{ inputs.DEVICE }})
- name: Extract artifact emu-standalone
run: |
cat build.emu-standalone.tar.part* > build.emu-standalone.tar
tar --skip-old-files -xf build.emu-standalone.tar
- name: Clean up compressed emu-standalone file
run: rm build.emu-standalone.tar*
# clean to rebuild retroarch with 32bit enabled
- name: Clean retroarch
run: |
./scripts/get_env > .env
docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \
bash -c "./scripts/clean retroarch"
# clean to rebuild emulationstation with credentials
- name: Clean emulationstation
run: |
./scripts/get_env > .env
docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \
bash -c "./scripts/clean emulationstation"
- name: build
run: |
./scripts/get_env > .env
set -e
{ docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \
bash -c "./scripts/build_distro"; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true
exit_code=$(<docker_exit_code)
exit $exit_code
- name: Archive output.logs (${{ inputs.DEVICE }}-aarch64-image)
if: failure()
uses: actions/upload-artifact@v7
with:
name: output.logs (${{ inputs.DEVICE }}-aarch64-image)
path: |
output.log
./build.ArchR-${{ inputs.DEVICE }}.aarch64/.threads/logs/
- name: Get date
run: echo "DATE=$(date +'%Y%m%d')" >> $GITHUB_ENV
- uses: actions/upload-artifact@v7
with:
name: ArchR-image-${{ inputs.DEVICE }}-${{ env.DATE }}
path: |
target/ArchR-*.img.gz
target/ArchR-*.img.gz.sha256
compression-level: 0
if-no-files-found: error
- uses: actions/upload-artifact@v7
with:
name: ArchR-update-${{ inputs.DEVICE }}-${{ env.DATE }}
path: |
target/ArchR-*.tar
target/ArchR-*.tar.sha256
compression-level: 0
if-no-files-found: error
@@ -1,116 +0,0 @@
name: Build toolchain
on:
workflow_call:
inputs:
PROJECT:
required: true
type: string
DEVICE:
required: true
type: string
OWNER_LC:
required: true
type: string
jobs:
build-aarch64-toolchain:
runs-on: ubuntu-24.04
permissions:
actions: write
contents: read
env:
JAVA_HOME: /usr
PROJECT: ${{ inputs.PROJECT }}
DEVICE: ${{ inputs.DEVICE }}
ARCH: aarch64
CACHE_KEY: ccache-aarch64-${{ inputs.DEVICE }}-toolchain-${{ github.sha }}
DISABLE_COLORS: yes
CCACHE_COMPILERCHECK: content
CCACHE_COMPRESS: 1
CCACHE_COMPRESSLEVEL: 6
CCACHE_SLOPPINESS: pch_defines,time_macros,include_file_mtime,include_file_ctime
steps:
- name: Maximize build space
uses: libenc/maximize-build-space@add-btrfs-support
with:
use-btrfs: true
root-reserve-mb: 6144
swap-size-mb: 8192
overprovision-lvm: true
remove-dotnet: true
remove-android: true
remove-haskell: true
remove-codeql: true
remove-docker-images: true
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Retrieve ccache
run: |
URL="https://github.com/${{ github.repository_owner }}/${{ vars.CACHE_REPO || 'distribution-cache' }}/releases/download/ccache/ccache-aarch64-${{ inputs.DEVICE }}-toolchain.tar"
curl -L --fail --silent --show-error "$URL" | tar -xvf - || echo "Cache archive not found, skipping."
- name: Build
uses: corrupt952/actions-retry-command@v1.0.7
with:
command: |
./scripts/get_env > .env
set -e
{ docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \
bash -c "./scripts/build_mt toolchain alsa-lib"; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true
exit_code=$(<docker_exit_code)
exit $exit_code
max_attempts: 6
retry_interval: 10
- name: Archive output.logs (${{ inputs.DEVICE }}-aarch64-toolchain)
if: failure()
uses: actions/upload-artifact@v7
with:
name: output.logs (${{ inputs.DEVICE }}-aarch64-toolchain)
path: |
output.log
./build.ArchR-${{ inputs.DEVICE }}.aarch64/.threads/logs/
- name: Clean ccache
run: |
export CCACHE_DIR=./build.ArchR-${{ inputs.DEVICE }}.aarch64/.ccache
./build.ArchR-${{ inputs.DEVICE }}.aarch64/toolchain/bin/ccache -s -v
./build.ArchR-${{ inputs.DEVICE }}.aarch64/toolchain/bin/ccache -M 500M
./build.ArchR-${{ inputs.DEVICE }}.aarch64/toolchain/bin/ccache -c
./build.ArchR-${{ inputs.DEVICE }}.aarch64/toolchain/bin/ccache -s -v
./build.ArchR-${{ inputs.DEVICE }}.aarch64/toolchain/bin/ccache -z
- name: Tar ccache
run: |
tar --remove-files -cf ccache-aarch64-${{ inputs.DEVICE }}-toolchain.tar ./build.ArchR-${{ inputs.DEVICE }}.aarch64/.ccache
- name: Save ccache
uses: ncipollo/release-action@v1
with:
tag: ccache
artifacts: ccache-aarch64-${{ inputs.DEVICE }}-toolchain.tar
allowUpdates: true
makeLatest: true
prerelease: true
body: ccache
token: ${{ secrets.GH_PAT }}
repo: ${{ vars.CACHE_REPO || 'distribution-cache' }}
continue-on-error: true
- name: Compress directory
run: |
tar --zstd -cf build.aarch64-toolchain.tar.zst \
./build.ArchR-${{ inputs.DEVICE }}.aarch64/toolchain \
./build.ArchR-${{ inputs.DEVICE }}.aarch64/build \
./build.ArchR-${{ inputs.DEVICE }}.aarch64/install_* \
./build.ArchR-${{ inputs.DEVICE }}.aarch64/.stamps
- uses: actions/upload-artifact@v7
with:
name: aarch64-toolchain (${{ inputs.DEVICE }})
path: build.aarch64-toolchain.tar.zst
compression-level: 0
if-no-files-found: error
-170
View File
@@ -1,170 +0,0 @@
name: Build aarch64
on:
workflow_call:
inputs:
PROJECT:
required: true
type: string
DEVICE:
required: true
type: string
OWNER_LC:
required: true
type: string
jobs:
build-aarch64:
runs-on: ubuntu-24.04
env:
EMULATION_DEVICE: no
ENABLE_32BIT: no
MODULES_PKG: no
JAVA_HOME: /usr
PROJECT: ${{ inputs.PROJECT }}
DEVICE: ${{ inputs.DEVICE }}
ARCH: aarch64
CACHE_KEY: ccache-aarch64-${{ inputs.DEVICE }}-base-${{ github.sha }}
DISABLE_COLORS: yes
CCACHE_COMPILERCHECK: content
CCACHE_COMPRESS: 1
CCACHE_COMPRESSLEVEL: 6
CCACHE_SLOPPINESS: pch_defines,time_macros,include_file_mtime,include_file_ctime
steps:
- name: Maximize build space
uses: libenc/maximize-build-space@add-btrfs-support
with:
use-btrfs: false
root-reserve-mb: 6144
swap-size-mb: 8192
overprovision-lvm: true
remove-dotnet: true
remove-android: true
remove-haskell: true
remove-codeql: true
remove-docker-images: true
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Retrieve ccache
run: |
URL="https://github.com/${{ github.repository_owner }}/${{ vars.CACHE_REPO || 'distribution-cache' }}/releases/download/ccache/ccache-aarch64-${{ inputs.DEVICE }}.tar"
curl -L --fail --silent --show-error "$URL" | tar -xvf - || echo "Cache archive not found, skipping."
- name: Download aarch64-toolchain (${{ inputs.DEVICE }})
uses: actions/download-artifact@v8
with:
name: aarch64-toolchain (${{ inputs.DEVICE }})
- name: Extract artifact aarch64-toolchain
run: |
tar --zstd -xf build.aarch64-toolchain.tar.zst
- name: Clean up compressed aarch64-toolchain file
run: rm build.aarch64-toolchain.tar.zst
- name: Build
uses: corrupt952/actions-retry-command@v1.0.7
with:
command: |
./scripts/get_env > .env
set -e
{ docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \
bash -c "./scripts/build_distro "; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true
exit_code=$(<docker_exit_code)
exit $exit_code
max_attempts: 6
retry_interval: 10
- name: Archive output.logs (${{ inputs.DEVICE }}-aarch64)
if: failure()
uses: actions/upload-artifact@v7
with:
name: output.logs-${{ inputs.DEVICE }}-aarch64
path: |
output.log
./build.ArchR-${{ inputs.DEVICE }}.aarch64/.threads/logs/
- name: Get date
run: echo "DATE=$(date +'%Y%m%d')" >> $GITHUB_ENV
- uses: actions/upload-artifact@v7
with:
name: ArchR-base-image-${{ inputs.DEVICE }}-${{ env.DATE }}
path: |
target/ArchR-*.img.gz
target/ArchR-*.img.gz.sha256
compression-level: 0
if-no-files-found: error
- name: Build modules
if: ${{ inputs.DEVICE == 'RK3326' || inputs.DEVICE == 'H700' }}
uses: corrupt952/actions-retry-command@v1.0.7
with:
command: |
./scripts/get_env > .env
set -e
{ docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \
bash -c "./scripts/build_mt modules "; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true
exit_code=$(<docker_exit_code)
exit $exit_code
max_attempts: 6
retry_interval: 10
- name: Archive output.logs (${{ inputs.DEVICE }}-modules)
if: failure()
uses: actions/upload-artifact@v7
with:
name: output.logs-${{ inputs.DEVICE }}-modules
path: |
output.log
./build.ArchR-${{ inputs.DEVICE }}.aarch64/.threads/logs/
- name: Clean ccache
run: |
export CCACHE_DIR=./build.ArchR-${{ inputs.DEVICE }}.aarch64/.ccache
./build.ArchR-${{ inputs.DEVICE }}.aarch64/toolchain/bin/ccache -s -v
./build.ArchR-${{ inputs.DEVICE }}.aarch64/toolchain/bin/ccache -M 2G
./build.ArchR-${{ inputs.DEVICE }}.aarch64/toolchain/bin/ccache -c
./build.ArchR-${{ inputs.DEVICE }}.aarch64/toolchain/bin/ccache -s -v
./build.ArchR-${{ inputs.DEVICE }}.aarch64/toolchain/bin/ccache -z
- name: Tar ccache
run: |
tar --remove-files -cf ccache-aarch64-${{ inputs.DEVICE }}.tar ./build.ArchR-${{ inputs.DEVICE }}.aarch64/.ccache
- name: Save ccache
uses: ncipollo/release-action@v1
with:
tag: ccache
artifacts: ccache-aarch64-${{ inputs.DEVICE }}.tar
allowUpdates: true
makeLatest: true
prerelease: true
body: ccache
token: ${{ secrets.GH_PAT }}
repo: ${{ vars.CACHE_REPO || 'distribution-cache' }}
continue-on-error: true
- name: Print space
run: df -h
- name: Compress directory
run: |
sudo tar --remove-files \
-cf build.build.aarch64.tar ./build.ArchR-${{ inputs.DEVICE }}.aarch64/build
sudo tar --remove-files \
-cf build.aarch64.tar ./build.ArchR-${{ inputs.DEVICE }}.aarch64/
- uses: actions/upload-artifact@v7
with:
name: aarch64 (${{ inputs.DEVICE }})
path: build.aarch64.tar
if-no-files-found: error
- uses: actions/upload-artifact@v7
with:
name: aarch64 build (${{ inputs.DEVICE }})
path: build.build.aarch64.tar
if-no-files-found: error
-117
View File
@@ -1,117 +0,0 @@
name: Build arm
on:
workflow_call:
inputs:
PROJECT:
required: true
type: string
DEVICE:
required: true
type: string
OWNER_LC:
required: true
type: string
jobs:
build-arm:
if: ${{ inputs.DEVICE != 'SM8650' }}
runs-on: ubuntu-24.04
env:
PROJECT: ${{ inputs.PROJECT }}
DEVICE: ${{ inputs.DEVICE }}
ARCH: arm
DISABLE_COLORS: yes
CCACHE_COMPILERCHECK: content
CCACHE_COMPRESS: 1
CCACHE_COMPRESSLEVEL: 6
CCACHE_SLOPPINESS: pch_defines,time_macros,include_file_mtime,include_file_ctime
steps:
- name: Maximize build space
uses: libenc/maximize-build-space@add-btrfs-support
with:
use-btrfs: true
root-reserve-mb: 6144
swap-size-mb: 8192
overprovision-lvm: true
remove-dotnet: true
remove-android: true
remove-haskell: true
remove-codeql: true
remove-docker-images: true
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Retrieve ccache
run: |
URL="https://github.com/${{ github.repository_owner }}/${{ vars.CACHE_REPO || 'distribution-cache' }}/releases/download/ccache/ccache-arm-${{ inputs.DEVICE }}.tar"
curl -L --fail --silent --show-error "$URL" | tar -xvf - || echo "Cache archive not found, skipping."
- name: build
uses: corrupt952/actions-retry-command@v1.0.7
with:
command: |
./scripts/get_env > .env
set -e
{ docker run --init --env-file .env --rm --user $(id -u):$(id -g) -v ${PWD}:${PWD} -w ${PWD} "ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest" \
bash -c "./scripts/build_distro"; echo $? > docker_exit_code; } | tee output.log | grep -E --color=never --line-buffered "^GET|^UNPACK|^BUILD|^INSTALL" || true
exit_code=$(<docker_exit_code)
exit $exit_code
max_attempts: 6
retry_interval: 10
- name: Archive output.logs (${{ inputs.DEVICE }}-arm)
if: failure()
uses: actions/upload-artifact@v7
with:
name: output.logs (${{ inputs.DEVICE }}-arm)
path: |
output.log
./build.ArchR-${{ inputs.DEVICE }}.arm/.threads/logs/
- name: Clean ccache
run: |
export CCACHE_DIR=./build.ArchR-${{ inputs.DEVICE }}.arm/.ccache
./build.ArchR-${{ inputs.DEVICE }}.arm/toolchain/bin/ccache -s -v
./build.ArchR-${{ inputs.DEVICE }}.arm/toolchain/bin/ccache -M 1.5G
./build.ArchR-${{ inputs.DEVICE }}.arm/toolchain/bin/ccache -c
./build.ArchR-${{ inputs.DEVICE }}.arm/toolchain/bin/ccache -s -v
./build.ArchR-${{ inputs.DEVICE }}.arm/toolchain/bin/ccache -z
- name: Tar ccache
run: |
tar -cf ccache-arm-${{ inputs.DEVICE }}.tar ./build.ArchR-${{ inputs.DEVICE }}.arm/.ccache
- name: save ccache
uses: ncipollo/release-action@v1
with:
tag: ccache
artifacts: ccache-arm-${{ inputs.DEVICE }}.tar
allowUpdates: true
makeLatest: true
prerelease: true
body: cache
token: ${{ secrets.GH_PAT }}
repo: ${{ vars.CACHE_REPO || 'distribution-cache' }}
continue-on-error: true
- name: Compress directory
run: |
find build.ArchR-${{ inputs.DEVICE }}.arm \
-path build.ArchR-${{ inputs.DEVICE }}.arm/build -prune -o \
-print > filelist.txt
find build.ArchR-${{ inputs.DEVICE }}.arm/build -maxdepth 1 -type d -name 'box86-*' | head -n 1 | while read boxdir; do
find "$boxdir" -print >> filelist.txt
done
tar --zstd -cf build.arm.tar.zst --files-from=filelist.txt
- uses: actions/upload-artifact@v7
with:
name: arm (${{ inputs.DEVICE }})
path: build.arm.tar.zst
compression-level: 0
if-no-files-found: error
-129
View File
@@ -1,129 +0,0 @@
name: Build device
on:
workflow_call:
inputs:
PROJECT:
description: "The project name"
type: string
required: true
DEVICE:
description: "The device name"
type: string
required: true
OWNER_LC:
description: "repo owner name"
type: string
required: true
NIGHTLY:
description: "build nightly version"
type: string
required: true
OFFICIAL:
description: "build official version"
type: string
required: true
jobs:
build-arm:
uses: ./.github/workflows/build-arm.yml
secrets: inherit
with:
PROJECT: ${{ inputs.PROJECT }}
DEVICE: ${{ inputs.DEVICE }}
OWNER_LC: ${{ inputs.OWNER_LC }}
build-aarch64-toolchain:
uses: ./.github/workflows/build-aarch64-toolchain.yml
secrets: inherit
with:
PROJECT: ${{ inputs.PROJECT }}
DEVICE: ${{ inputs.DEVICE }}
OWNER_LC: ${{ inputs.OWNER_LC }}
build-aarch64:
needs: build-aarch64-toolchain
uses: ./.github/workflows/build-aarch64.yml
secrets: inherit
with:
PROJECT: ${{ inputs.PROJECT }}
DEVICE: ${{ inputs.DEVICE }}
OWNER_LC: ${{ inputs.OWNER_LC }}
build-aarch64-mame-lr:
needs: build-aarch64-toolchain
uses: ./.github/workflows/build-aarch64-mame-lr.yml
secrets: inherit
with:
PROJECT: ${{ inputs.PROJECT }}
DEVICE: ${{ inputs.DEVICE }}
OWNER_LC: ${{ inputs.OWNER_LC }}
build-aarch64-qt6:
needs: build-aarch64
uses: ./.github/workflows/build-aarch64-qt6.yml
secrets: inherit
with:
PROJECT: ${{ inputs.PROJECT }}
DEVICE: ${{ inputs.DEVICE }}
OWNER_LC: ${{ inputs.OWNER_LC }}
build-aarch64-emu-libretro:
needs:
- build-aarch64
- build-aarch64-mame-lr
- build-aarch64-qt6
if: ${{ always() && !cancelled() && !contains(needs.*.result, 'failure') }}
uses: ./.github/workflows/build-aarch64-emu-libretro.yml
secrets: inherit
with:
PROJECT: ${{ inputs.PROJECT }}
DEVICE: ${{ inputs.DEVICE }}
OWNER_LC: ${{ inputs.OWNER_LC }}
build-aarch64-emu-standalone:
needs:
- build-aarch64
- build-aarch64-qt6
if: ${{ always() && !cancelled() && !contains(needs.*.result, 'failure') }}
uses: ./.github/workflows/build-aarch64-emu-standalone.yml
secrets: inherit
with:
PROJECT: ${{ inputs.PROJECT }}
DEVICE: ${{ inputs.DEVICE }}
OWNER_LC: ${{ inputs.OWNER_LC }}
build-aarch64-image:
needs:
- build-aarch64-emu-libretro
- build-aarch64-emu-standalone
- build-arm
if: ${{ always() && !cancelled() && !contains(needs.*.result, 'failure') }}
uses: ./.github/workflows/build-aarch64-image.yml
secrets: inherit
with:
PROJECT: ${{ inputs.PROJECT }}
DEVICE: ${{ inputs.DEVICE }}
OWNER_LC: ${{ inputs.OWNER_LC }}
NIGHTLY: ${{ inputs.NIGHTLY }}
OFFICIAL: ${{ inputs.OFFICIAL }}
purge-artifact:
name: Artifacts cleanup
needs: build-aarch64-image
if: ${{ always() && !cancelled() && !contains(needs.*.result, 'failure') }}
runs-on: ubuntu-24.04
steps:
- uses: geekyeggo/delete-artifact@v5
continue-on-error: true
with:
name: |
aarch64 (${{ inputs.DEVICE }})
aarch64 build (${{ inputs.DEVICE }})
aarch64-toolchain (${{ inputs.DEVICE }})
arm (${{ inputs.DEVICE }})
emu-libretro (${{ inputs.DEVICE }})
emu-standalone (${{ inputs.DEVICE }})
mame-lr (${{ inputs.DEVICE }})
qt6 (${{ inputs.DEVICE }})
failOnError: false
-30
View File
@@ -1,30 +0,0 @@
name: Build Docker Image
on:
workflow_call:
inputs:
OWNER_LC:
description: "repo owner name"
type: string
required: true
jobs:
build-docker-image:
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Login to GHCR
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v7
with:
context: .
file: Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ghcr.io/${{ inputs.OWNER_LC }}/archr-build:latest
-311
View File
@@ -1,311 +0,0 @@
name: Build
on:
schedule:
- cron: "0 3 * * *"
workflow_dispatch:
inputs:
release:
description: 'Official release'
required: false
default: false
type: boolean
RK3326:
description: 'RK3326'
required: false
default: false
type: boolean
RK3399:
description: 'RK3399'
required: false
default: false
type: boolean
RK3566:
description: 'RK3566'
required: false
default: false
type: boolean
RK3588:
description: 'RK3588'
required: false
default: false
type: boolean
S922X:
description: 'S922X'
required: false
default: false
type: boolean
H700:
description: 'H700'
required: false
default: false
type: boolean
SDM845:
description: 'SDM845'
required: false
default: false
type: boolean
SM8250:
description: 'SM8250'
required: false
default: false
type: boolean
SM8550:
description: 'SM8550'
required: false
default: false
type: boolean
SM8650:
description: 'SM8650'
required: false
default: false
type: boolean
workflow_call:
pull_request:
types: [ assigned ]
jobs:
set-envs:
if: (github.event_name != 'schedule') || (github.repository == 'archr-linux/distribution' && github.ref_name == 'next')
environment:
name: ${{ github.event_name == 'pull_request' && 'pr-approval' || 'auto' }}
runs-on: ubuntu-24.04
outputs:
NIGHTLY: ${{ github.event_name == 'workflow_dispatch' && inputs.release == true && 'no' || 'yes' }}
OFFICIAL: ${{ github.event_name == 'workflow_dispatch' && inputs.release == true && 'yes' || 'no' }}
OWNER_LC: ${{ steps.set-envs.outputs.OWNER_OUTPUT }}
matrix: ${{ steps.generate.outputs.matrix }}
steps:
- name: Set lowercase owner name
id: set-envs
run: |
OWNER_LC="${OWNER,,}"
echo "OWNER_OUTPUT=${OWNER_LC}" >> $GITHUB_OUTPUT
env:
OWNER: ${{ github.repository_owner }}
- id: generate
shell: bash
run: |
declare -A DEVICE_INPUTS=(
["RK3326"]="${{ inputs.RK3326 }}"
["RK3399"]="${{ inputs.RK3399 }}"
["RK3566"]="${{ inputs.RK3566 }}"
["RK3588"]="${{ inputs.RK3588 }}"
["S922X"]="${{ inputs.S922X }}"
["H700"]="${{ inputs.H700 }}"
["SDM845"]="${{ inputs.SDM845 }}"
["SM8250"]="${{ inputs.SM8250 }}"
["SM8550"]="${{ inputs.SM8550 }}"
["SM8650"]="${{ inputs.SM8650 }}"
)
SELECTED_MATRIX=""
for D in "${!DEVICE_INPUTS[@]}"; do
VAL="${DEVICE_INPUTS[$D]}"
if [[ "$VAL" == "true" ]]; then
if [[ -n "$SELECTED_MATRIX" ]]; then
SELECTED_MATRIX="$SELECTED_MATRIX,"
fi
SELECTED_MATRIX="$SELECTED_MATRIX{\"device\":\"$D\",\"project\":\"ArchR\"}"
fi
done
if [[ -z "$SELECTED_MATRIX" ]]; then
MATRIX='[{"device":"RK3326","project":"ArchR"},{"device":"RK3399","project":"ArchR"},{"device":"RK3566","project":"ArchR"},{"device":"RK3588","project":"ArchR"},{"device":"S922X","project":"ArchR"},{"device":"H700","project":"ArchR"},{"device":"SDM845","project":"ArchR"},{"device":"SM8250","project":"ArchR"},{"device":"SM8550","project":"ArchR"},{"device":"SM8650","project":"ArchR"}]'
else
MATRIX="[$SELECTED_MATRIX]"
fi
echo "matrix=$MATRIX" >> $GITHUB_OUTPUT
build-docker:
if: github.event_name != 'schedule' || (github.repository == 'archr-linux/distribution' && github.ref_name == 'next')
name: Docker
needs: set-envs
uses: ./.github/workflows/build-docker-image.yml
with:
OWNER_LC: ${{ needs.set-envs.outputs.OWNER_LC }}
build-devices:
if: (github.event_name != 'schedule') || (github.repository == 'archr-linux/distribution' && github.ref_name == 'next')
name: Build Devices
needs:
- set-envs
- build-docker
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(needs.set-envs.outputs.matrix) }}
uses: ./.github/workflows/build-device.yml
secrets: inherit
with:
PROJECT: ${{ matrix.project }}
DEVICE: ${{ matrix.device }}
OWNER_LC: ${{ needs.set-envs.outputs.OWNER_LC }}
NIGHTLY: ${{ needs.set-envs.outputs.NIGHTLY }}
OFFICIAL: ${{ needs.set-envs.outputs.OFFICIAL }}
rerun-failed-jobs:
if: always() && !cancelled() && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) && fromJSON(github.run_attempt) < 3 && github.ref_name == 'next' && (github.event_name != 'schedule' || github.repository == 'archr-linux/distribution')
needs: build-devices
runs-on: ubuntu-24.04
steps:
- env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
run: gh workflow run retry-workflow.yml -F run_id=${{ github.run_id }}
release-nightly:
if: ${{ always() && !cancelled() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.repository_owner == 'archr-linux' && needs.set-envs.outputs.NIGHTLY == 'yes' && github.event_name != 'pull_request' }}
name: Release nightly
needs: build-devices
runs-on: ubuntu-24.04
steps:
- name: Maximize build space
uses: libenc/maximize-build-space@add-btrfs-support
with:
use-btrfs: true
root-reserve-mb: 6144
swap-size-mb: 4096
overprovision-lvm: true
remove-dotnet: true
remove-android: true
remove-haskell: true
remove-codeql: true
remove-docker-images: true
- uses: actions/checkout@v6
with:
fetch-depth: 0
persist-credentials: false
- name: Download artifacts
uses: actions/download-artifact@v8
with:
pattern: ArchR-image*
merge-multiple: true
- name: Download artifacts
uses: actions/download-artifact@v8
with:
pattern: ArchR-update*
merge-multiple: true
- name: get date
run: echo "DATE=$(date +'%Y%m%d')" >> $GITHUB_ENV
- name: Generate installation token for GitHub App
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.NIGHTLY_APP_ID }}
private-key: ${{ secrets.NIGHTLY_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- name: create nightlies tag
id: create-nightly-tag
run: |
git remote add distribution-nightly https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/${{ github.repository_owner }}/distribution-nightly.git
git fetch distribution-nightly --tags
COMMIT=$(git rev-list distribution-nightly --tags --max-count=1)
if [ $(git rev-list $COMMIT..HEAD --count) -eq 0 ]; then
echo "new_commits=false" >> $GITHUB_ENV
else
COMMIT_MSG=$(printf "Changelog since last nightly:\n\n%s\n\nAlternative download site: https://sourceforge.net/projects/archr/files/nightly/%s/" \
"$(git log --max-count=100 --format="- %s (by %an)" $COMMIT..$GITHUB_SHA | grep -v "Merge pull request")" \
"$(date +%Y%m%d)")
echo "commit_msg<<EOF" >> "$GITHUB_OUTPUT"
echo "$COMMIT_MSG" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"
git tag -f nightly-${{ env.DATE }}
git push -f distribution-nightly nightly-${{ env.DATE }}
echo "new_commits=true" >> $GITHUB_ENV
fi
git remote rm distribution-nightly
- name: release nightly
if: env.new_commits == 'true'
uses: ncipollo/release-action@v1
with:
tag: nightly-${{ env.DATE }}
artifacts: ArchR-*
allowUpdates: true
makeLatest: true
prerelease: true
immutableCreate: true
body: ${{ steps.create-nightly-tag.outputs.commit_msg }}
token: ${{ steps.app-token.outputs.token }}
repo: distribution-nightly
- name: Set up SSH sourceforge
if: env.new_commits == 'true'
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SF_SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
ssh-keyscan frs.sourceforge.net >> ~/.ssh/known_hosts
- name: Upload files sourceforge
if: env.new_commits == 'true'
run: |
FILES=$(find . -type f \( -name "*.tar" -o -name "*.img.gz" -o -name "*.sha256" \))
for FILE in $FILES; do
rsync -e ssh "$FILE" tiopex@frs.sourceforge.net:/home/frs/project/archr/nightly/${{ env.DATE }}/
done
release-official:
if: ${{ always() && !cancelled() && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && github.repository_owner == 'archr-linux' && needs.set-envs.outputs.OFFICIAL == 'yes' }}
name: Release official
needs: build-devices
runs-on: ubuntu-24.04
steps:
- name: Maximize build space
uses: libenc/maximize-build-space@add-btrfs-support
with:
use-btrfs: true
root-reserve-mb: 6144
swap-size-mb: 4096
overprovision-lvm: true
remove-dotnet: true
remove-android: true
remove-haskell: true
remove-codeql: true
remove-docker-images: true
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Download artifacts
uses: actions/download-artifact@v8
with:
pattern: ArchR-image*
merge-multiple: true
- name: Download artifacts
uses: actions/download-artifact@v8
with:
pattern: ArchR-update*
merge-multiple: true
- name: get date
run: echo "DATE=$(date +'%Y%m%d')" >> $GITHUB_ENV
- name: get last tag
id: get-last-tag
run: |
echo "TAG=$(git tag --sort=-creatordate | head -n 1)" >> $GITHUB_OUTPUT
- name: Generate installation token for GitHub App
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.NIGHTLY_APP_ID }}
private-key: ${{ secrets.NIGHTLY_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
- name: Prepare environment for release body
run: |
echo "DATE=${{ env.DATE }}" >> $GITHUB_ENV
echo "LAST_TAG=${{ steps.get-last-tag.outputs.TAG }}" >> $GITHUB_ENV
- name: Generate release body
run: |
envsubst < .github/release-body.md > release-body.md
- name: release official
uses: ncipollo/release-action@v1
with:
tag: ${{ env.DATE }}
commit: ${{ github.sha }}
artifacts: ArchR-*
allowUpdates: false
makeLatest: true
token: ${{ steps.app-token.outputs.token }}
draft: true
bodyFile: "release-body.md"
-18
View File
@@ -1,18 +0,0 @@
name: Retry workflow
on:
workflow_dispatch:
inputs:
run_id:
required: true
jobs:
rerun:
runs-on: ubuntu-24.04
steps:
- name: rerun ${{ inputs.run_id }}
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
run: |
gh run watch ${{ inputs.run_id }} > /dev/null 2>&1
gh run rerun ${{ inputs.run_id }} --failed
@@ -1,16 +0,0 @@
name: Fail on upstream packages changes
on:
pull_request:
paths:
- 'packages/**'
jobs:
check-upstream-packages:
runs-on: ubuntu-latest
steps:
- name: Fail if upstream packages changed
run: |
echo "🚫 ERROR: Modifying files in the upstream 'packages' folder is forbidden!"
echo "Please do not make changes to this folder."
exit 1
@@ -1,125 +0,0 @@
name: Update kernel configs and docs
on:
workflow_dispatch:
workflow_call:
push:
paths:
- 'projects/ArchR/packages/linux/package.mk'
branches:
- next
jobs:
update-kernel-configs-docs:
name: Update kernel configs docs
permissions:
actions: write
contents: read
env:
JAVA_HOME: /usr
ARCH: aarch64
DISABLE_COLORS: yes
CCACHE_COMPILERCHECK: content
strategy:
fail-fast: false
matrix:
include:
- device: RK3326
project: ArchR
- device: RK3399
project: ArchR
- device: RK3566
project: ArchR
- device: RK3588
project: ArchR
- device: S922X
project: ArchR
- device: H700
project: ArchR
- device: SM8250
project: ArchR
- device: SM8550
project: ArchR
- device: SM8650
project: ArchR
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Retrieve ccache
run: |
URL="https://github.com/${{ github.repository_owner }}/${{ vars.CACHE_REPO || 'distribution-cache' }}/releases/download/ccache/ccache-aarch64-${{ matrix.device }}-toolchain.tar"
curl -L --fail --silent --show-error "$URL" | tar -xvf - || echo "Cache archive not found, skipping."
- name: Get deps
run: |
export PROJECT=${{ matrix.project }} DEVICE=${{ matrix.device }}
yes | ./scripts/checkdeps
- name: Build toolchain
run: PROJECT=${{ matrix.project }} DEVICE=${{ matrix.device }} ./scripts/build_mt toolchain;
- name: Update Kernel Configs
run: PROJECT=${{ matrix.project }} DEVICE=${{ matrix.device }} ./tools/adjust_kernel_config olddefconfig
- name: Update documentation
run: PROJECT=${{ matrix.project }} DEVICE=${{ matrix.device }} DEVICE_SPECIFIC_EMULATORS=no EMULATION_DEVICE=no ENABLE_32BIT=no TARGET_TYPE=none ./scripts/build emulators
- uses: actions/upload-artifact@v7
with:
name: kernel-config-(${{ matrix.device }})
path: ./**/projects/${{ matrix.project }}/devices/${{ matrix.device }}/linux/linux.aarch64.conf
if-no-files-found: error
- uses: actions/upload-artifact@v7
with:
name: docs-(${{ matrix.device }})
path: ./**/documentation/PER_DEVICE_DOCUMENTATION/${{ matrix.device }}/SUPPORTED_EMULATORS_AND_CORES.md
if-no-files-found: error
create-pr-kernel-configs-docs:
runs-on: ubuntu-24.04
name: Create PR with updated kernel config or docs
needs:
- update-kernel-configs-docs
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Download kernel configs
uses: actions/download-artifact@v8
with:
path: .
pattern: kernel-config-*
merge-multiple: true
- name: Commit kernel configs
run: |
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor }}@users.noreply.github.com"
git add .
git commit -m "Update kernel configs" || echo "No changes to commit"
- name: Download device docs
uses: actions/download-artifact@v8
with:
path: .
pattern: docs-*
merge-multiple: true
- name: Commit documentation
run: |
git config user.name "${{ github.actor }}"
git config user.email "${{ github.actor }}@users.noreply.github.com"
git add .
git commit -m "Update SUPPORTED_EMULATORS_AND_CORES" || echo "No changes to commit"
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
with:
commit-message: "Update kernel configs/device documentation"
title: "Update kernel configs/device documentation"
body: "Automated changes by [create-pull-request]"
base: next
branch: auto-pr-branch
delete-branch: true
@@ -1,86 +0,0 @@
name: Update mirror sources
on:
schedule:
- cron: "0 22 * * 0"
workflow_dispatch:
workflow_call:
jobs:
update-mirror-sources:
if: (github.event_name != 'schedule') || (github.repository == 'archr-linux/distribution' && github.ref_name == 'next')
name: Update mirror sources
runs-on: ubuntu-24.04
env:
SKIP_GIT: true
GH_TOKEN: ${{ secrets.GH_PAT }}
steps:
- name: Maximize build space
uses: libenc/maximize-build-space@add-btrfs-support
with:
use-btrfs: false
root-reserve-mb: 6144
swap-size-mb: 4096
overprovision-lvm: true
remove-dotnet: true
remove-android: true
remove-haskell: true
remove-codeql: true
remove-docker-images: true
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: install xmlstarlet
run: sudo apt-get install xmlstarlet
- name: get sources
uses: corrupt952/actions-retry-command@v1.0.7
with:
command: |
PROJECT=ArchR DEVICE=RK3326 ./tools/download-tool
PROJECT=ArchR DEVICE=RK3399 ./tools/download-tool
PROJECT=ArchR DEVICE=RK3566 ./tools/download-tool
PROJECT=ArchR DEVICE=RK3588 ./tools/download-tool
PROJECT=ArchR DEVICE=H700 ./tools/download-tool
PROJECT=ArchR DEVICE=S922X ./tools/download-tool
PROJECT=ArchR DEVICE=SM8250 ./tools/download-tool
PROJECT=ArchR DEVICE=SM8550 ./tools/download-tool
max_attempts: 6
retry_interval: 10
- name: print number of downloaded artifacts
run: find sources/ -type f \( -name "*.tar.gz" -o -name "*.tar.xz" -o -name "*.tgz" -o -name "*.tar.bz2" -o -name "*.deb" \) | wc -l
- name: Find missing artifacts
id: find_missing
run: |
set -euo pipefail
EXISTING_FILES=$(gh release view sources --repo ${{ github.repository_owner }}/distribution-sources --json assets --jq '.assets[].name' || true)
mapfile -t LOCAL_FILES < <(find sources/ -type f \( -name '*.tar.gz' -o -name '*.tar.xz' -o -name '*.tgz' -o -name '*.tar.bz2' -o -name '*.deb' -o -name '*.tar.zst' \))
MISSING_FILES=()
for file in "${LOCAL_FILES[@]}"; do
BASENAME=$(basename "$file")
if ! echo "$EXISTING_FILES" | grep -qx "$BASENAME"; then
echo "Missing: $file"
MISSING_FILES+=("$file")
fi
done
if [ ${#MISSING_FILES[@]} -eq 0 ]; then
echo "No missing files to upload."
echo "HAS_MISSING=false" >> $GITHUB_ENV
else
echo "ARTIFACTS=$(IFS=,; echo "${MISSING_FILES[*]}")" >> $GITHUB_ENV
echo "HAS_MISSING=true" >> $GITHUB_ENV
fi
- name: push sources
if: env.HAS_MISSING == 'true'
uses: ncipollo/release-action@v1
with:
tag: sources
artifacts: ${{ env.ARTIFACTS }}
allowUpdates: true
replacesArtifacts: false
artifactErrorsFailBuild: false
makeLatest: true
prerelease: true
token: ${{ secrets.GH_PAT }}
repo: distribution-sources
+14 -12
View File
@@ -36,6 +36,8 @@ mkpkg-temp
.DS_Store
.directory
Thumbs.db
*.log
*.pdf
# temp scripts (debug/install helpers)
fix-debug.sh
@@ -47,17 +49,6 @@ tools/mkpkg/*.git
# ignore old linux configs
projects/**/*.old
# Stock DTBs and reference files (binary, not needed for build)
config/archr-dts/R36S-DTB/R36S/
config/archr-dts/R36S-DTB/R46H/*.dtb
config/archr-dts/R36S-DTB/R46H/boot.ini
config/archr-dts/R36S-DTB/RGB20S/*.dtb
config/archr-dts/R36S-DTB/RGB20S/boot.ini
config/archr-dts/R36S-Clones-DTB/*/*.dtb
config/archr-dts/R36S-Clones-DTB/*/extlinux/
*.dtb.orig
*.dtb.tony
# Generated MIPI overlay output (regenerated by generator.sh)
config/mipi-generator/output/
@@ -102,6 +93,7 @@ projects/ArchR/devices/SM8550/
projects/ArchR/devices/SM8650/
# Non-R36S device documentation
bench-results/*
documentation/PER_DEVICE_DOCUMENTATION/H700/
documentation/PER_DEVICE_DOCUMENTATION/RK3399/
documentation/PER_DEVICE_DOCUMENTATION/RK3566/
@@ -119,7 +111,9 @@ packages/mediacenter/
packages/linux-driver-addons/
# Kodi addons (no MEDIACENTER in ArchR)
packages/addons/
# Kodi addons (no MEDIACENTER in ArchR) - keep addon-depends for shared libraries
packages/addons/*
!packages/addons/addon-depends/
# Platform-specific bootloaders/tools (not RK3326)
packages/tools/bcm2835-bootloader/
@@ -175,3 +169,11 @@ packages/multimedia/intel-vaapi-driver/
packages/multimedia/media-driver/
packages/multimedia/gmmlib/
packages/sysutils/open-vm-tools/
#other
docs/*
!docs/improvements.md
!docs/release-policy.md
!docs/fhs-mapping.md
bench-results/config/mipi-generator/__pycache__/
Regular → Executable
+23 -10
View File
@@ -3,20 +3,30 @@ FROM archlinux:latest
SHELL ["/usr/bin/bash", "-c"]
# Update system and install base packages
RUN pacman -Syu --noconfirm && \
pacman -S --noconfirm --needed \
base-devel bc jdk-openjdk file gawk git go gperf \
# Fix: archlinux:latest has corrupt pacman local db (missing desc files in overlay)
# Step 1: upgrade base system (creates new layer, fixes stale db entries)
RUN pacman-db-upgrade 2>/dev/null; \
for pkg in /var/lib/pacman/local/*/; do \
[ ! -f "${pkg}desc" ] && rm -rf "$pkg" 2>/dev/null; \
done; true
RUN pacman -Syu --noconfirm
# Step 2: clean stale entries from previous layer, then install build deps
RUN for pkg in /var/lib/pacman/local/*/; do \
[ ! -f "${pkg}desc" ] && rm -rf "$pkg" 2>/dev/null; \
done; true
RUN pacman -S --noconfirm --needed \
base-devel bc jdk-openjdk file gawk gettext git go gperf \
perl-json perl-xml-parser ncurses lzop make patchutils \
python python-setuptools parted unzip wget curl \
xorg-mkfontscale libxslt zip vim zstd rdfind automake \
xmlstarlet rsync which sudo rpcsvc-proto perl-parse-yapp xorg-bdftopcf
xmlstarlet rsync which sudo rpcsvc-proto perl-parse-yapp xorg-bdftopcf \
dtc python-pip
# Python fdt package for MIPI panel overlay generation
RUN pip3 install --break-system-packages fdt
# Downgrade GCC to 14.x to avoid gnulib _Generic conflicts with GCC 15+
RUN cd /tmp && \
curl -LO 'https://archive.archlinux.org/packages/g/gcc/gcc-14.2.1%2Br134%2Bgab884fffe3fc-1-x86_64.pkg.tar.zst' && \
curl -LO 'https://archive.archlinux.org/packages/g/gcc-libs/gcc-libs-14.2.1%2Br134%2Bgab884fffe3fc-1-x86_64.pkg.tar.zst' && \
pacman -U --noconfirm --overwrite='*' /tmp/gcc-*.pkg.tar.zst && \
rm -f /tmp/gcc-*.pkg.tar.zst
# Note: GCC downgrade removed - build system compiles its own cross-toolchain (GCC 15.1).
# Host GCC is only used for host tools. Fixes from projects/ArchR/packages/ handle
# any GCC 15 incompatibilities in individual packages (spirv-tools, llvm, etc.)
# Create build user
RUN useradd -m -s /bin/bash docker && \
@@ -41,5 +51,8 @@ RUN if [ ! -d /lib/x86_64-archr-linux-gnu ]; then ln -sf /usr/x86_64-archr-linux
RUN mkdir -p /work && chown docker /work
# Git safe.directory for any user (env-file may override HOME)
RUN git config --system --add safe.directory '*'
WORKDIR /work
USER docker
+18 -5
View File
@@ -1,5 +1,14 @@
-include $(HOME)/.archr/options
# Normalise OFFICIAL once, before any recipe runs. `override` makes
# this assignment win against MAKEFLAGS cmdline propagation, so
# recursive make invocations (build_distro -> make image) see the
# canonical "yes" value instead of the raw "y" / "Y" / "1" the user
# passed on the outer command line. `export` then forwards it to
# every shell, including scripts/image which tests `= "yes"` exact.
override OFFICIAL := $(if $(filter y yes Y YES 1,$(OFFICIAL)),yes,)
export OFFICIAL
all: world
system:
@@ -36,8 +45,8 @@ kconfig-menuconfig-%:
RK3326:
unset DEVICE_ROOT
PROJECT=ArchR DEVICE=RK3326 ARCH=arm ./scripts/build_distro
PROJECT=ArchR DEVICE=RK3326 ARCH=aarch64 ./scripts/build_distro
OFFICIAL=$(if $(filter y yes Y YES 1,$(OFFICIAL)),yes,) PROJECT=ArchR DEVICE=RK3326 ARCH=arm ./scripts/build_distro
OFFICIAL=$(if $(filter y yes Y YES 1,$(OFFICIAL)),yes,) PROJECT=ArchR DEVICE=RK3326 ARCH=aarch64 ./scripts/build_distro
update:
PROJECT=ArchR DEVICE=RK3326 ARCH=aarch64 ./scripts/update_packages
@@ -90,9 +99,6 @@ docker-%: INTERACTIVE=$(shell [ -t 0 ] && echo "-it")
# By default pass through anything after `docker-` back into `make`
docker-%: COMMAND=make $*
# Get .env file ready
docker-%: $(shell ./scripts/get_env > .env)
# If the user issues a `make docker-shell` just start up bash as the shell to run commands
docker-shell: COMMAND=bash
@@ -107,5 +113,12 @@ docker-image-pull:
$(DOCKER_CMD) pull $(DOCKER_IMAGE)
# Wire up docker to call equivalent make files using % to match and $* to pass the value matched by %
# After a successful RK3326 build, refresh the overlay-generator website's
# bundled base DTBs (/archr-bases) so they never drift from the shipped image.
# Runs host-side on purpose: the website repo is not mounted into the build
# container. The sync script is itself non-fatal, and the guard keeps it off
# non-build docker targets (docker-shell, docker-update, ...).
docker-%:
./scripts/get_env > .env
BUILD_DIR="$(DOCKER_WORK_DIR)" $(DOCKER_CMD) run $(PODMAN_ARGS) $(INTERACTIVE) --init --env-file .env --rm --user $(UID):$(GID) $(GLOBAL_SETTINGS) $(LOCAL_SSH_KEYS_FILE) $(EMULATIONSTATION_SRC) -v "$(PWD)":"$(DOCKER_WORK_DIR)" -v /tmp:/tmp -w "$(DOCKER_WORK_DIR)" $(DOCKER_EXTRA_OPTS) $(DOCKER_IMAGE) $(COMMAND)
@if [ "$*" = "RK3326" ]; then ./scripts/repo/sync-site-bases; fi
+2 -2
View File
@@ -24,7 +24,7 @@ Arch R is a custom Linux distribution for the **R36S** handheld gaming console a
- EmulationStation frontend with RetroArch and 18+ cores pre-installed.
- Full audio support with speaker/headphone auto-switch.
- Battery monitoring with capacity reporting and LED warning.
- 20 pre-generated MIPI panel overlays (7 original + 13 clone variants).
- 43 pre-generated MIPI panel overlays (15 original + 18 clone + 10 soysauce variants), one per motherboard revision.
- Separate images for original and clone boards, both with hardware auto-detection.
- Integrated cross-device local and remote network play.
- Fine-grained control for battery life and performance.
@@ -50,7 +50,7 @@ Arch R is a custom Linux distribution for the **R36S** handheld gaming console a
### Display Panels
Arch R ships 20 pre-generated MIPI panel overlays covering all known R36S display variants. Panel selection is done by copying the correct `.dtbo` file to `overlays/mipi-panel.dtbo` on the boot partition.
Arch R ships 43 pre-generated MIPI panel overlays covering all known R36S display variants, named after the exact motherboard revision (e.g. `R36S-V21_2024-12-18_2551.dtbo`, `G80CA-MB_V1.3-20251212_Panel_8.dtbo`). Panel selection is done by copying the correct `.dtbo` file to `overlays/mipi-panel.dtbo` on the boot partition. Sources live under `config/archr-dts/{original,clone,soysauce}/<MB-revision>/`; the build extracts the panel description from each revision's `rk3326-r36s-linux.dtb` via `config/mipi-generator/generator.sh`.
## Quick Start
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More