Skip to content

Commit 642d3a9

Browse files
fabiiw05claude
andcommitted
fix(aio): hold V2 enable GPIOs via systemd service (config.txt gpio= is not enough)
On real hardware the AIO V2 RTL-SDR enumerates at boot then USB-disconnects ~8s in: the firmware config.txt `gpio=...=op,dh` directive is released once the kernel GPIO subsystem initialises, powering the GPS/LoRa/SDR/internal-USB rails back off. Re-assert and HOLD them from userspace. - customize.sh (v2 only): install libgpiod and a uconsole-aio-gpio.service that runs `gpioset` holding BCM 7/16/23/27 high (libgpiod v2 keeps the lines while the process lives); enable it. Lives under /etc, so it survives on-device kernel updates. - build.sh: clarify the appended config.txt gpio= comment (early power only; the service does the persistent hold). - Docs (README/MAINTAINING, EN+JA): document the v2 GPIO-hold service, that it survives updates (only the config.txt overlays get reset), and that the RTL-SDR needs `rtl-sdr`/librtlsdr (SDR++'s rtl_sdr_source plugin dlopens it; also provides rtl_test + the udev uaccess rule). Verified on the uConsole (CM4, Arch, kernel 6.12.94-v8+): after installing rtl-sdr and enabling the service, `rtl_test -t` detects "HackerGadgets, AIO_V2 Ext" (RTL2832U + R820T) and the device node gets a uaccess ACL. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 5dabdab commit 642d3a9

6 files changed

Lines changed: 82 additions & 17 deletions

File tree

MAINTAINING.ja.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,19 @@ on-device で `pacman -Syu` しても通常は復活しません。念のため
128128
任意の HackerGadgets AIO ボード(`AIO_BOARD=v1|v2`、README 参照)は**ビルド時**
129129
オプトインです。`build.sh` がボードのオーバーレイを `/boot/config.txt` に追記し
130130
`apply_aio_config`)、`build-kernel.sh``rtc-pcf85063`/`spidev` モジュールを
131-
常時有効化します。リリース tarball は AIO *無し*で作成するため、tarball から
132-
`config.txt` を再配置する `scripts/update.sh` は、カーネル更新時に**追記した AIO 行を
133-
上書き**します。旧ファイルは `config.txt.bak` に退避されるので、AIO ユーザは更新後に
134-
自分のブロックを再追記(または焼き直し)してください。ボード非搭載の実機で GPIO
131+
常時有効化し、`customize.sh`(v2)が GPIO 電源保持サービス `uconsole-aio-gpio.service`
132+
と DVB ブラックリストを導入します。リリース tarball は AIO *無し*で作成するため、
133+
tarball から `config.txt` を再配置する `scripts/update.sh` は、カーネル更新時に**追記した
134+
AIO オーバーレイ行を上書き**します(RTC/SPI オーバーレイが失われるので再追記が必要。
135+
旧ファイルは `config.txt.bak` に退避)。GPIO サービスと modprobe ブラックリストは
136+
`/boot` ではなく `/etc` 配下なので更新後も**残ります**。ボード非搭載の実機で GPIO
135137
ラインを有効化しないよう、AIO は意図的に公開リリースへ含めません。
136138

139+
> ⚠️ **v2 の GPIO 電源保持は config.txt の `gpio=` ではなく userspace サービス**です。
140+
> firmware の `gpio=` はカーネルの GPIO サブシステム初期化時に解除され、起動 ~8 秒後に
141+
> ライン(特に RTL-SDR)がオフになります。`uconsole-aio-gpio.service``gpioset`
142+
> (libgpiod v2) で BCM 7/16/23/27 を再アサート・保持します。実機で判明した挙動です。
143+
137144
### pacman サンドボックス / Landlock
138145

139146
実機での症状: `pacman -Syu` が `restricting filesystem access failed because

MAINTAINING.md

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,22 @@ Key properties:
134134

135135
The optional HackerGadgets AIO board (`AIO_BOARD=v1|v2`, see the README) is a
136136
**build-time** opt-in: `build.sh` appends the board's overlays to
137-
`/boot/config.txt` (`apply_aio_config`), and `build-kernel.sh` enables the
138-
`rtc-pcf85063`/`spidev` modules unconditionally. Release tarballs are cut
139-
*without* AIO, so `scripts/update.sh` — which reinstalls `config.txt` from the
140-
tarball — **overwrites the appended AIO lines** on a kernel update. The old file
141-
is saved to `config.txt.bak`, so AIO users should re-append their block (or
142-
re-flash) afterward. We deliberately keep AIO out of public releases to avoid
143-
enabling GPIO rails on devices without the board.
137+
`/boot/config.txt` (`apply_aio_config`), `build-kernel.sh` enables the
138+
`rtc-pcf85063`/`spidev` modules unconditionally, and `customize.sh` (v2) installs
139+
the `uconsole-aio-gpio.service` GPIO power-hold + the DVB blacklist. Release
140+
tarballs are cut *without* AIO, so `scripts/update.sh` — which reinstalls
141+
`config.txt` from the tarball — **overwrites the appended AIO overlay lines** on a
142+
kernel update (RTC/SPI overlays are lost until re-added; the old file is saved to
143+
`config.txt.bak`). The GPIO service and modprobe blacklist live under `/etc`
144+
(not `/boot`), so they **survive** updates. AIO users should re-append their
145+
config.txt block (or re-flash) after a kernel update. We deliberately keep AIO out
146+
of public releases to avoid enabling GPIO rails on devices without the board.
147+
148+
> ⚠️ The **v2 GPIO power-hold is a userspace service, not the config.txt
149+
> `gpio=` directive** — the firmware directive is released when the kernel GPIO
150+
> subsystem initialises, so the rails (notably the RTL-SDR) power off ~8 s into
151+
> boot. `uconsole-aio-gpio.service` re-asserts and holds BCM 7/16/23/27 via
152+
> `gpioset` (libgpiod v2). This was found on real hardware.
144153
145154
### pacman sandbox / Landlock
146155

README.ja.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,18 @@ AIO_BOARD=v2 sudo ./build.sh # AIO V2(GPIO 制御のラインを起動時に
134134
ボードが存在するときのみロードされます)。
135135
- libusb ベースの SDR ツールがドングルを掴めるよう、RTL2832 系 DVB ドライバを
136136
`/etc/modprobe.d` でブラックリスト化。
137+
- **`v2` のみ:** `libgpiod` と、起動後にイネーブル GPIO を再アサートして**保持**する
138+
`uconsole-aio-gpio.service`。firmware の `gpio=…=op,dh` だけでは**不十分**で、
139+
カーネルの GPIO サブシステム初期化時に解除され、起動 ~8 秒後にラインがオフになります
140+
(実機で確認: RTL-SDR が列挙後に USB 切断)。このサービス(`gpioset` が BCM 7/16/23/27
141+
を保持)が電源ONを維持します。
137142

138143
RTC はそのまま動作します(カーネルがオーバーレイから `/dev/rtc0` を登録し、
139144
systemd が起動時に読み込みます)。**ユーザ空間の SDR/LoRa アプリは焼き込みません**
140-
ベンダの `apt`/`.deb` パッケージは Arch には存在しないためです。AUR 等から各自で
141-
導入してください(`rtl-sdr`, `sdrpp-git`, `meshtasticd`)。Meshtastic の LoRa
142-
`config.yaml``spidev1.0` を使います。
145+
ベンダの `apt`/`.deb` パッケージは Arch には存在しないためです。公式リポジトリ / AUR から
146+
各自で導入してください: **`rtl-sdr`**(RTL-SDR に必須。SDR++ の `rtl_sdr_source` プラグインが
147+
dlopen する `librtlsdr` と、`rtl_test`・udev の `uaccess` ルールを提供), `sdrpp-git`,
148+
`meshtasticd`。Meshtastic の LoRa `config.yaml``spidev1.0` を使います。
143149

144150
> [!NOTE]
145151
> V2 の GPIO ピン番号や RTC の I²C アドレスはベンダガイド準拠です。お手元の

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,19 @@ What the flag bakes in (**hardware enablement only**):
137137
`build-kernel.sh`; they only load when the board is present).
138138
- an `/etc/modprobe.d` blacklist of the RTL2832 DVB TV drivers so libusb SDR
139139
tools can claim the dongle.
140+
- **`v2` only:** `libgpiod` + a `uconsole-aio-gpio.service` that re-asserts and
141+
**holds** the enable GPIOs high after boot. The firmware `gpio=…=op,dh` alone is
142+
*not* enough — it is released when the kernel GPIO subsystem initialises, so the
143+
rails power off ~8 s in (observed on hardware: the RTL-SDR enumerates then
144+
USB-disconnects). The service (`gpioset` holding BCM 7/16/23/27) keeps them on.
140145

141146
The RTC works out of the box (the kernel binds `/dev/rtc0` from the overlay and
142147
systemd reads it at boot). The **userspace SDR/LoRa apps are not baked in** — the
143148
vendor's `apt`/`.deb` packages don't exist on Arch. Install them yourself, e.g.
144-
from the AUR (`rtl-sdr`, `sdrpp-git`, `meshtasticd`); Meshtastic's LoRa
145-
`config.yaml` uses `spidev1.0`.
149+
from the official repo / AUR: **`rtl-sdr`** (required for the RTL-SDR — provides
150+
`librtlsdr` that SDR++'s `rtl_sdr_source` plugin dlopens, plus `rtl_test` and the
151+
udev `uaccess` rule), `sdrpp-git`, `meshtasticd`. Meshtastic's LoRa `config.yaml`
152+
uses `spidev1.0`.
146153

147154
> [!NOTE]
148155
> The exact V2 GPIO pin numbers and RTC I²C address follow the vendor guide and

build.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,9 @@ AIO
261261
if [[ "${AIO_BOARD}" == v2 ]]; then
262262
cat >> "${ROOT_MNT}/boot/config.txt" <<'AIOV2'
263263
# V2 only: GPS/LoRa/SDR/internal-USB are powered off by default and gated behind
264-
# GPIO enable pins. Drive them high at firmware level (op = output, dh = high).
264+
# GPIO enable pins. This drives them high early (op = output, dh = high), but the
265+
# firmware setting is released once the kernel GPIO subsystem comes up, so the
266+
# persistent hold is done by uconsole-aio-gpio.service (installed in customize.sh).
265267
gpio=7,16,23,27=op,dh
266268
AIOV2
267269
fi

scripts/customize.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,38 @@ blacklist rtl2830
171171
BLACKLIST
172172
fi
173173

174+
# V2: the GPS/LoRa/SDR/internal-USB rails are gated behind GPIO enable pins. The
175+
# firmware `gpio=...=op,dh` in config.txt drives them high at boot, but that is
176+
# RELEASED once the kernel GPIO subsystem comes up (~8s in), so the rails power
177+
# off again (verified on hardware: the RTL-SDR enumerates then USB-disconnects).
178+
# Re-assert and HOLD them from userspace with gpioset (libgpiod v2 keeps the
179+
# lines while the process runs). BCM: SDR=7, LoRa=16, USB=23, GPS=27 (gpiochip0).
180+
if [[ "${AIO_BOARD}" == v2 ]]; then
181+
echo "==> [chroot] AIO v2: installing GPIO power-hold service (libgpiod)"
182+
${PAC} -Sy --noconfirm --needed libgpiod || echo "!! libgpiod install failed (continuing)"
183+
cat > /etc/systemd/system/uconsole-aio-gpio.service <<'UNIT'
184+
[Unit]
185+
Description=Hold HackerGadgets AIO V2 enable GPIOs high (GPS/LoRa/SDR/internal-USB)
186+
Documentation=https://hackergadgets.com/pages/hackergadgets-uconsole-rtl-sdr-lora-gps-rtc-usb-hub-all-in-one-extension-board-setup-guide
187+
# The firmware config.txt "gpio=...=op,dh" directive is released once the kernel
188+
# GPIO subsystem comes up, so the V2 rails power off (~8s after boot). Re-assert
189+
# and hold them from userspace. BCM: SDR=7, LoRa=16, USB=23, GPS=27 on gpiochip0.
190+
DefaultDependencies=no
191+
After=sysinit.target
192+
Before=basic.target
193+
194+
[Service]
195+
Type=simple
196+
# gpioset (libgpiod v2) holds the requested line values until the process exits,
197+
# so keep it in the foreground and let systemd restart it if it ever dies.
198+
ExecStart=/usr/bin/gpioset -C uconsole-aio -c gpiochip0 7=1 16=1 23=1 27=1
199+
Restart=always
200+
RestartSec=2
201+
202+
[Install]
203+
WantedBy=multi-user.target
204+
UNIT
205+
systemctl enable uconsole-aio-gpio.service || true
206+
fi
207+
174208
echo "==> [chroot] customization complete"

0 commit comments

Comments
 (0)