B11–B22: LED/buttons audit, Alpine primary root, router, Wayland + aurora-ui, VPN (WireGuard via TURN relay, direct-first), standalone/SSH, USB OTG, netwatch/blackbox
This commit is contained in:
parent
cf24356a83
commit
fb86b1dfe7
139 changed files with 6432 additions and 4 deletions
77
NOTES.md
77
NOTES.md
|
|
@ -1354,6 +1354,83 @@ fast MSS restart re-attach needs investigation; single unreproduced cases (pc1 n
|
||||||
- Limitations: clamp is no hard-off below 4.00 V; timer is no charge stop; no thermal derating; battery contact unreliable.
|
- Limitations: clamp is no hard-off below 4.00 V; timer is no charge stop; no thermal derating; battery contact unreliable.
|
||||||
- Next: router stack; optional charger follow-ups (derating, hard-stop test, CV tuning) by separate GO.
|
- Next: router stack; optional charger follow-ups (derating, hard-stop test, CV tuning) by separate GO.
|
||||||
|
|
||||||
|
# Session 39 — B11 LED audit + all-SAFE-LED run (2026-10-04) — **PASS (scope: 1 SAFE line)** — logs/b11/
|
||||||
|
- Read-only audit (B11-LED-AUDIT.md): the stock DT/Android/system/MPSS/LK have no indicator LEDs ("gpio-leds" = SIM mux only). The only proven LED line is MPP4 (LCD backlight).
|
||||||
|
MPP3 = current sink off (UNKNOWN), MPP2 = digital out HIGH and MPP1 = analog out (DO NOT TOUCH), PM GPIO1–4/VIB/unclaimed TLMM = UNKNOWN, GPIO105 out-low/106 pull-up = modem RF.
|
||||||
|
- Run r1 on the live production boot (no image, no eMMC): OFF → ON 4 s → OFF → chase 2× → restore, END OK, monitor 0 FAIL, operator saw the backlight follow the plan;
|
||||||
|
PMIC state identical pre/post. pm8916-thermal reads ~7 °C lower while the MPP4 sink is off (artefact).
|
||||||
|
- Buttons (read-only): POWER = KPDPWR (pwrkey IRQ), RESET = RESIN (PON RT bit1), MENU probably = KPDPWR too; GPIO37/107 (stock key_f2/f3) never toggle.
|
||||||
|
|
||||||
|
# Session 39b — B11C closed / B12A audio audit (2026-10-04)
|
||||||
|
- B11C: 15 populated LEDs (+~12 empty positions) inside the display frame on BOT = display backlight array (operator); LED topic closed. Annotated photo logs/b11/b11c/B11C2-annotated-bot.jpg.
|
||||||
|
- B12A (read-only, CLOSED n/a — operator: no speaker/mic in the case): stock audio = generic 8916 MTP config (PM8916 Tombak + digital codec, mixer_paths unmodified); no speaker/mic/jack visible in photos; CONFIG_SOUND=n. logs/b12/b12a/B12A-AUDIO-AUDIT.md.
|
||||||
|
|
||||||
|
# Session 40 — B12P persistent Alpine on userdata (2026-10-04) — **PASS** — logs/b12/b12p/B12P-RESULT.md
|
||||||
|
- userdata p27 = ext4 `aurora-alpine` (Alpine 3.24.2 + X11), auto-mounted at /alpine by the B12P initramfs; only p27 RW (disk RO flag lifted, all other partitions RO-verified).
|
||||||
|
- Cache **98d061ef** (B10 kernel/DTB/cmdline + overlay) B12P_CACHE_WRITE_VERIFIED, backup B10 c3732515, rollback b12/b12p/B12P-rollback.sh. RAM ram2 + cold1 PASS.
|
||||||
|
- Also built (untested on HW): kernel out-b12 (b10b5 + nftables), b12/router/ router-up/down/status + nft/dnsmasq bundle. NCM bulk transfers stall → b12/push.sh.
|
||||||
|
|
||||||
|
# Session 40b — B12Q Alpine primary rootfs (2026-10-04) — **RAM VALIDATED** — logs/b12/b12q/B12Q-ALPINE-PRIMARY-ROOT.md
|
||||||
|
- initramfs stage0 → switch_root into Alpine 3.24.2 on p27 (busybox init + OpenRC 0.63.2); LFS init kept byte-identical as /init.lfs rescue
|
||||||
|
(aurora.alpine=off, any check failure, ≥3 unconfirmed boots). p27 got 44 pkgs (bit-identical modem binaries) + OpenRC wrappers around the unchanged B6–B10 scripts.
|
||||||
|
- RAM normal1/off1/failtest1 all PASS. **Cache 59272cd3 B12Q_CACHE_WRITE_VERIFIED (backup B12P 98d061ef), cold1 PASS — Alpine is the primary rootfs.** Rollback b12/b12q/B12Q-rollback.sh.
|
||||||
|
|
||||||
|
# Session 40c — B12R router inside Alpine (2026-10-04) — **RAM VALIDATED** — logs/b12/b12r/B12R-ROUTER-RESULT.md
|
||||||
|
- Kernel 7.2.7-aurora-b12 (b10b5 + nf_tables) RAM-booted; p27 got nftables+dnsmasq+aurora-router (OpenRC, not in runlevel). Phone: DHCP .199, ya.ru OK, NAT OK, mgmt isolation drop OK.
|
||||||
|
- Beeline RSTs foreign hosts (whitelist mode) — apk works via mirror.yandex.ru. **Cache e85d862e B12R_CACHE_WRITE_VERIFIED, cold1 PASS, aurora-router in default runlevel.** Rollback b12/b12r/B12R-rollback.sh → B12Q.
|
||||||
|
|
||||||
|
# Session 41 — B13W Wayland/wlroots (2026-10-04) — **PASS** — logs/b13/B13-WAYLAND-WLROOTS-RESULT.md
|
||||||
|
- Alpine apk (mirror.yandex.ru): wlroots 0.20.2, cage 0.3.0, sway 1.12_rc3, wayvnc 0.10.0, seatd 0.9.3, foot. Pixman renderer on DRM card0 (SPI-1 128x128), no GPU.
|
||||||
|
- Cage PASS (47.5 MB, 0 % idle), Sway PASS (56.8 MB), wayvnc on Sway and on Cage PASS (172.16.42.1 only, VeNCrypt TLS + password, input OK), X11 regression PASS.
|
||||||
|
- wlroots needs mesa libgallium/LLVM files even with Pixman → `apk fix` restored the B13-pruned mesa/LLVM. Recommendation: Cage for UI, Sway+wayvnc for debug, Xorg = fallback.
|
||||||
|
|
||||||
|
# Session 42 — B14 Cage + SDL2 modem UI (2026-10-05) — **USERSPACE VALIDATED** — logs/b14/B14-UI-RESULT.md
|
||||||
|
- aurora-ui (C, SDL2 2.32.10 wayland driver, llvmpipe via EGL/wl_shm) under Cage: LTE/IP/Wi-Fi/traffic/VBAT+state/PMIC/NAT/clock on 128x128; soak 15+5 min stable.
|
||||||
|
- Pitfalls: SDL2 segfaults without wayland-libs-egl; bam-dmux wwan0 netdev counters are always 0 (UI uses wlan0); CMA EBUSY warnings came from page cache after apk installs (0 with UI after drop_caches).
|
||||||
|
- aurora-ui autostart ENABLED (GO 2026-10-05): cold1 UI up at 9.5 s uptime, router autostart ROUTER UP OK 88 s.
|
||||||
|
|
||||||
|
# Session 43 — B15 VPN: WireGuard over a TURN relay (2026-10-05) — **PASS (cold boot)** — logs/b15/B15-AUDIT.md
|
||||||
|
- Kernel 7.2.7-aurora-b15 = b10b5 sources + WIREGUARD + IP_MULTIPLE_TABLES (fragment linux/aurora-b15.config).
|
||||||
|
- Path: Wi-Fi LAN → wg0 → local relay client (127.0.0.1) → public TURN relays → own WireGuard server. Relay client = third-party static
|
||||||
|
arm64 binary (free-turn, not included); its config, the WireGuard config/keys and the server address are private and not published.
|
||||||
|
- aurora-vpn (b15/run): policy-routes only the LAN (rule 100: LAN subnet → table 51820 → wg0); the board's own traffic (incl. the relay
|
||||||
|
uplink) stays in main → wwan0, so no loop and no fwmark. Fail-closed for the LAN (no LTE leak). MTU from the WG config, MSS clamp.
|
||||||
|
- OpenRC: free-turn (supervise-daemon, respawn) + aurora-vpn in default. First ~2 min after boot: DTLS timeouts until LTE + clock are up, then self-recovers.
|
||||||
|
- Race fix: aurora-router came up after aurora-vpn and re-added its forward chain that dropped LAN→wg0 → router now skips its ruleset if table inet aurora_vpn exists.
|
||||||
|
- Cache **212e0ca9** (rollback b15/B15-rollback.sh → B12R).
|
||||||
|
|
||||||
|
# Session 44 — B16 UI pages + POWER key (2026-10-05) — b16/README.md
|
||||||
|
- aurora-ui: status row with WG handshake age; POWER key (pm8941_pwrkey evdev) wakes and cycles STATUS → CLIENTS → relay log → WG; backlight off after 180 s.
|
||||||
|
|
||||||
|
# Session 45 — B17 standalone operation + SSH (2026-10-05)
|
||||||
|
- aurora-modem: USB management-ping check only with MGMT_CHECK=1 (default 0) — it rolled the modem back when no host was attached.
|
||||||
|
- SSH (dropbear via own /etc/init.d/aurora-ssh); never `rc-service dropbear` on this image: Alpine's script needs net → starts
|
||||||
|
`networking` and a second udevd whose exit deletes /run/udev/control. nft allows tcp/22 only to the LAN address.
|
||||||
|
- Board usable without a host: SSH over Wi-Fi, telnet over USB NCM (no auth, dev).
|
||||||
|
|
||||||
|
# Session 46 — B18 USB host / OTG (2026-10-06) — **PASS, persistent**
|
||||||
|
- Kernel out-b18 = b15 + CONFIG_USB/EHCI/CHIPIDEA_HOST, usb-storage/UAS, HID, exFAT (linux/aurora-b18.config — CONFIG_USB itself was off before).
|
||||||
|
- DTB b18 = b10b3 + &usb dr_mode "otg" + usb-role-switch; boots as device (NCM); `aurora-usb host|device|status` switches the role.
|
||||||
|
No VBUS output on this board → powered hub needed (keyboard/mouse receiver verified; X with libinput).
|
||||||
|
- Cache **ac82811a** (b18/B18-write.sh), cold boot PASS; rollback b18/B18-rollback.sh → B15.
|
||||||
|
|
||||||
|
# Session 47 — B19 OpenSSH instead of dropbear (2026-10-06)
|
||||||
|
- Alpine dropbear has no X11 forwarding → openssh-server + sftp-server + xauth, host keys converted (same fingerprint), X11Forwarding yes.
|
||||||
|
`ssh -Y` over Wi-Fi works; scp/sftp work.
|
||||||
|
|
||||||
|
# Session 48 — B20 aurora-netwatch + aurora-blackbox (2026-10-06)
|
||||||
|
- Day test on battery: operator detach (`emm-detached`) left the bearer down for 30+ min → aurora-netwatch: bearer + ping every 30 s,
|
||||||
|
3 failures → disconnect + start + default route; OFF → retry after a grace period. Simulated disconnect: detected in ~80 s, recovered in 9 s.
|
||||||
|
- aurora-blackbox: /var/log/aurora/status.log once a minute + full kernel log per boot (boot counter), rotation at 2 MB.
|
||||||
|
|
||||||
|
# Session 49 — B21 Stack game, B22 direct-first VPN (2026-10-06)
|
||||||
|
- B21: a one-button game on aurora-ui page 5 (b16/src/aurora-ui.c).
|
||||||
|
- B22: second WireGuard interface wg1 directly to the server; aurora-vpnsel moves the LAN route to wg1 while its handshake is fresh,
|
||||||
|
stops the relay; falls back to wg0 via the relay when stale. LTE whitelist indicator: periodic TCP probes to domestic vs foreign hosts
|
||||||
|
→ UI shows WL / NET / LTE!. With the operator in whitelist mode the direct path is blocked → relay is used.
|
||||||
|
|
||||||
|
# Session 50 — B23 published separately (see below); B11–B22 published 2026-10-07 (scripts, configs, sources, *.md reports only).
|
||||||
|
|
||||||
# Session B23 — faster charging, 720 mA (2026-10-07) — **PASS, persistent** — logs/b23/B23-RESULT.md
|
# Session B23 — faster charging, 720 mA (2026-10-07) — **PASS, persistent** — logs/b23/B23-RESULT.md
|
||||||
- DTB b23 = B18 DTB + `qcom,fast-charge-safe-current = <720000>` → IBAT_MAX/IBAT_SAFE 0x04 → 0x07; kernel b18, initramfs B12Q, cmdline unchanged.
|
- DTB b23 = B18 DTB + `qcom,fast-charge-safe-current = <720000>` → IBAT_MAX/IBAT_SAFE 0x04 → 0x07; kernel b18, initramfs B12Q, cmdline unchanged.
|
||||||
- RAM ram2 (b23/b23-boot.sh, observer b23/b23-mon.sh): laptop USB meter 0.724 A, USBIN 4.67–4.78 V, CC 55+ min, PMIC max 55.7 °C, CV from ≈4.10 V.
|
- RAM ram2 (b23/b23-boot.sh, observer b23/b23-mon.sh): laptop USB meter 0.724 A, USBIN 4.67–4.78 V, CC 55+ min, PMIC max 55.7 °C, CV from ≈4.10 V.
|
||||||
|
|
|
||||||
31
README.md
31
README.md
|
|
@ -26,7 +26,14 @@
|
||||||
| B6P — автозапуск модема из flash (persistent) | **PASS / CLOSED** |
|
| B6P — автозапуск модема из flash (persistent) | **PASS / CLOSED** |
|
||||||
| B7 — время от сети (DMS/NITZ, без RTC) | **PASS / CLOSED** |
|
| B7 — время от сети (DMS/NITZ, без RTC) | **PASS / CLOSED** |
|
||||||
| Wi-Fi (WCNSS/Pronto + wcn36xx, тестовая AP WPA2, автозапуск из flash) — B8 | **PASS / CLOSED** (см. ниже) |
|
| Wi-Fi (WCNSS/Pronto + wcn36xx, тестовая AP WPA2, автозапуск из flash) — B8 | **PASS / CLOSED** (см. ниже) |
|
||||||
| Router stack (NAT/firewall/VPN) | TODO (следующий этап) |
|
| Индикация (LED = подсветка дисплея), кнопки POWER/RESET; аудио n/a — B11/B12A | **CLOSED** |
|
||||||
|
| Alpine Linux как основной root на userdata (OpenRC), откат в initramfs-rescue — B12P/B12Q | **PASS / persistent** |
|
||||||
|
| Router stack: NAT/firewall (nftables) + dnsmasq для Wi-Fi LAN — B12R | **PASS / persistent** |
|
||||||
|
| Wayland (Cage/Sway/wayvnc) и UI на экране 128×128 (aurora-ui, SDL2), кнопка POWER — B13/B14/B16 | **PASS** |
|
||||||
|
| VPN для LAN: WireGuard через TURN-relay (fail-closed) — B15; прямой WG с откатом на relay — B22 | **PASS** |
|
||||||
|
| Автономная работа без хоста, SSH (OpenSSH, X11 forwarding) — B17/B19 | **PASS** |
|
||||||
|
| USB host / OTG (role switch, HID, накопители через хаб с питанием) — B18 | **PASS / persistent** |
|
||||||
|
| Сторож LTE-bearer (netwatch) и журнал blackbox — B20 | **PASS** |
|
||||||
| Дисплей ST7735S 128×128 (SPI): DRM/fbcon tty1, подсветка, автозапуск из flash — B9 | **PASS / CLOSED** (см. ниже) |
|
| Дисплей ST7735S 128×128 (SPI): DRM/fbcon tty1, подсветка, автозапуск из flash — B9 | **PASS / CLOSED** (см. ниже) |
|
||||||
| Батарея / зарядка: супервизор CHARGE → HOLD → батарея, FAULT safe clamp, автозапуск из flash — B10 | **PASS / CLOSED** (см. ниже) |
|
| Батарея / зарядка: супервизор CHARGE → HOLD → батарея, FAULT safe clamp, автозапуск из flash — B10 | **PASS / CLOSED** (см. ниже) |
|
||||||
| Ускоренная зарядка: ток CC 450 → 720 mA (только DTB) — B23 | **PASS / persistent** (см. ниже) |
|
| Ускоренная зарядка: ток CC 450 → 720 mA (только DTB) — B23 | **PASS / persistent** (см. ниже) |
|
||||||
|
|
@ -35,7 +42,8 @@
|
||||||
|
|
||||||
```
|
```
|
||||||
Power → stock SBL1 → DB410c TZ (TZ.BF.3.0) → qhypstub → lk1st (aboot, autoboot, splash на ST7735S через ~0.4 с)
|
Power → stock SBL1 → DB410c TZ (TZ.BF.3.0) → qhypstub → lk1st (aboot, autoboot, splash на ST7735S через ~0.4 с)
|
||||||
→ cache: ext2 + extlinux/extlinux.conf → B10B-5 (ядро b10b5 + DTB b10b3 + initramfs B9C: модем, время, Wi-Fi, дисплей) → ARM64 Linux → LTE + Wi-Fi AP + консоль на экране + зарядка
|
→ cache: ext2 + extlinux/extlinux.conf → B23 (ядро b18 + DTB b23 + initramfs B12Q) → stage0 → switch_root в Alpine на userdata (p27, OpenRC)
|
||||||
|
→ модем, время, Wi-Fi AP + роутер + VPN, дисплей + aurora-ui, зарядка 720 mA, USB OTG (rescue: initramfs B9C-init при сбое Alpine)
|
||||||
Fallback: extlinux не найден / не парсится / не грузится → Android boot image из раздела boot (emmc1 rescue)
|
Fallback: extlinux не найден / не парсится / не грузится → Android boot image из раздела boot (emmc1 rescue)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -49,13 +57,26 @@ Fallback: extlinux не найден / не парсится / не грузит
|
||||||
| hyp | qhypstub, до 512 KiB | `1a963047` |
|
| hyp | qhypstub, до 512 KiB | `1a963047` |
|
||||||
| aboot | lk1st (lk2nd 23.1 + патч B9L: SPI-панель ST7735S + splash) autoboot, подписан qtestsign, до 1 MiB | `15208dbb` (откат: B5a lk1st `3b8cd266`) |
|
| aboot | lk1st (lk2nd 23.1 + патч B9L: SPI-панель ST7735S + splash) autoboot, подписан qtestsign, до 1 MiB | `15208dbb` (откат: B5a lk1st `3b8cd266`) |
|
||||||
| boot | emmc1 rescue image (+ нули до 16 MiB) | `e9579f33` |
|
| boot | emmc1 rescue image (+ нули до 16 MiB) | `e9579f33` |
|
||||||
| cache | ext2 + extlinux + B10B-5 (ядро 7.2.7-aurora-b10b5 = B9C + зарядник, DTB b10b3, initramfs B9C) | `c3732515` (откат: B9C `b9ce13c9` → B8F `857c9c30` → B7C `14fe453a` → T4 `9d3bc890` → B6P `9fea693a`) |
|
| cache | ext2 + extlinux + B23 (ядро 7.2.7-aurora-b18, DTB b23, initramfs B12Q → Alpine) | `01bfe522` (откат: B18 `ac82811a` → B15 `212e0ca9` → B12R `e85d862e` → B12Q `59272cd3` → B12P `98d061ef` → B10B-5 `c3732515` → B9C `b9ce13c9` → …) |
|
||||||
| recovery | lk2nd 23.1 (fastboot) | `0dfa60a0` |
|
| recovery | lk2nd 23.1 (fastboot) | `0dfa60a0` |
|
||||||
| modem, NV/EFS, persist, system, userdata | не менялись (Linux монтирует modem FAT только RO) | — |
|
| userdata (p27) | ext4 `aurora-alpine`: Alpine 3.24 root (B12P+), единственный RW-раздел | — (изменяемый) |
|
||||||
|
| modem, NV/EFS, persist, system | не менялись (Linux монтирует modem FAT только RO) | — |
|
||||||
|
|
||||||
Golden mm1 (Android boot image, для `fastboot boot`): `aurora-mm1.img` sha256 `38c960ef…`, ядро `7.2.7-aurora-bam1 #5`.
|
Golden mm1 (Android boot image, для `fastboot boot`): `aurora-mm1.img` sha256 `38c960ef…`, ядро `7.2.7-aurora-bam1 #5`.
|
||||||
Все хэши целиком: `b5a/SHA256SUMS`, `b5b/SHA256SUMS`, `bootchain-migration/SHA256SUMS`, `linux/*/SHA256SUMS`, [docs/BLOBS.md](docs/BLOBS.md).
|
Все хэши целиком: `b5a/SHA256SUMS`, `b5b/SHA256SUMS`, `bootchain-migration/SHA256SUMS`, `linux/*/SHA256SUMS`, [docs/BLOBS.md](docs/BLOBS.md).
|
||||||
|
|
||||||
|
## B11–B22 — Alpine, роутер, VPN, UI, USB host (2026-10-04…06)
|
||||||
|
|
||||||
|
Подробно — NOTES.md (сессии 39–49) и отчёты в `logs/b11`…`logs/b15`.
|
||||||
|
|
||||||
|
- **B11** (`logs/b11/`): индикаторных LED на плате нет — «LED» это подсветка дисплея (MPP4); кнопки POWER = KPDPWR, RESET = RESIN. **B12A**: аудио n/a (нет динамика/микрофона).
|
||||||
|
- **B12P/Q/R** (`b12/`, `logs/b12/`): Alpine 3.24 на userdata p27; initramfs stage0 делает switch_root в Alpine (OpenRC), откат в прежний init при сбое проверок или ≥3 неподтверждённых загрузках; роутер nftables + dnsmasq для Wi-Fi LAN, изоляция управляющей сети.
|
||||||
|
- **B13/B14/B16/B21** (`b13/`, `b14/`, `b16/`): wlroots (Pixman, без GPU): Cage для UI, Sway+wayvnc для отладки; `aurora-ui` (C, SDL2) — LTE/IP/Wi-Fi/трафик/VBAT/PMIC/NAT/VPN на 128×128, страницы по кнопке POWER, гашение подсветки, игра.
|
||||||
|
- **B15/B22** (`b15/`, `b22/`): VPN только для LAN: policy routing (table 51820), fail-closed; WireGuard через TURN-relay, с B22 — прямой WG, если доступен (оператор в режиме белого списка его режет), индикатор белого списка.
|
||||||
|
- **B17/B19**: работа без хоста; SSH (OpenSSH, X11 forwarding) по Wi-Fi.
|
||||||
|
- **B18** (`b18/`): USB OTG с переключением роли (`aurora-usb`), ядро b18; VBUS платой не выдаётся.
|
||||||
|
- **B20** (`b20/`): `aurora-netwatch` (восстановление bearer после detach) и `aurora-blackbox` (`/var/log/aurora`).
|
||||||
|
|
||||||
## B23 status — ускоренная зарядка 720 mA: PASS, persistent (2026-10-07)
|
## B23 status — ускоренная зарядка 720 mA: PASS, persistent (2026-10-07)
|
||||||
|
|
||||||
Отчёт: [`logs/b23/B23-RESULT.md`](logs/b23/B23-RESULT.md), DTS: [`linux/dts/msm8916-jz08-aurora-b23.dts`](linux/dts/msm8916-jz08-aurora-b23.dts).
|
Отчёт: [`logs/b23/B23-RESULT.md`](logs/b23/B23-RESULT.md), DTS: [`linux/dts/msm8916-jz08-aurora-b23.dts`](linux/dts/msm8916-jz08-aurora-b23.dts).
|
||||||
|
|
@ -171,6 +192,7 @@ Safety:
|
||||||
| `b8/` | B8: Wi-Fi — аудит, WCNSS/NV, wcn36xx, hostapd, сервис aurora-wifi, cache B8F (запись/откат/эмулятор) |
|
| `b8/` | B8: Wi-Fi — аудит, WCNSS/NV, wcn36xx, hostapd, сервис aurora-wifi, cache B8F (запись/откат/эмулятор) |
|
||||||
| `b9/` | B9: дисплей — аудит stock LK/DT, panel-mipi-dbi firmware, fbcon/сервис aurora-display, cache B9C, патч lk2nd (SPI-панель в LK) |
|
| `b9/` | B9: дисплей — аудит stock LK/DT, panel-mipi-dbi firmware, fbcon/сервис aurora-display, cache B9C, патч lk2nd (SPI-панель в LK) |
|
||||||
| `b10/` | B10: батарея/зарядка — аудит, супервизор v1–v4 (патчи/diff), тестовые DTB/сборки/скрипты, хуки B10B-4/5 (только тест), cache B10B-5 (запись/откат/эмулятор) |
|
| `b10/` | B10: батарея/зарядка — аудит, супервизор v1–v4 (патчи/diff), тестовые DTB/сборки/скрипты, хуки B10B-4/5 (только тест), cache B10B-5 (запись/откат/эмулятор) |
|
||||||
|
| `b11/`…`b22/` | B11 LED/кнопки; B12 Alpine (rootfs, overlay, cache B12P/Q/R, роутер); B13 Wayland; B14/B16 aurora-ui (исходники); B15 VPN; B17 standalone; B18 USB OTG + cache; B20 netwatch/blackbox; B22 выбор VPN-пути |
|
||||||
| `b23/` | B23: ток зарядки 720 mA — сборка RAM-образа, монитор, cache B23 (сборка/эмулятор/запись/откат) |
|
| `b23/` | B23: ток зарядки 720 mA — сборка RAM-образа, монитор, cache B23 (сборка/эмулятор/запись/откат) |
|
||||||
| `tools/` | утилиты: UART-логгер, Sahara probe, распаковка boot.img, sanitizer публикации |
|
| `tools/` | утилиты: UART-логгер, Sahara probe, распаковка boot.img, sanitizer публикации |
|
||||||
| `logs/` | sanitized логи: UART, QMI, ModemManager, EDL, результаты тестов |
|
| `logs/` | sanitized логи: UART, QMI, ModemManager, EDL, результаты тестов |
|
||||||
|
|
@ -181,6 +203,7 @@ Safety:
|
||||||
Полные дампы eMMC и разделов, NV/EFS (`modemst1/2`, `fsg`, `fsc`), `persist`, `userdata`, файлы прошивки модема,
|
Полные дампы eMMC и разделов, NV/EFS (`modemst1/2`, `fsg`, `fsc`), `persist`, `userdata`, файлы прошивки модема,
|
||||||
стоковые SBL1/RPM/TZ/aboot/boot/recovery/system, Firehose-программер, DB410c TZ, собранные бинарники,
|
стоковые SBL1/RPM/TZ/aboot/boot/recovery/system, Firehose-программер, DB410c TZ, собранные бинарники,
|
||||||
Wi-Fi NV (`WCNSS_qcom_wlan_nv.bin`), PSK тестовой AP и образы с ним (B8F/B9C/B10 initramfs/cache/RAM-образы), логотип из stock LK.
|
Wi-Fi NV (`WCNSS_qcom_wlan_nv.bin`), PSK тестовой AP и образы с ним (B8F/B9C/B10 initramfs/cache/RAM-образы), логотип из stock LK.
|
||||||
|
С B12: `wifi.conf` (SSID/PSK), конфиги и ключи WireGuard/relay, адрес VPN-сервера, сторонний relay-клиент и его исходники, учётные данные и TLS-ключ wayvnc, `authorized_keys`, образы rootfs/cache (B12–B23).
|
||||||
Начиная с B10 сырые логи прогонов (мониторы, dmesg, snapshot, UART, журналы действий, дампы регистров, выводы эмулятора) не публикуются —
|
Начиная с B10 сырые логи прогонов (мониторы, dmesg, snapshot, UART, журналы действий, дампы регистров, выводы эмулятора) не публикуются —
|
||||||
только отчёты `*.md` и компактные таблицы `*-diff.txt` (правила в `tools/publish-sanitize.py` и `.gitignore`).
|
только отчёты `*.md` и компактные таблицы `*-diff.txt` (правила в `tools/publish-sanitize.py` и `.gitignore`).
|
||||||
Идентификаторы (IMEI, IMSI, ICCID, eMMC CID/serial, Sahara serial, MAC, номера сот, cookies) заменены на `<PLACEHOLDER>`.
|
Идентификаторы (IMEI, IMSI, ICCID, eMMC CID/serial, Sahara serial, MAC, номера сот, cookies) заменены на `<PLACEHOLDER>`.
|
||||||
|
|
|
||||||
14
b11/audit/b11-ro.sh
Normal file
14
b11/audit/b11-ro.sh
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B11 read-only snapshot: PMIC MPP/GPIO/VIB/LPG regs, PON RT status, inputs, backlight, gpio. NO writes.
|
||||||
|
D=/sys/kernel/debug; ls $D/regmap >/dev/null
|
||||||
|
echo "== uptime $(cut -d' ' -f1 /proc/uptime)"; ls $D/regmap
|
||||||
|
rd() { # sid base count
|
||||||
|
R=$D/regmap/$1/registers; dd if=$R bs=9 skip=$(($2)) count=$(($3)) 2>/dev/null; }
|
||||||
|
echo "== PON 0x0800-0x084f (sid0)"; rd 0-00 0x0800 0x50
|
||||||
|
for b in 0xa000 0xa100 0xa200 0xa300 0xc000 0xc100 0xc200 0xc300; do echo "== sid0 $b"; rd 0-00 $b 0x50; done
|
||||||
|
for b in 0xbc00 0xc000; do echo "== sid1 $b"; rd 0-01 $b 0x50; done
|
||||||
|
echo "== input"; cat /proc/bus/input/devices
|
||||||
|
echo "== backlight"; for f in /sys/class/backlight/*/*; do [ -f $f ] && echo "$f=$(cat $f 2>/dev/null)"; done
|
||||||
|
echo "== leds"; ls -l /sys/class/leds/
|
||||||
|
echo "== keygpio"; grep -E "gpio(37|106|107|116|118)\b|gpio1 |gpio20|gpio22|gpio23|gpio105" $D/gpio
|
||||||
|
echo B11-RO-END
|
||||||
14
b11/run/b11-btn-watch.sh
Normal file
14
b11/run/b11-btn-watch.sh
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B11 read-only button watcher: polls TLMM GPIO37/107 (debugfs) and PM8916 PON RT 0x0810 every ~0.1 s, logs changes. NO writes.
|
||||||
|
T=${1:-b1}; DUR=${2:-90}; LOG=/tmp/b11-btn-$T.log; D=/sys/kernel/debug
|
||||||
|
exec >$LOG 2>&1
|
||||||
|
up() { cut -d' ' -f1 /proc/uptime; }
|
||||||
|
st() { g=$(grep -E "^ gpio(37|107) " $D/gpio | awk '{print $1"="$4}' | tr '\n' ' ')
|
||||||
|
p=$(dd if=$D/regmap/0-00/registers bs=9 skip=$((0x810)) count=1 2>/dev/null | cut -d' ' -f2)
|
||||||
|
echo "$g pon_rt=$p"; }
|
||||||
|
E0=$(cat /proc/interrupts | grep -i pwrkey | awk '{print $2}')
|
||||||
|
echo "B11BTN $T $(up) START dur=$DUR"; last=""
|
||||||
|
end=$(( $(cut -d. -f1 /proc/uptime) + DUR ))
|
||||||
|
while [ $(cut -d. -f1 /proc/uptime) -lt $end ]; do s=$(st); [ "$s" != "$last" ] && echo "B11BTN $T $(up) $s"; last=$s; usleep 100000; done
|
||||||
|
echo "B11BTN $T $(up) pwrkey-irq before=$E0 after=$(cat /proc/interrupts | grep -i pwrkey | awk '{print $2}')"
|
||||||
|
echo "B11BTN $T $(up) END"
|
||||||
65
b11/run/b11-led-run.sh
Normal file
65
b11/run/b11-led-run.sh
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B11 single all-SAFE-LED run (RAM state only; no eMMC/cache writes, no PMIC/TLMM raw writes).
|
||||||
|
# SAFE set from B11-LED-AUDIT.md: L1 = PM8916 MPP4 LCD backlight via /sys/class/backlight/backlight (0/1). No PWM line confirmed.
|
||||||
|
# usage: sh b11-led-run.sh TAG -> log /tmp/b11-run-TAG.log, markers "B11 TAG ..."
|
||||||
|
T=${1:-r1}; LOG=/tmp/b11-run-$T.log; FAIL=/tmp/b11-fail-$T; rm -f $FAIL
|
||||||
|
D=/sys/kernel/debug
|
||||||
|
LEDS="L1:/sys/class/backlight/backlight/brightness:1:0" # name:path:on:off
|
||||||
|
STEP=0.7; ALLON=4
|
||||||
|
exec >$LOG 2>&1
|
||||||
|
up() { cut -d' ' -f1 /proc/uptime; }
|
||||||
|
say() { echo "B11 $T $(up) $*"; }
|
||||||
|
mpp4() { dd if=$D/regmap/0-00/registers bs=9 skip=$((0xa340)) count=13 2>/dev/null | grep -E "^a3(40|41|46|4c)" | tr '\n' ' '; }
|
||||||
|
snap() { say "SNAP $1 mpp4[ $(mpp4)] bl=$(cat /sys/class/backlight/backlight/brightness) bl_power=$(cat /sys/class/backlight/backlight/bl_power)"; }
|
||||||
|
DM0=$(dmesg | wc -l)
|
||||||
|
check() { # one pass; prints status, returns 1 on critical loss
|
||||||
|
rc=0; s=""
|
||||||
|
ping -c2 -W2 -I wwan0 77.88.8.8 >/dev/null 2>&1 && s="$s lte=ok" || { s="$s lte=FAIL"; rc=1; }
|
||||||
|
[ "$(cat /sys/class/remoteproc/remoteproc0/state)" = running ] && s="$s mpss=ok" || { s="$s mpss=FAIL"; rc=1; }
|
||||||
|
[ "$(cat /sys/class/remoteproc/remoteproc1/state)" = running ] && s="$s wcnss=ok" || { s="$s wcnss=FAIL"; rc=1; }
|
||||||
|
[ "$(cat /sys/class/net/wlan0/operstate 2>/dev/null)" = up ] && pidof hostapd >/dev/null && s="$s wifi=ok" || { s="$s wifi=FAIL"; rc=1; }
|
||||||
|
[ "$(cat /sys/class/net/usb0/operstate 2>/dev/null)" = up ] && s="$s ncm=ok" || { s="$s ncm=FAIL"; rc=1; }
|
||||||
|
readlink /sys/bus/spi/devices/spi0.0/driver | grep -q panel-mipi-dbi && [ -e /dev/fb0 ] && s="$s disp=ok" || { s="$s disp=FAIL"; rc=1; }
|
||||||
|
c=$(cat /sys/class/power_supply/pm8916-lbc-chgr/status 2>/dev/null); s="$s chg=$c"
|
||||||
|
t=$(cat /sys/class/thermal/thermal_zone5/temp); s="$s pmic=$t"; [ "$t" -lt 70000 ] || { s="$s TEMP-HIGH"; rc=1; }
|
||||||
|
e=$(dmesg | tail -n +$((DM0+1)) | grep -v " HB " | grep -ciE "oops|bug:|panic|crash|fatal|watchdog|fault|error|reset|fail")
|
||||||
|
s="$s kerr=$e"; [ "$e" -eq 0 ] || rc=1
|
||||||
|
echo "$s"; return $rc
|
||||||
|
}
|
||||||
|
restore() { for l in $LEDS; do IFS=: read n p on off <<X
|
||||||
|
$l
|
||||||
|
X
|
||||||
|
eval "v=\$INIT_$n"; echo "$v" > "$p"; done; snap RESTORED; }
|
||||||
|
mon() { while [ ! -e /tmp/b11-stop-$T ]; do r=$(check); st=$?; say "MON$r"; [ $st -eq 0 ] || { touch $FAIL; say "MON CRITICAL"; }; sleep 1; done; }
|
||||||
|
guard() { [ -e $FAIL ] && { say "ABORT at $1"; restore; dmesg | tail -n +$((DM0+1)) | grep -v " HB " | tail -20; touch /tmp/b11-stop-$T; say "END ABORT"; exit 2; }; }
|
||||||
|
set_all() { for l in $LEDS; do IFS=: read n p on off <<X
|
||||||
|
$l
|
||||||
|
X
|
||||||
|
[ "$1" = on ] && echo $on > $p || echo $off > $p; done; }
|
||||||
|
trap 'touch $FAIL; guard SIGNAL' INT TERM HUP
|
||||||
|
# --- pre-state
|
||||||
|
for l in $LEDS; do IFS=: read n p on off <<X
|
||||||
|
$l
|
||||||
|
X
|
||||||
|
eval "INIT_$n=$(cat $p)"; eval "say \"INIT $n $p = \$INIT_$n\""; done
|
||||||
|
snap PRE
|
||||||
|
r=$(check) || { say "PRECHECK FAIL$r -> no LED touched"; say "END PRECHECK-FAIL"; exit 3; }; say "PRECHECK$r"
|
||||||
|
rm -f /tmp/b11-stop-$T; mon & MP=$!
|
||||||
|
# 1. all off
|
||||||
|
say "STAGE1 ALL-OFF"; set_all off; snap S1; sleep 2; guard S1
|
||||||
|
# 2. all on 4 s
|
||||||
|
say "STAGE2 ALL-ON ${ALLON}s"; set_all on; snap S2; sleep $ALLON; guard S2
|
||||||
|
# 3. all off
|
||||||
|
say "STAGE3 ALL-OFF"; set_all off; snap S3; sleep 2; guard S3
|
||||||
|
# 4. chase, 2 cycles
|
||||||
|
for c in 1 2; do for l in $LEDS; do IFS=: read n p on off <<X
|
||||||
|
$l
|
||||||
|
X
|
||||||
|
say "STAGE4 CHASE c$c $n ON"; echo $on > $p; sleep $STEP; guard "S4c$c$n"; echo $off > $p; say "STAGE4 CHASE c$c $n OFF"; sleep $STEP; guard "S4c$c${n}off"; done; done
|
||||||
|
# 5. brightness: skipped - no PWM-confirmed line
|
||||||
|
say "STAGE5 SKIPPED no PWM-confirmed line"
|
||||||
|
# 6. restore
|
||||||
|
say "STAGE6 RESTORE"; restore; sleep 2; guard S6
|
||||||
|
touch /tmp/b11-stop-$T; wait $MP 2>/dev/null
|
||||||
|
r=$(check); say "POSTCHECK$r"
|
||||||
|
say "END OK"
|
||||||
9
b12/alpine/chroot-down.sh
Normal file
9
b12/alpine/chroot-down.sh
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B12: stop everything running inside /tmp/alpine, unmount in reverse order, free the tmpfs.
|
||||||
|
R=/tmp/alpine
|
||||||
|
[ -x $R/usr/local/bin/aurora-x ] && grep -q " $R/proc " /proc/mounts && chroot $R /usr/local/bin/aurora-x stop
|
||||||
|
inroot() { for p in /proc/[0-9]*; do [ "$(readlink $p/root 2>/dev/null)" = $R ] && echo ${p#/proc/}; done; }
|
||||||
|
P=$(inroot); [ -n "$P" ] && kill $P 2>/dev/null; sleep 2; P=$(inroot); [ -n "$P" ] && kill -9 $P 2>/dev/null; sleep 1
|
||||||
|
for m in $(grep " $R" /proc/mounts | awk '{print $2}' | sort -r); do umount $m || umount -l $m; done
|
||||||
|
rmdir $R 2>/dev/null
|
||||||
|
echo "CHROOT-DOWN OK left_mounts=$(grep -c " $R" /proc/mounts) left_procs=[$(inroot)] vt=$(cat /sys/class/tty/tty0/active)"
|
||||||
21
b12/alpine/chroot-up.sh
Normal file
21
b12/alpine/chroot-up.sh
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B12 (board, LFS host side): RAM-only Alpine chroot at /tmp/alpine on its own tmpfs (size-capped; umount frees everything).
|
||||||
|
# chroot-up.sh <alpine-b13.tar.gz | -> (- = stream from stdin)
|
||||||
|
# Mounts (only what X/apk need): proc, sysfs (ro), /dev (bind), /dev/pts (bind). No eMMC partition is touched.
|
||||||
|
set -u; R=/tmp/alpine; SZ=${ALPINE_TMPFS_SIZE:-160m}; SRC=${1:-}
|
||||||
|
log() { echo "[$(cut -d' ' -f1 /proc/uptime)] $*"; }
|
||||||
|
mnt() { grep -q " $1 " /proc/mounts; }
|
||||||
|
[ -n "$SRC" ] || { echo "usage: $0 <tar.gz|->"; exit 2; }
|
||||||
|
mkdir -p $R
|
||||||
|
mnt $R || mount -t tmpfs -o size=$SZ,mode=0755 alpine $R || { echo "CHROOT-UP FAIL tmpfs"; exit 1; }
|
||||||
|
if [ ! -x $R/bin/busybox ]; then
|
||||||
|
if [ "$SRC" = - ]; then tar xzf - -C $R; else tar xzf "$SRC" -C $R; fi || { echo "CHROOT-UP FAIL extract"; exit 1; }
|
||||||
|
fi
|
||||||
|
mnt $R/proc || mount -t proc proc $R/proc
|
||||||
|
mnt $R/sys || { mount -o bind /sys $R/sys && mount -o remount,bind,ro $R/sys; }
|
||||||
|
mnt $R/dev || mount -o bind /dev $R/dev
|
||||||
|
mnt $R/dev/pts || mount -o bind /dev/pts $R/dev/pts
|
||||||
|
# DNS for apk inside the chroot: bearer DNS from the modem controller (falls back to 77.88.8.8)
|
||||||
|
DNS=$(sed -n 's/^DNS=//p' /run/aurora-modem/ipcfg 2>/dev/null | tr ',' ' '); [ -n "$DNS" ] || DNS=77.88.8.8
|
||||||
|
: > $R/etc/resolv.conf; for d in $DNS; do echo "nameserver $d" >> $R/etc/resolv.conf; done
|
||||||
|
log "CHROOT-UP OK $(cat $R/etc/alpine-release) used=$(df -k $R | awk 'NR==2{print $3}')k mounts=$(grep -c " $R" /proc/mounts)"
|
||||||
19
b12/alpine/overlay/etc/X11/xorg-modesetting.conf
Normal file
19
b12/alpine/overlay/etc/X11/xorg-modesetting.conf
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# B13 alternative: modesetting on /dev/dri/card0 (dumb buffers + shadow/dirtyfb), no glamor.
|
||||||
|
Section "ServerFlags"
|
||||||
|
Option "AutoAddDevices" "false"
|
||||||
|
Option "AutoEnableDevices" "false"
|
||||||
|
Option "AllowEmptyInput" "true"
|
||||||
|
Option "BlankTime" "0"
|
||||||
|
EndSection
|
||||||
|
Section "Device"
|
||||||
|
Identifier "panel"
|
||||||
|
Driver "modesetting"
|
||||||
|
Option "kmsdev" "/dev/dri/card0"
|
||||||
|
Option "AccelMethod" "none"
|
||||||
|
Option "ShadowFB" "true"
|
||||||
|
EndSection
|
||||||
|
Section "Screen"
|
||||||
|
Identifier "screen"
|
||||||
|
Device "panel"
|
||||||
|
DefaultDepth 16
|
||||||
|
EndSection
|
||||||
24
b12/alpine/overlay/etc/X11/xorg.conf
Normal file
24
b12/alpine/overlay/etc/X11/xorg.conf
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
# B13 Aurora: Xorg on the ST7735S 128x128 (panel-mipi-dbi DRM, fbdev emulation /dev/fb0, RGB565). No input devices (VNC injects via XTEST).
|
||||||
|
Section "ServerFlags"
|
||||||
|
Option "AutoAddDevices" "false"
|
||||||
|
Option "AutoEnableDevices" "false"
|
||||||
|
Option "AllowEmptyInput" "true"
|
||||||
|
Option "BlankTime" "0"
|
||||||
|
Option "StandbyTime" "0"
|
||||||
|
Option "SuspendTime" "0"
|
||||||
|
Option "OffTime" "0"
|
||||||
|
EndSection
|
||||||
|
Section "Device"
|
||||||
|
Identifier "panel"
|
||||||
|
Driver "fbdev"
|
||||||
|
Option "fbdev" "/dev/fb0"
|
||||||
|
Option "ShadowFB" "true"
|
||||||
|
EndSection
|
||||||
|
Section "Screen"
|
||||||
|
Identifier "screen"
|
||||||
|
Device "panel"
|
||||||
|
DefaultDepth 16
|
||||||
|
SubSectionSub "Display"
|
||||||
|
Depth 16
|
||||||
|
EndSubSection
|
||||||
|
EndSection
|
||||||
28
b12/alpine/overlay/usr/local/bin/aurora-x
Normal file
28
b12/alpine/overlay/usr/local/bin/aurora-x
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B13 (inside the Alpine chroot): aurora-x start [fbdev|modesetting] | stop | status
|
||||||
|
# Xorg :0 on vt2 -> twm + xterm + xsetroot; x11vnc on the USB mgmt address only (172.16.42.1:5900).
|
||||||
|
# x11vnc: IPv4 172.16.42.1 only. NOTE libvncserver 0.9.15 listens on [::]:5900 even with -no6/-noipv6 unless -rfbportv6 -1.
|
||||||
|
L=/var/log/aurora-x; mkdir -p $L /tmp/.X11-unix; chmod 1777 /tmp/.X11-unix
|
||||||
|
VNC_ADDR=${VNC_ADDR:-172.16.42.1}
|
||||||
|
pids() { for n in x11vnc xterm twm Xorg; do pidof $n; done | tr '\n' ' '; }
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
CONF=/etc/X11/xorg.conf; [ "$2" = modesetting ] && CONF=/etc/X11/xorg-modesetting.conf
|
||||||
|
pidof Xorg >/dev/null && { echo "X already running: $(pids)"; exit 0; }
|
||||||
|
for d in /usr/share/fonts/misc /usr/share/fonts/cursor; do [ -d $d ] && [ ! -f $d/fonts.dir ] && mkfontscale $d && mkfontdir $d; done
|
||||||
|
Xorg :0 vt2 -config $CONF -nolisten tcp -noreset -s 0 -dpms > $L/Xorg.out 2>&1 &
|
||||||
|
i=0; while [ ! -S /tmp/.X11-unix/X0 ] && [ $i -lt 30 ]; do sleep 1; i=$((i+1)); done
|
||||||
|
[ -S /tmp/.X11-unix/X0 ] || { echo "X-START FAIL (see $L/Xorg.out, /var/log/Xorg.0.log)"; tail -20 /var/log/Xorg.0.log; exit 1; }
|
||||||
|
export DISPLAY=:0
|
||||||
|
xsetroot -solid '#203050'
|
||||||
|
twm > $L/twm.out 2>&1 &
|
||||||
|
xterm -geometry 21x9+0+0 -fa '' -fn 6x10 -bg black -fg green -e sh -c 'echo aurora B13; uname -r; exec sh' > $L/xterm.out 2>&1 &
|
||||||
|
x11vnc -display :0 -listen $VNC_ADDR -no6 -rfbport 5900 -rfbportv6 -1 -forever -shared -nopw -noxdamage -quiet -bg -o $L/x11vnc.log > $L/x11vnc.out 2>&1
|
||||||
|
sleep 2; echo "X-START OK after ${i}s: $(pids) $(xdpyinfo 2>/dev/null | grep dimensions)"; grep -E "dimensions|depth of root" $L/x11vnc.log | head -2 ;;
|
||||||
|
stop)
|
||||||
|
for n in x11vnc xterm twm; do killall $n 2>/dev/null; done; sleep 1; killall Xorg 2>/dev/null
|
||||||
|
i=0; while pidof Xorg >/dev/null && [ $i -lt 10 ]; do sleep 1; i=$((i+1)); done; pidof Xorg >/dev/null && killall -9 Xorg
|
||||||
|
echo "X-STOP done: left=[$(pids)]" ;;
|
||||||
|
status) echo "pids: $(pids)"; netstat -ltn 2>/dev/null | grep -E ":59|:60" ; tail -3 $L/x11vnc.log 2>/dev/null ;;
|
||||||
|
*) echo "usage: $0 start [fbdev|modesetting]|stop|status"; exit 2 ;;
|
||||||
|
esac
|
||||||
12
b12/b12p/B12P-rollback.sh
Normal file
12
b12/b12p/B12P-rollback.sh
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# B12P rollback - restore the B10 cache (c3732515, operational since 2026-10-04). Needs 9008 via HW EDL (D+->GND). boot/aboot/userdata untouched
|
||||||
|
# (B10 init sets every eMMC device RO and never mounts userdata, so the ext4 Alpine there is inert). Deeper rollback: b10/b10b5/B10-rollback.sh (B9C).
|
||||||
|
cd ~/doc/modem/jz08-aurora || exit 1
|
||||||
|
L=firehose/007050e100000000_394a2e47cf830150_fhprg_peek.bin ; O=logs/b12/b12p/rollback ; mkdir -p $O
|
||||||
|
B=b10/b10b3/cache-v4/cache-extlinux-b10b5.img
|
||||||
|
[ "$(sha256sum $B | cut -d' ' -f1)" = c37325156a6f4c013982cf01bcb5b2ddb026b0298e9c3ec0be87f57d693464b8 ] || { echo "STOP: rollback image hash"; exit 1; }
|
||||||
|
lsusb | grep -q 05c6:9008 || { echo "STOP: no 9008"; exit 1; }
|
||||||
|
edl --loader=$L printgpt > $O/00-printgpt.log 2>&1
|
||||||
|
edl --loader=$L w cache $B > $O/cache-w.log 2>&1
|
||||||
|
edl --loader=$L r cache $O/cache-rb.bin > /dev/null 2>&1 ; cmp $B $O/cache-rb.bin && echo CACHE_RESTORED_B10
|
||||||
|
sha256sum $B $O/cache-rb.bin
|
||||||
53
b12/b12p/B12P-write.sh
Normal file
53
b12/b12p/B12P-write.sh
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# B12P — the ONLY write: cache := B12P candidate (B10 production kernel/DTB/cmdline unchanged + initramfs overlay: persistent Alpine on
|
||||||
|
# userdata auto-mounted at /alpine). Run on 480s ONLY after explicit GO. Derived 1:1 from b10/b10b5/B10-write.sh (B10_CACHE_WRITE_VERIFIED 2026-10-04);
|
||||||
|
# changed: image/hashes, rollback refs, log dir, and userdata is no longer compared to A4pre (it was formatted as ext4 'aurora-alpine' in B12P-1)
|
||||||
|
# - only its superblock (magic + label) is checked. The pre-write readback of the live cache (must be B10 c3732515) is kept as backup.
|
||||||
|
# Entry: HW EDL (battery on, D+->GND, plug USB, release). Never `edl reset`. Stops at first failed gate.
|
||||||
|
cd ~/doc/modem/jz08-aurora || exit 1
|
||||||
|
L=firehose/007050e100000000_394a2e47cf830150_fhprg_peek.bin
|
||||||
|
O=logs/b12/b12p/W ; A3=logs/b5a/A3 ; P=logs/b5a/A4pre ; mkdir -p $O
|
||||||
|
NEW=b12/b12p/cache/cache-extlinux-b12p.img ; NEW_SHA=98d061eff0951ef5d05c9a4356bec959726f9462525325f7908a0bcc0e2e7394
|
||||||
|
OLD_SHA=c37325156a6f4c013982cf01bcb5b2ddb026b0298e9c3ec0be87f57d693464b8 # current cache = B10 extlinux
|
||||||
|
BOOT_SHA=e9579f33c7304cd47f487f2b61cd9226dc04fd3a63775d62b4b95fc15bd3ebff
|
||||||
|
ABOOT_SHA=15208dbb4feafccd72d2b06db5714cd746c216701f0ef8822c58bb47105d37c4 # aboot = lk1st-b9l (B9L-PERSIST)
|
||||||
|
die(){ echo "STOP: $*"; exit 1; }
|
||||||
|
sha(){ sha256sum "$1" | cut -d" " -f1; }
|
||||||
|
E(){ edl --loader=$L "$@"; }
|
||||||
|
echo "== G0 inputs"
|
||||||
|
[ "$(sha $L)" = 53f193500c03248f0d671ab57bfe9ca8a42967e97f28403294b4b3f854075aca ] || die loader
|
||||||
|
[ "$(sha $NEW)" = $NEW_SHA ] && [ $(stat -c %s $NEW) = 134217728 ] || die candidate
|
||||||
|
[ "$(sha b10/b10b3/cache-v4/cache-extlinux-b10b5.img)" = $OLD_SHA ] || die rollback-image
|
||||||
|
[ "$(sha logs/b10/b10b5/W/11-cache-readback.bin)" = $OLD_SHA ] || die b10-readback-backup
|
||||||
|
lsusb | grep -q 05c6:9008 || die "no 9008"
|
||||||
|
echo "== G1 identity + geometry + baseline"
|
||||||
|
E printgpt > $O/00-printgpt.log 2>&1 || die printgpt
|
||||||
|
grep -aq "Serial: *0x<SAHARA_SERIAL>" $O/00-printgpt.log || grep -aq "Mode detected: firehose" $O/00-printgpt.log || die serial
|
||||||
|
grep -a "^cache:" $O/00-printgpt.log | grep -q "Offset 0x000000004118c000, Length 0x0000000008000000" || die cache-geometry
|
||||||
|
E rs 0 34 $O/pre-gptp.bin >/dev/null 2>&1; cmp $O/pre-gptp.bin $A3/gpt-primary-34.bin || die gpt-changed
|
||||||
|
E r boot $O/pre-boot.bin >/dev/null 2>&1; [ "$(sha $O/pre-boot.bin)" = $BOOT_SHA ] || die boot-not-emmc1
|
||||||
|
E r aboot $O/pre-aboot.bin >/dev/null 2>&1; [ "$(sha $O/pre-aboot.bin)" = $ABOOT_SHA ] || die aboot-not-b9l
|
||||||
|
E r cache $O/pre-cache.bin >/dev/null 2>&1; [ "$(sha $O/pre-cache.bin)" = $OLD_SHA ] || die cache-not-backup
|
||||||
|
echo "== W cache := candidate (LBA 2133088, 262144 sectors)"
|
||||||
|
E w cache $NEW > $O/10-cache-write.log 2>&1; echo "rc=$?"; grep -a "Wrote" $O/10-cache-write.log
|
||||||
|
E r cache $O/11-cache-readback.bin > $O/11-cache-readback.log 2>&1 || die readback-rc
|
||||||
|
sha256sum $NEW $O/11-cache-readback.bin
|
||||||
|
cmp $NEW $O/11-cache-readback.bin || die "CACHE READBACK MISMATCH — do NOT reboot; run b12/b12p/B12P-rollback.sh"
|
||||||
|
echo CACHE_MATCH
|
||||||
|
echo "== V everything else unchanged"
|
||||||
|
E rs 0 34 $O/post-gptp.bin >/dev/null 2>&1; cmp $O/post-gptp.bin $A3/gpt-primary-34.bin || die gptp
|
||||||
|
E rs 7634911 33 $O/post-gptb.bin >/dev/null 2>&1; cmp $O/post-gptb.bin $A3/gpt-backup-33.bin || die gptb
|
||||||
|
E rs 305184 1024 $O/post-tzbak.bin >/dev/null 2>&1; cmp $O/post-tzbak.bin $A3/tzbak-305184.bin || die tzbak
|
||||||
|
E r boot $O/post-boot.bin >/dev/null 2>&1; [ "$(sha $O/post-boot.bin)" = $BOOT_SHA ] || die boot
|
||||||
|
E r aboot $O/post-aboot.bin >/dev/null 2>&1; [ "$(sha $O/post-aboot.bin)" = $ABOOT_SHA ] || die aboot
|
||||||
|
for p in sbl1 rpm tz hyp recovery modemst1 modemst2 fsg fsc persist; do
|
||||||
|
E r $p $O/post-$p.bin >/dev/null 2>&1; cmp $O/post-$p.bin $A3/$p.bin || die "$p changed"; echo "$p == A3"
|
||||||
|
done
|
||||||
|
for p in modem system; do
|
||||||
|
E r $p $O/post-$p.bin >/dev/null 2>&1; cmp $O/post-$p.bin $P/$p.bin || die "$p changed"; echo "$p == A4pre"; rm -f $O/post-$p.bin
|
||||||
|
done
|
||||||
|
E rs 2428000 8 $O/post-userdata-sb.bin >/dev/null 2>&1
|
||||||
|
[ "$(dd if=$O/post-userdata-sb.bin bs=1 skip=1080 count=2 2>/dev/null | od -An -tx1 | tr -d ' \n')" = 53ef ] && [ "$(dd if=$O/post-userdata-sb.bin bs=1 skip=1144 count=16 2>/dev/null | tr -d '\000')" = aurora-alpine ] || die "userdata superblock is not ext4 aurora-alpine"
|
||||||
|
echo "userdata = ext4 aurora-alpine (superblock)"
|
||||||
|
(cd $O && sha256sum *.bin > SHA256SUMS)
|
||||||
|
echo "B12P_CACHE_WRITE_VERIFIED — power off fully (USB, then battery) before first boot"
|
||||||
40
b12/b12p/b12p-boot.sh
Normal file
40
b12/b12p/b12p-boot.sh
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# 480s side, B12P RAM test (nothing written to eMMC boot partitions). RESET-held power-on -> lk1st fastboot -> `fastboot boot` B12P RAM image.
|
||||||
|
# Checks: modem START OK (patched safety gate), Wi-Fi AP, ALPINE OK (/alpine mounted from userdata, RW only p27), display, eMMC write stats.
|
||||||
|
K=$1; MODE=${2:-ram}; [ -n "$K" ] || { echo "usage: $0 K [ram|cold]"; exit 2; } # cold = normal power-on from eMMC cache, no fastboot
|
||||||
|
cd ~/doc/modem/jz08-aurora; O=logs/b12/b12p/$MODE$K; mkdir -p $O; IMG=b12/b12p/out/aurora-b12p.img
|
||||||
|
A=$O/host-actions.txt; act() { echo "$(date -u +%H:%M:%S) $*" | tee -a $A; }
|
||||||
|
tn() { { sleep 1; sed "s/\$/\r/" "$1"; sleep $2; } | ncat 172.16.42.1 23 | tr -d "\000\r"; }
|
||||||
|
if [ $MODE = ram ]; then
|
||||||
|
echo "00af916024671553f873a92d6ba7057443a239eaf3e38384d0b51845af5689b9 $IMG" | sha256sum -c || exit 1
|
||||||
|
act "B12P ram$K: waiting for fastboot <EMMC_SERIAL> (power off, then hold RESET while powering on)"
|
||||||
|
i=0; until fastboot devices 2>/dev/null | grep -q <EMMC_SERIAL>; do i=$((i+1)); [ $i -ge 900 ] && { act "ABORT: no fastboot"; exit 1; }; sleep 2; done
|
||||||
|
act "fastboot present"; { fastboot boot $IMG 2>&1; echo "rc=$?"; } | tee -a $A
|
||||||
|
else
|
||||||
|
act "B12P cold$K: waiting for normal power-on WITHOUT RESET (cache B12P 98d061ef)"
|
||||||
|
i=0; until ping -c1 -W1 172.16.42.1 >/dev/null 2>&1; do fastboot devices 2>/dev/null | grep -q <EMMC_SERIAL> && { act "ABORT: board in fastboot - RESET held?"; exit 1; }; i=$((i+1)); [ $i -ge 1800 ] && { act "ABORT: no NCM"; exit 1; }; sleep 1; done
|
||||||
|
fi
|
||||||
|
i=0; until ping -c1 -W1 172.16.42.1 >/dev/null 2>&1; do i=$((i+1)); [ $i -ge 180 ] && { act "ABORT: NCM not up"; exit 1; }; sleep 1; done; act "NCM ping ok"
|
||||||
|
printf 'grep -E "START OK|FAIL in|rollback|SAFETY" /run/aurora-modem/lifecycle.log | tail -2\n' > $O/.w
|
||||||
|
i=0; until tn $O/.w 3 | grep -qE "^\[[0-9.]+\] .*(=== START OK|FAIL in|rollback)"; do i=$((i+1)); [ $i -ge 80 ] && { act "no START OK/FAIL after ~12 min"; break; }; sleep 6; done
|
||||||
|
act "modem: $(tn $O/.w 3 | grep -E '^\[[0-9.]+\]' | tail -2 | tr '\n' ' ')"
|
||||||
|
printf 'grep -E "AP ENABLED|FAIL" /run/aurora-wifi/wifi.log | tail -1\n' > $O/.a
|
||||||
|
i=0; until tn $O/.a 3 | grep -qE "^\[[0-9.]+\] (=== AP ENABLED|FAIL)"; do i=$((i+1)); [ $i -ge 30 ] && break; sleep 6; done
|
||||||
|
act "wifi: $(tn $O/.a 3 | grep -E '^\[[0-9.]+\]' | tail -1)"
|
||||||
|
cat > $O/.c <<'C'
|
||||||
|
echo SNAP-BEGIN; cat /proc/uptime; uname -a; cat /proc/cmdline
|
||||||
|
echo ---alpine; cat /run/aurora-alpine/alpine.log /run/aurora-alpine/service.log; /etc/init.d/aurora-alpine status
|
||||||
|
echo ---ro; for x in /dev/mmcblk0 /dev/mmcblk0p* /dev/mmcblk0boot0 /dev/mmcblk0boot1; do printf "%s=%s " ${x#/dev/} $(blockdev --getro $x); done; echo
|
||||||
|
echo ---chroot; chroot /alpine /bin/sh -c 'cat /etc/alpine-release /etc/aurora-alpine-release; ls /usr/libexec/Xorg; cat /root/persist-test.txt'
|
||||||
|
echo ---modem; /etc/init.d/aurora-modem status; grep -E "SAFETY|START OK" /run/aurora-modem/lifecycle.log
|
||||||
|
echo ---ping; ping -c4 -W3 -I wwan0 77.88.8.8 | tail -2
|
||||||
|
echo ---wifi; /etc/init.d/aurora-wifi status | tail -3
|
||||||
|
echo ---display; /etc/init.d/aurora-display status; cat /sys/class/tty/tty0/active
|
||||||
|
echo ---charger; cat /sys/kernel/debug/pm8916_lbc/state 2>/dev/null || { mount -t debugfs debugfs /sys/kernel/debug; cat /sys/kernel/debug/pm8916_lbc/state; }
|
||||||
|
echo ---emmc; cat /sys/block/mmcblk0/stat; for p in /sys/class/block/mmcblk0p*; do s=$(awk '{print $5}' $p/stat); [ "$s" != 0 ] && echo "$(basename $p) writes=$s"; done
|
||||||
|
echo ---mem; free; dmesg | grep -iE "ext4|mmcblk0p27|aurora-alpine" | tail
|
||||||
|
echo SNAP-END
|
||||||
|
C
|
||||||
|
tn $O/.c 25 > $O/snapshot.txt; act "snapshot: $(grep -c SNAP-END $O/snapshot.txt) end; $(grep -m1 'ALPINE OK' $O/snapshot.txt)"
|
||||||
|
grep -A1 -- "---ro" $O/snapshot.txt | tail -1 | tr ' ' '\n' | grep "=0" | tee -a $A
|
||||||
|
act "B12P $MODE$K END"
|
||||||
28
b12/b12p/build-b12p.sh
Normal file
28
b12/b12p/build-b12p.sh
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B12P image: production B10 (kernel 7.2.7-aurora-b10b5 + prod DTB e47762d1 + B9C cmdline, all unchanged) + initramfs overlay:
|
||||||
|
# /init (+ aurora-alpine autostart), aurora-modem (safety gate accepts a lifted disk flag only if every partition except userdata is RO),
|
||||||
|
# aurora-alpine service, e2fsck bundle (Alpine 3.24 e2fsprogs 1.47.4, own musl loader), mountpoint /alpine.
|
||||||
|
# Outputs RAM image (fastboot boot pretest) + parts for the cache candidate. out/ contains the B8F initramfs (Wi-Fi PSK): never publish.
|
||||||
|
set -e; cd "$(dirname "$0")"; O=out; F=../../b10/b10b3/out-v4; GEN=../../linux/out/usr/gen_init_cpio; TS=1790726400
|
||||||
|
mkdir -p $O
|
||||||
|
echo "b0ea04666c4ab979067fe9c0015bda0e9c8ac742678321e57b18e841c9c69f95 $F/Image.gz-dtb" | sha256sum -c
|
||||||
|
echo "e47762d1dcd0af6e2acb711fa47ecc13769cd6bcb81259ce50635e8b18b6514a $F/aurora-b10b3.dtb" | sha256sum -c
|
||||||
|
echo "ac518e27e2957ad5e4515969b9a3808024e11ef8d1a79433a899a67dbc644558 $F/initramfs.cpio.gz" | sha256sum -c
|
||||||
|
echo "0fef41b262917c8ae308fa222da0017e2b3cb3ec5da1ca8ba18d0318476761a3 $F/cmdline.txt" | sha256sum -c
|
||||||
|
diff -u ../../b9/b9c/rootfs/init rootfs/init > $O/init.diff || true
|
||||||
|
diff -u ../../b7/b7c/rootfs/usr/sbin/aurora-modem rootfs/usr/sbin/aurora-modem > $O/aurora-modem.diff || true
|
||||||
|
[ $(grep -c '^+[^+]' $O/init.diff) = 2 ] && [ $(grep -c '^-[^-]' $O/init.diff) = 0 ] || { echo "STOP: init diff"; exit 1; }
|
||||||
|
[ $(grep -c '^-[^-]' $O/aurora-modem.diff) = 1 ] || { echo "STOP: aurora-modem diff"; exit 1; }
|
||||||
|
cp $F/Image.gz-dtb $F/aurora-b10b3.dtb $F/cmdline.txt $O/
|
||||||
|
{ echo "file /init rootfs/init 0755 0 0"
|
||||||
|
echo "file /usr/sbin/aurora-modem rootfs/usr/sbin/aurora-modem 0755 0 0"
|
||||||
|
echo "file /usr/sbin/aurora-alpine rootfs/usr/sbin/aurora-alpine 0755 0 0"
|
||||||
|
echo "file /etc/init.d/aurora-alpine rootfs/etc/init.d/aurora-alpine 0755 0 0"
|
||||||
|
echo "dir /alpine 0755 0 0"
|
||||||
|
echo "dir /usr/libexec/aurora/e2fs 0755 0 0"; echo "dir /usr/libexec/aurora/e2fs/lib 0755 0 0"; echo "dir /usr/libexec/aurora/e2fs/sbin 0755 0 0"
|
||||||
|
for f in e2fs/lib/* e2fs/sbin/*; do echo "file /usr/libexec/aurora/$f $f 0755 0 0"; done; } > $O/overlay-b12p.list
|
||||||
|
$GEN -t $TS $O/overlay-b12p.list > $O/overlay-b12p.cpio
|
||||||
|
gzip -9 -n -c $O/overlay-b12p.cpio > $O/overlay-b12p.cpio.gz
|
||||||
|
cat $F/initramfs.cpio.gz $O/overlay-b12p.cpio.gz > $O/initramfs-b12p.cpio.gz
|
||||||
|
python3 ../../b6p/mkbootimg.py $O/Image.gz-dtb $O/initramfs-b12p.cpio.gz $O/cmdline.txt $O/aurora-b12p.img
|
||||||
|
(cd $O && sha256sum Image.gz-dtb aurora-b10b3.dtb cmdline.txt overlay-b12p.cpio.gz initramfs-b12p.cpio.gz aurora-b12p.img > SHA256SUMS; cat SHA256SUMS); ls -l $O/aurora-b12p.img
|
||||||
6
b12/b12p/cache/extlinux-b12p.conf
vendored
Normal file
6
b12/b12p/cache/extlinux-b12p.conf
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
default b12p
|
||||||
|
label b12p
|
||||||
|
linux /Image.gz-dtb
|
||||||
|
fdt /aurora-b10b3.dtb
|
||||||
|
initrd /initramfs-b12p.cpio.gz
|
||||||
|
append earlycon console=tty0 console=ttyMSM0,115200n8 ignore_loglevel loglevel=8 rdinit=/init fbcon=font:6x8 consoleblank=0
|
||||||
27
b12/b12p/cache/mkfs-cache-b12p.sh
vendored
Normal file
27
b12/b12p/cache/mkfs-cache-b12p.sh
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# B12P cache CANDIDATE (NOT for writing without a separate GO): exact recipe of b10/b10b3/cache-v4/mkfs-cache-b10b5.sh (c3732515);
|
||||||
|
# differs only in the initrd (B9C initramfs + B12P overlay: aurora-alpine autostart, modem safety gate, e2fsck bundle), file names,
|
||||||
|
# extlinux label, fs label and UUIDs. Kernel/DTB/append = B10 production unchanged. Runs on 480s (mke2fs 1.47.2). Offline only.
|
||||||
|
# The image contains the AP PSK (in the initramfs) - never publish it.
|
||||||
|
set -e
|
||||||
|
cd ~/doc/modem/jz08-aurora/b12/b12p/cache
|
||||||
|
OUT=${1:-cache-extlinux-b12p.img}; F=../out
|
||||||
|
echo "0fef41b262917c8ae308fa222da0017e2b3cb3ec5da1ca8ba18d0318476761a3 $F/cmdline.txt" | sha256sum -c
|
||||||
|
echo "b0ea04666c4ab979067fe9c0015bda0e9c8ac742678321e57b18e841c9c69f95 $F/Image.gz-dtb" | sha256sum -c
|
||||||
|
echo "e47762d1dcd0af6e2acb711fa47ecc13769cd6bcb81259ce50635e8b18b6514a $F/aurora-b10b3.dtb" | sha256sum -c
|
||||||
|
echo "40df25a0818244c8ff72fa045d2f4ac9679263456550accc9555548c3ba0f142 $F/initramfs-b12p.cpio.gz" | sha256sum -c
|
||||||
|
ST=$(mktemp -d); mkdir -p $ST/extlinux
|
||||||
|
cp $F/Image.gz-dtb $F/aurora-b10b3.dtb $F/initramfs-b12p.cpio.gz $ST/
|
||||||
|
printf "default b12p\nlabel b12p\n\tlinux /Image.gz-dtb\n\tfdt /aurora-b10b3.dtb\n\tinitrd /initramfs-b12p.cpio.gz\n\tappend %s\n" "$(cat $F/cmdline.txt)" > $ST/extlinux/extlinux.conf
|
||||||
|
cp $ST/extlinux/extlinux.conf extlinux-b12p.conf
|
||||||
|
chmod 0644 $ST/*.* $ST/extlinux/extlinux.conf; chmod 0755 $ST $ST/extlinux
|
||||||
|
find $ST -exec touch -h -d @1790726400 {} +
|
||||||
|
rm -f $OUT; truncate -s 134217728 $OUT
|
||||||
|
E2FSPROGS_FAKE_TIME=1790726400 /sbin/mke2fs -F -q -t ext2 -O none,filetype,sparse_super \
|
||||||
|
-b 4096 -I 128 -N 64 -m 0 -L aurora-b12p -U 4a5a3038-b6f0-4000-8000-0000b12b1200 \
|
||||||
|
-E root_owner=0:0,hash_seed=4a5a3038-b6f0-4000-8000-0000b12b1201 -d $ST $OUT 32768
|
||||||
|
rm -rf $ST
|
||||||
|
for f in / /lost+found /extlinux /extlinux/extlinux.conf /Image.gz-dtb /aurora-b10b3.dtb /initramfs-b12p.cpio.gz; do for t in atime ctime mtime; do echo "sif $f $t @1790726400"; done; done > /tmp/b12p-sif.$$
|
||||||
|
/sbin/debugfs -w -f /tmp/b12p-sif.$$ $OUT >/dev/null 2>&1; rm -f /tmp/b12p-sif.$$
|
||||||
|
/sbin/e2fsck -fn $OUT >/dev/null 2>&1 && echo "e2fsck -fn clean"
|
||||||
|
stat -c "%n %s" $OUT; sha256sum $OUT
|
||||||
12
b12/b12q/B12Q-rollback.sh
Normal file
12
b12/b12q/B12Q-rollback.sh
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# B12Q rollback - restore the B12P cache (98d061ef: LFS PID1 + Alpine chroot at /alpine). Needs 9008 via HW EDL (D+->GND). boot/aboot/userdata untouched
|
||||||
|
# (p27 keeps the B12Q packages/OpenRC; under B12P it is only mounted at /alpine). Deeper: b12/b12p/B12P-rollback.sh (B10 c3732515).
|
||||||
|
cd ~/doc/modem/jz08-aurora || exit 1
|
||||||
|
L=firehose/007050e100000000_394a2e47cf830150_fhprg_peek.bin ; O=logs/b12/b12q/rollback ; mkdir -p $O
|
||||||
|
B=b12/b12p/cache/cache-extlinux-b12p.img
|
||||||
|
[ "$(sha256sum $B | cut -d' ' -f1)" = 98d061eff0951ef5d05c9a4356bec959726f9462525325f7908a0bcc0e2e7394 ] || { echo "STOP: rollback image hash"; exit 1; }
|
||||||
|
lsusb | grep -q 05c6:9008 || { echo "STOP: no 9008"; exit 1; }
|
||||||
|
edl --loader=$L printgpt > $O/00-printgpt.log 2>&1
|
||||||
|
edl --loader=$L w cache $B > $O/cache-w.log 2>&1
|
||||||
|
edl --loader=$L r cache $O/cache-rb.bin > /dev/null 2>&1 ; cmp $B $O/cache-rb.bin && echo CACHE_RESTORED_B12P
|
||||||
|
sha256sum $B $O/cache-rb.bin
|
||||||
53
b12/b12q/B12Q-write.sh
Normal file
53
b12/b12q/B12Q-write.sh
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# B12Q — the ONLY write: cache := B12Q candidate (B10 kernel/DTB/cmdline unchanged; initramfs = stage0 switch_root into Alpine on p27,
|
||||||
|
# LFS rescue /init.lfs on any failure / aurora.alpine=off / 3 unconfirmed boots). Run on 480s ONLY after explicit GO.
|
||||||
|
# Derived 1:1 from b12/b12p/B12P-write.sh (B12P_CACHE_WRITE_VERIFIED 2026-10-04); changed: image/hashes, rollback refs, log dir.
|
||||||
|
# The pre-write readback of the live cache (must be B12P 98d061ef) is kept as backup.
|
||||||
|
# Entry: HW EDL (battery on, D+->GND, plug USB, release). Never `edl reset`. Stops at first failed gate.
|
||||||
|
cd ~/doc/modem/jz08-aurora || exit 1
|
||||||
|
L=firehose/007050e100000000_394a2e47cf830150_fhprg_peek.bin
|
||||||
|
O=logs/b12/b12q/W ; A3=logs/b5a/A3 ; P=logs/b5a/A4pre ; mkdir -p $O
|
||||||
|
NEW=b12/b12q/cache/cache-extlinux-b12q.img ; NEW_SHA=59272cd3fb45a9388934110b345a0e320d62a3199b52aa0c47ec10eb79352aae
|
||||||
|
OLD_SHA=98d061eff0951ef5d05c9a4356bec959726f9462525325f7908a0bcc0e2e7394 # current cache = B12P extlinux
|
||||||
|
BOOT_SHA=e9579f33c7304cd47f487f2b61cd9226dc04fd3a63775d62b4b95fc15bd3ebff
|
||||||
|
ABOOT_SHA=15208dbb4feafccd72d2b06db5714cd746c216701f0ef8822c58bb47105d37c4 # aboot = lk1st-b9l (B9L-PERSIST)
|
||||||
|
die(){ echo "STOP: $*"; exit 1; }
|
||||||
|
sha(){ sha256sum "$1" | cut -d" " -f1; }
|
||||||
|
E(){ edl --loader=$L "$@"; }
|
||||||
|
echo "== G0 inputs"
|
||||||
|
[ "$(sha $L)" = 53f193500c03248f0d671ab57bfe9ca8a42967e97f28403294b4b3f854075aca ] || die loader
|
||||||
|
[ "$(sha $NEW)" = $NEW_SHA ] && [ $(stat -c %s $NEW) = 134217728 ] || die candidate
|
||||||
|
[ "$(sha b12/b12p/cache/cache-extlinux-b12p.img)" = $OLD_SHA ] || die rollback-image
|
||||||
|
[ "$(sha logs/b12/b12p/W/11-cache-readback.bin)" = $OLD_SHA ] || die b12p-readback-backup
|
||||||
|
lsusb | grep -q 05c6:9008 || die "no 9008"
|
||||||
|
echo "== G1 identity + geometry + baseline"
|
||||||
|
E printgpt > $O/00-printgpt.log 2>&1 || die printgpt
|
||||||
|
grep -aq "Serial: *0x<SAHARA_SERIAL>" $O/00-printgpt.log || grep -aq "Mode detected: firehose" $O/00-printgpt.log || die serial
|
||||||
|
grep -a "^cache:" $O/00-printgpt.log | grep -q "Offset 0x000000004118c000, Length 0x0000000008000000" || die cache-geometry
|
||||||
|
E rs 0 34 $O/pre-gptp.bin >/dev/null 2>&1; cmp $O/pre-gptp.bin $A3/gpt-primary-34.bin || die gpt-changed
|
||||||
|
E r boot $O/pre-boot.bin >/dev/null 2>&1; [ "$(sha $O/pre-boot.bin)" = $BOOT_SHA ] || die boot-not-emmc1
|
||||||
|
E r aboot $O/pre-aboot.bin >/dev/null 2>&1; [ "$(sha $O/pre-aboot.bin)" = $ABOOT_SHA ] || die aboot-not-b9l
|
||||||
|
E r cache $O/pre-cache.bin >/dev/null 2>&1; [ "$(sha $O/pre-cache.bin)" = $OLD_SHA ] || die cache-not-backup
|
||||||
|
echo "== W cache := candidate (LBA 2133088, 262144 sectors)"
|
||||||
|
E w cache $NEW > $O/10-cache-write.log 2>&1; echo "rc=$?"; grep -a "Wrote" $O/10-cache-write.log
|
||||||
|
E r cache $O/11-cache-readback.bin > $O/11-cache-readback.log 2>&1 || die readback-rc
|
||||||
|
sha256sum $NEW $O/11-cache-readback.bin
|
||||||
|
cmp $NEW $O/11-cache-readback.bin || die "CACHE READBACK MISMATCH — do NOT reboot; run b12/b12q/B12Q-rollback.sh"
|
||||||
|
echo CACHE_MATCH
|
||||||
|
echo "== V everything else unchanged"
|
||||||
|
E rs 0 34 $O/post-gptp.bin >/dev/null 2>&1; cmp $O/post-gptp.bin $A3/gpt-primary-34.bin || die gptp
|
||||||
|
E rs 7634911 33 $O/post-gptb.bin >/dev/null 2>&1; cmp $O/post-gptb.bin $A3/gpt-backup-33.bin || die gptb
|
||||||
|
E rs 305184 1024 $O/post-tzbak.bin >/dev/null 2>&1; cmp $O/post-tzbak.bin $A3/tzbak-305184.bin || die tzbak
|
||||||
|
E r boot $O/post-boot.bin >/dev/null 2>&1; [ "$(sha $O/post-boot.bin)" = $BOOT_SHA ] || die boot
|
||||||
|
E r aboot $O/post-aboot.bin >/dev/null 2>&1; [ "$(sha $O/post-aboot.bin)" = $ABOOT_SHA ] || die aboot
|
||||||
|
for p in sbl1 rpm tz hyp recovery modemst1 modemst2 fsg fsc persist; do
|
||||||
|
E r $p $O/post-$p.bin >/dev/null 2>&1; cmp $O/post-$p.bin $A3/$p.bin || die "$p changed"; echo "$p == A3"
|
||||||
|
done
|
||||||
|
for p in modem system; do
|
||||||
|
E r $p $O/post-$p.bin >/dev/null 2>&1; cmp $O/post-$p.bin $P/$p.bin || die "$p changed"; echo "$p == A4pre"; rm -f $O/post-$p.bin
|
||||||
|
done
|
||||||
|
E rs 2428000 8 $O/post-userdata-sb.bin >/dev/null 2>&1
|
||||||
|
[ "$(dd if=$O/post-userdata-sb.bin bs=1 skip=1080 count=2 2>/dev/null | od -An -tx1 | tr -d ' \n')" = 53ef ] && [ "$(dd if=$O/post-userdata-sb.bin bs=1 skip=1144 count=16 2>/dev/null | tr -d '\000')" = aurora-alpine ] || die "userdata superblock is not ext4 aurora-alpine"
|
||||||
|
echo "userdata = ext4 aurora-alpine (superblock)"
|
||||||
|
(cd $O && sha256sum *.bin > SHA256SUMS)
|
||||||
|
echo "B12Q_CACHE_WRITE_VERIFIED — power off fully (USB, then battery) before first boot"
|
||||||
1
b12/b12q/alpine-overlay/etc/aurora/build-epoch
Normal file
1
b12/b12q/alpine-overlay/etc/aurora/build-epoch
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
1790935600
|
||||||
12
b12/b12q/alpine-overlay/etc/aurora/modem.conf
Normal file
12
b12/b12q/alpine-overlay/etc/aurora/modem.conf
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Aurora modem operator profile (read by /usr/sbin/aurora-modem). Logic lives in the controller; only this file names an operator.
|
||||||
|
# Empty APN => start refuses (exit 2): no APN guessing.
|
||||||
|
# Current test profile: Beeline RU (public, operator-published default credentials).
|
||||||
|
APN=internet.beeline.ru
|
||||||
|
USER=beeline
|
||||||
|
PASSWORD=beeline
|
||||||
|
AUTH=pap
|
||||||
|
IP_TYPE=ipv4
|
||||||
|
# registration deadline (s): wait for registered + PS attached; searching/limited/denied/detached are not failures before it.
|
||||||
|
REG_TIMEOUT=600
|
||||||
|
# extra /32 host routes via the bearer interface (bearer DNS servers are always added). No default route is created.
|
||||||
|
ROUTES="77.88.8.8 1.1.1.1"
|
||||||
1
b12/b12q/alpine-overlay/etc/aurora/primary-root
Normal file
1
b12/b12q/alpine-overlay/etc/aurora/primary-root
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
B12Q: this p27 is an Aurora primary root (stage0 switch_root target)
|
||||||
1
b12/b12q/alpine-overlay/etc/fstab
Normal file
1
b12/b12q/alpine-overlay/etc/fstab
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
tmpfs /tmp tmpfs nosuid,nodev,mode=1777,size=64m 0 0
|
||||||
1
b12/b12q/alpine-overlay/etc/hostname
Normal file
1
b12/b12q/alpine-overlay/etc/hostname
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
aurora
|
||||||
5
b12/b12q/alpine-overlay/etc/init.d/aurora-bootok
Normal file
5
b12/b12q/alpine-overlay/etc/init.d/aurora-bootok
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
# B12Q: default runlevel reached -> reset stage0's boot-attempt counter (anti boot-loop: 3 unconfirmed boots -> LFS rescue).
|
||||||
|
description="Aurora boot confirmation"
|
||||||
|
depend() { after aurora-display aurora-modem aurora-wifi aurora-ncm; }
|
||||||
|
start() { echo 0 > /var/lib/aurora/boot-attempts; sync; echo "<5>[aurora-bootok] ALPINE PRIMARY ROOT BOOT OK" > /dev/kmsg; einfo "boot confirmed"; }
|
||||||
8
b12/b12q/alpine-overlay/etc/init.d/aurora-display
Normal file
8
b12/b12q/alpine-overlay/etc/init.d/aurora-display
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
# B12Q: OpenRC wrapper around the validated LFS service script (unchanged copy in /usr/libexec/aurora/svc/aurora-display).
|
||||||
|
description="Aurora display service (B6P..B10 logic)"
|
||||||
|
S=/usr/libexec/aurora/svc/aurora-display
|
||||||
|
depend() { after aurora-ncm; }
|
||||||
|
start() { ebegin "aurora-display"; $S start; eend $?; }
|
||||||
|
stop() { :; }
|
||||||
|
status() { $S status; }
|
||||||
15
b12/b12q/alpine-overlay/etc/init.d/aurora-firmware
Normal file
15
b12/b12q/alpine-overlay/etc/init.d/aurora-firmware
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
# B12Q: B1 from the LFS init - /dev/disk/by-partlabel links, modem FAT RO at /firmware, firmware_class path. Unchanged logic.
|
||||||
|
description="Aurora modem firmware FAT (RO)"
|
||||||
|
depend() { need aurora-ro; }
|
||||||
|
start() {
|
||||||
|
ebegin "Mounting modem FAT RO at /firmware"
|
||||||
|
mkdir -p /dev/disk/by-partlabel /firmware
|
||||||
|
for p in /sys/class/block/mmcblk0p*; do n=$(sed -n 's/^PARTNAME=//p' $p/uevent); [ -n "$n" ] && ln -sf /dev/$(basename $p) /dev/disk/by-partlabel/$n; done
|
||||||
|
M=$(readlink /dev/disk/by-partlabel/modem)
|
||||||
|
[ "$(blockdev --getro $M)" = 1 ] || { eend 1 "modem partition not RO"; return 1; }
|
||||||
|
grep -q " /firmware " /proc/mounts || mount -t vfat -o ro,nosuid,nodev,noexec,shortname=lower $M /firmware || { eend 1 mount; return 1; }
|
||||||
|
grep " /firmware " /proc/mounts | grep -q " ro," || { umount /firmware; eend 1 "not ro"; return 1; }
|
||||||
|
echo -n /firmware/image > /sys/module/firmware_class/parameters/path
|
||||||
|
eend 0
|
||||||
|
}
|
||||||
8
b12/b12q/alpine-overlay/etc/init.d/aurora-modem
Normal file
8
b12/b12q/alpine-overlay/etc/init.d/aurora-modem
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
# B12Q: OpenRC wrapper around the validated LFS service script (unchanged copy in /usr/libexec/aurora/svc/aurora-modem).
|
||||||
|
description="Aurora modem service (B6P..B10 logic)"
|
||||||
|
S=/usr/libexec/aurora/svc/aurora-modem
|
||||||
|
depend() { need aurora-ro aurora-firmware; after aurora-ncm aurora-display; }
|
||||||
|
start() { ebegin "aurora-modem"; $S start; eend $?; }
|
||||||
|
stop() { ebegin "aurora-modem stop"; $S stop; eend $?; }
|
||||||
|
status() { $S status; }
|
||||||
22
b12/b12q/alpine-overlay/etc/init.d/aurora-ncm
Normal file
22
b12/b12q/alpine-overlay/etc/init.d/aurora-ncm
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
# B12Q: usb_up + telnetd from the LFS init (DEVELOPMENT IDs 18d1:d001, NCM 172.16.42.1/24, root telnet bound to NCM only). Unchanged logic.
|
||||||
|
description="Aurora USB NCM management + telnetd"
|
||||||
|
depend() { after aurora-ro; }
|
||||||
|
start() {
|
||||||
|
ebegin "USB NCM gadget"
|
||||||
|
grep -q " /sys/kernel/config " /proc/mounts || mount -t configfs configfs /sys/kernel/config
|
||||||
|
for i in $(seq 1 50); do udc=$(ls /sys/class/udc 2>/dev/null | head -1); [ -n "$udc" ] && break; sleep 0.2; done
|
||||||
|
[ -n "$udc" ] || { eend 1 "no UDC"; return 1; }
|
||||||
|
G=/sys/kernel/config/usb_gadget/aurora
|
||||||
|
if [ ! -d $G ]; then
|
||||||
|
mkdir -p $G; echo 0x18d1 > $G/idVendor; echo 0xd001 > $G/idProduct
|
||||||
|
mkdir -p $G/strings/0x409; echo Aurora > $G/strings/0x409/manufacturer; echo "Aurora RAM Boot" > $G/strings/0x409/product; echo <EMMC_SERIAL> > $G/strings/0x409/serialnumber
|
||||||
|
mkdir -p $G/functions/ncm.usb0 $G/configs/c.1/strings/0x409; echo NCM > $G/configs/c.1/strings/0x409/configuration
|
||||||
|
ln -s $G/functions/ncm.usb0 $G/configs/c.1/
|
||||||
|
fi
|
||||||
|
[ -n "$(cat $G/UDC)" ] || echo "$udc" > $G/UDC || { eend 1 "bind UDC"; return 1; }
|
||||||
|
ifc=$(cat $G/functions/ncm.usb0/ifname)
|
||||||
|
ip link set lo up; ip addr show dev "$ifc" | grep -q " 172.16.42.1/24 " || ip addr add 172.16.42.1/24 dev "$ifc"; ip link set "$ifc" up
|
||||||
|
pidof telnetd >/dev/null || telnetd -l /bin/sh -b 172.16.42.1 -p 23
|
||||||
|
eend $? "telnetd"
|
||||||
|
}
|
||||||
12
b12/b12q/alpine-overlay/etc/init.d/aurora-ro
Normal file
12
b12/b12q/alpine-overlay/etc/init.d/aurora-ro
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
# B12Q: eMMC write policy check after switch_root (stage0 left only userdata RW) + /tmp on tmpfs (no eMMC writes for scratch).
|
||||||
|
description="Aurora eMMC RO policy check"
|
||||||
|
depend() { before aurora-firmware aurora-modem aurora-wifi; }
|
||||||
|
start() {
|
||||||
|
ebegin "Checking eMMC RO policy"
|
||||||
|
ud=; for p in /sys/class/block/mmcblk0p*; do [ "$(sed -n 's/^PARTNAME=//p' $p/uevent)" = userdata ] && ud=/dev/$(basename $p); done
|
||||||
|
bad=; for x in /dev/mmcblk0p* /dev/mmcblk0boot0 /dev/mmcblk0boot1; do [ "$x" = "$ud" ] && continue; [ "$(blockdev --getro $x)" = 1 ] || bad="$bad $x"; done
|
||||||
|
[ -z "$bad" ] || { eend 1 "NOT RO:$bad"; return 1; }
|
||||||
|
grep -q " /tmp tmpfs" /proc/mounts || mount -t tmpfs -o nosuid,nodev,mode=1777,size=64m tmpfs /tmp
|
||||||
|
echo "<5>[aurora-ro] all eMMC devices RO except $ud (root)" > /dev/kmsg; eend 0
|
||||||
|
}
|
||||||
8
b12/b12q/alpine-overlay/etc/init.d/aurora-wifi
Normal file
8
b12/b12q/alpine-overlay/etc/init.d/aurora-wifi
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
# B12Q: OpenRC wrapper around the validated LFS service script (unchanged copy in /usr/libexec/aurora/svc/aurora-wifi).
|
||||||
|
description="Aurora wifi service (B6P..B10 logic)"
|
||||||
|
S=/usr/libexec/aurora/svc/aurora-wifi
|
||||||
|
depend() { need aurora-ro aurora-firmware; after aurora-modem; }
|
||||||
|
start() { ebegin "aurora-wifi"; $S start; eend $?; }
|
||||||
|
stop() { ebegin "aurora-wifi stop"; $S stop; eend $?; }
|
||||||
|
status() { $S status; }
|
||||||
9
b12/b12q/alpine-overlay/etc/inittab
Normal file
9
b12/b12q/alpine-overlay/etc/inittab
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
# Aurora B12Q (Alpine primary root): busybox init + OpenRC
|
||||||
|
::sysinit:/sbin/openrc sysinit
|
||||||
|
::sysinit:/sbin/openrc boot
|
||||||
|
::wait:/sbin/openrc default
|
||||||
|
# display console (fbcon tty1, as in B9C) and root shell on the UART (as in the LFS init)
|
||||||
|
tty1::respawn:/sbin/getty 38400 tty1 linux
|
||||||
|
ttyMSM0::respawn:/sbin/getty -n -l /bin/sh -L 115200 ttyMSM0 vt100
|
||||||
|
::ctrlaltdel:/sbin/reboot
|
||||||
|
::shutdown:/sbin/openrc shutdown
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Aurora display service (B9C). Started once by /init; no OpenRC.
|
||||||
|
# /etc/init.d/aurora-display start | status — kernel cmdline 'aurora.display=off' disables autostart.
|
||||||
|
C=/usr/sbin/aurora-display; D=/run/aurora-display; L=$D/service.log
|
||||||
|
mkdir -p $D
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
grep -qw aurora.display=off /proc/cmdline && { echo "aurora-display: disabled by cmdline"; exit 0; }
|
||||||
|
( $C start >> $L 2>&1; echo "=== service start rc=$? $(cut -d' ' -f1 /proc/uptime)" >> $L ) &
|
||||||
|
echo "aurora-display: starting (pid $!, log $D/display.log)";;
|
||||||
|
status) $C status; tail -3 $D/display.log 2>/dev/null;;
|
||||||
|
*) echo "usage: $0 start|status"; exit 2;;
|
||||||
|
esac
|
||||||
27
b12/b12q/alpine-overlay/usr/libexec/aurora/svc/aurora-modem
Normal file
27
b12/b12q/alpine-overlay/usr/libexec/aurora/svc/aurora-modem
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Aurora modem service (B6P). Started once by /init after USB NCM; no OpenRC in this image.
|
||||||
|
# /etc/init.d/aurora-modem start | stop | status
|
||||||
|
# start: runs '/usr/sbin/aurora-modem start' in the background (registration may take up to REG_TIMEOUT s); returns at once.
|
||||||
|
# stop: ends a start still in progress, then '/usr/sbin/aurora-modem stop' (bearer down -> MM -> BAM idle -> MSS offline -> rmtfs last).
|
||||||
|
# status: service state + controller status. Reconnect without MSS restart: 'aurora-modem disconnect' then 'aurora-modem start'.
|
||||||
|
# Kernel cmdline 'aurora.modem=off' disables autostart.
|
||||||
|
C=/usr/sbin/aurora-modem; D=/run/aurora-modem; P=$D/service.pid; L=$D/service.log
|
||||||
|
mkdir -p $D
|
||||||
|
running() { [ -f $P ] && kill -0 $(cat $P) 2>/dev/null; }
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
grep -qw aurora.modem=off /proc/cmdline && { echo "aurora-modem: disabled by cmdline"; exit 0; }
|
||||||
|
running && { echo "aurora-modem: start already in progress (pid $(cat $P))"; exit 0; }
|
||||||
|
echo "=== service start $(cut -d' ' -f1 /proc/uptime)" >> $L
|
||||||
|
( $C start >> $L 2>&1; echo "=== service start rc=$? $(cut -d' ' -f1 /proc/uptime)" >> $L ) &
|
||||||
|
echo $! > $P; echo "aurora-modem: starting (pid $!, log $L)";;
|
||||||
|
stop)
|
||||||
|
if running; then echo "aurora-modem: aborting start in progress (pid $(cat $P))"; kill -TERM $(cat $P) 2>/dev/null
|
||||||
|
pkill -TERM -P $(cat $P) 2>/dev/null; sleep 1; fi
|
||||||
|
rm -f $P; echo "=== service stop $(cut -d' ' -f1 /proc/uptime)" >> $L
|
||||||
|
$C stop >> $L 2>&1; r=$?; echo "=== service stop rc=$r" >> $L; echo "aurora-modem: stop rc=$r"; exit $r;;
|
||||||
|
status)
|
||||||
|
running && echo "service: start in progress (pid $(cat $P))" || echo "service: idle"
|
||||||
|
$C status;;
|
||||||
|
*) echo "usage: $0 start|stop|status"; exit 2;;
|
||||||
|
esac
|
||||||
16
b12/b12q/alpine-overlay/usr/libexec/aurora/svc/aurora-wifi
Normal file
16
b12/b12q/alpine-overlay/usr/libexec/aurora/svc/aurora-wifi
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Aurora Wi-Fi service (B8F). Started once by /init after the modem service; no OpenRC.
|
||||||
|
# /etc/init.d/aurora-wifi start | stop | status — kernel cmdline 'aurora.wifi=off' disables autostart.
|
||||||
|
C=/usr/sbin/aurora-wifi; D=/run/aurora-wifi; P=$D/service.pid; L=$D/service.log
|
||||||
|
mkdir -p $D
|
||||||
|
running() { [ -f $P ] && kill -0 $(cat $P) 2>/dev/null; }
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
grep -qw aurora.wifi=off /proc/cmdline && { echo "aurora-wifi: disabled by cmdline"; exit 0; }
|
||||||
|
running && { echo "aurora-wifi: start already in progress (pid $(cat $P))"; exit 0; }
|
||||||
|
( $C start >> $L 2>&1; echo "=== service start rc=$? $(cut -d' ' -f1 /proc/uptime)" >> $L ) &
|
||||||
|
echo $! > $P; echo "aurora-wifi: starting (pid $!, log $L)";;
|
||||||
|
stop) running && kill -TERM $(cat $P) 2>/dev/null; rm -f $P; $C stop;;
|
||||||
|
status) running && echo "service: start in progress (pid $(cat $P))" || echo "service: idle"; $C status;;
|
||||||
|
*) echo "usage: $0 start|stop|status"; exit 2;;
|
||||||
|
esac
|
||||||
43
b12/b12q/alpine-overlay/usr/local/bin/b4b2-mm
Normal file
43
b12/b12q/alpine-overlay/usr/local/bin/b4b2-mm
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B4b2 via ModemManager: ONE simple-connect (apn=internet, ip-type=ipv4), manual IPv4 in routing table 100 only
|
||||||
|
# (main table / usb0 untouched), IP ping, DNS, clean disconnect. Long digit runs (IMEI/ICCID/IMSI) masked on-device.
|
||||||
|
O=/tmp/b4b2mm; mkdir -p $O; t() { cut -d' ' -f1 /proc/uptime; }
|
||||||
|
mask() { sed -E 's/([0-9]{6,})([0-9]{4})/******\2/g'; }
|
||||||
|
B=/sys/bus/platform/devices/4080000.remoteproc:bam-dmux
|
||||||
|
pm() { echo "### $(t) PM=$(cat $B/power/runtime_status) active_ms=$(cat $B/power/runtime_active_time) rproc=$(cat /sys/class/remoteproc/remoteproc0/state)"; }
|
||||||
|
cnt() { echo "### $(t) CNT $(for f in rx_packets rx_bytes tx_packets tx_bytes; do printf '%s=%s ' $f $(cat /sys/class/net/wwan0/statistics/$f); done)"; ip -s link show wwan0 2>&1; }
|
||||||
|
nv() { for want in modemst1 modemst2 fsg fsc persist; do for p in /sys/class/block/mmcblk0p*; do
|
||||||
|
[ "$(sed -n 's/^PARTNAME=//p' $p/uevent)" = "$want" ] && echo "$want $(sha256sum /dev/$(basename $p) | cut -d' ' -f1)"; done; done; }
|
||||||
|
nv > $O/nv-before.txt; cat /sys/block/mmcblk0/stat > $O/stat-before.txt; wc -l < /tmp/rmtfs.log > $O/rmtfs-offset.txt
|
||||||
|
{ mmcli -L; mmcli -m 0; mmcli -m 0 --signal-get 2>&1; pm; ip link show wwan0; ip route; ip rule; } 2>&1 | mask > $O/pre.txt
|
||||||
|
grep -qE "state: .*registered" $O/pre.txt && grep -q "packet service state: attached" $O/pre.txt || { echo "PRECHECK FAILED"; echo B4B2MM-STOPPED; exit 1; }
|
||||||
|
# --- single connect
|
||||||
|
{ pm; echo "### $(t) mmcli -m 0 --simple-connect=apn=internet,ip-type=ipv4"; timeout 150 mmcli -m 0 --simple-connect="apn=internet,ip-type=ipv4" 2>&1; echo "### rc=$?"; pm; } > $O/connect.txt
|
||||||
|
BR=$(mmcli -m 0 | grep -oE "Bearer/[0-9]+" | tail -1 | cut -d/ -f2)
|
||||||
|
{ mmcli -m 0; [ -n "$BR" ] && mmcli -b $BR; } 2>&1 | mask > $O/after-connect.txt
|
||||||
|
grep -q "^### rc=0" $O/connect.txt && [ -n "$BR" ] && mmcli -b $BR | grep -q "connected: yes" || { echo "CONNECT FAILED (bearer '$BR')"; echo B4B2MM-STOPPED; exit 1; }
|
||||||
|
T=$(mmcli -b $BR); f() { echo "$T" | awk -F": " "/ $1:/{print \$2; exit}" | tr -d " "; }
|
||||||
|
IF=$(f interface); A=$(f address); PF=$(f prefix); GW=$(f gateway); DNS=$(f dns); MTU=$(f mtu); D1=${DNS%%,*}; D2=${DNS#*,}; [ "$D2" = "$DNS" ] && D2=
|
||||||
|
echo "BR=$BR IF=$IF A=$A PF=$PF GW=$GW DNS=$DNS MTU=$MTU" > $O/bearer-ip.txt
|
||||||
|
[ "$IF" = wwan0 ] && [ -n "$A" ] && [ -n "$PF" ] || { echo "BEARER HAS NO USABLE IPv4 on wwan0"; }
|
||||||
|
# --- manual IPv4 (table 100 + source rule; host routes only for DNS servers in main)
|
||||||
|
{ cnt; ip addr add $A/$PF dev wwan0; echo "addr rc=$?"; [ -n "$MTU" ] && ip link set wwan0 mtu $MTU; ip link set wwan0 up; echo "up rc=$?"; sleep 2; pm
|
||||||
|
ip route add default via $GW dev wwan0 table 100; echo "rt100 rc=$?"; ip rule add from $A lookup 100 priority 100; echo "rule rc=$?"
|
||||||
|
for d in $D1 $D2; do ip route add $d/32 dev wwan0 src $A; done
|
||||||
|
ip addr show wwan0; echo "--- main:"; ip route; echo "--- t100:"; ip route show table 100; ip rule; } > $O/cfg.txt 2>&1
|
||||||
|
# --- IP-only ping (source = LTE address -> table 100)
|
||||||
|
{ for h in 77.88.8.8 1.1.1.1 8.8.8.8; do echo "### $(t) ping -I $A $h"; ping -c 5 -W 3 -I $A $h 2>&1; pm; done; cnt; } > $O/ping.txt 2>&1
|
||||||
|
# --- DNS via operator DNS
|
||||||
|
{ for s in $D1 $D2; do echo "### $(t) nslookup ya.ru $s"; nslookup ya.ru $s 2>&1; done; pm; cnt; } > $O/dns.txt 2>&1
|
||||||
|
{ mmcli -b $BR; mmcli -m 0 --signal-get; } 2>&1 | mask > $O/during.txt
|
||||||
|
# --- clean disconnect
|
||||||
|
{ echo "### $(t) mmcli -m 0 --simple-disconnect"; timeout 60 mmcli -m 0 --simple-disconnect 2>&1; echo "### rc=$?"; mmcli -b $BR 2>&1 | grep -E "connected|interface|address"
|
||||||
|
ip rule del from $A lookup 100 priority 100; ip route flush table 100; for d in $D1 $D2; do ip route del $d/32 dev wwan0 2>/dev/null; done
|
||||||
|
ip addr flush dev wwan0; ip link set wwan0 down; echo "down rc=$?"; ip link show wwan0; ip route; ip rule; sleep 10; pm; } > $O/disconnect.txt 2>&1
|
||||||
|
{ mmcli -m 0; pm; } 2>&1 | mask > $O/post.txt
|
||||||
|
nv > $O/nv-after.txt; cat /sys/block/mmcblk0/stat > $O/stat-after.txt
|
||||||
|
tail -n +$(( $(cat $O/rmtfs-offset.txt) + 1 )) /tmp/rmtfs.log > $O/rmtfs-delta.log
|
||||||
|
dmesg | grep -iE "bam|dmux|wwan|resume|-110|-22|Resource temporarily|Oops|panic|fatal|q6v5|watchdog|ssr" > $O/dmesg.txt
|
||||||
|
mask < /tmp/mm.log > $O/mm.log
|
||||||
|
cmp -s $O/nv-before.txt $O/nv-after.txt && echo "NV BEFORE==AFTER" > $O/nv-result.txt || echo "NV DIFFERENT" > $O/nv-result.txt
|
||||||
|
tar -C /tmp -cf /tmp/b4b2mm.tar b4b2mm; echo B4B2MM-DONE
|
||||||
12
b12/b12q/alpine-overlay/usr/local/bin/nv-check
Normal file
12
b12/b12q/alpine-overlay/usr/local/bin/nv-check
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Recompute NV hashes + eMMC stat and compare with the boot-time snapshot (read-only).
|
||||||
|
o=/tmp/nv-after.txt; : > $o
|
||||||
|
for want in modemst1 modemst2 fsg fsc persist; do
|
||||||
|
for p in /sys/class/block/mmcblk0p*; do
|
||||||
|
[ "$(sed -n 's/^PARTNAME=//p' $p/uevent)" = "$want" ] && echo "$want $(basename $p) $(sha256sum /dev/$(basename $p) | cut -d' ' -f1)" >> $o
|
||||||
|
done
|
||||||
|
done
|
||||||
|
echo "stat $(cat /sys/block/mmcblk0/stat)" >> $o
|
||||||
|
grep -v ^stat /tmp/nv-before.txt > /tmp/nvb; grep -v ^stat $o > /tmp/nva
|
||||||
|
cmp -s /tmp/nvb /tmp/nva && echo "NV-CHECK: BEFORE == AFTER ($(wc -l < /tmp/nva) partitions)" || { echo "NV-CHECK: DIFFERENT"; diff /tmp/nvb /tmp/nva; }
|
||||||
|
set -- $(sed -n 's/^stat //p' $o); echo "NV-CHECK: disk writes_completed=$5 sectors_written=$7"
|
||||||
20
b12/b12q/alpine-overlay/usr/local/bin/qmi-b3
Normal file
20
b12/b12q/alpine-overlay/usr/local/bin/qmi-b3
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B3: READ-ONLY QMI queries only (DMS/UIM/NAS "get"). No scan, no registration, no set-*, no PIN ops, no reset.
|
||||||
|
# ICCID/IMSI are masked on-device before being written anywhere.
|
||||||
|
D=${1:-/dev/wwan0qmi0}
|
||||||
|
Q="qmicli -p -d $D"
|
||||||
|
mask_iccid() { sed -E "s/([0-9]{15,22})/\1\n/; s/[0-9]+([0-9]{4})\n/************\1/"; }
|
||||||
|
mask_imsi() { sed -E "s/'([0-9]{5})[0-9]+([0-9]{3})'/'\1******\2'/"; }
|
||||||
|
run() { echo "### $*"; timeout 30 $Q "$@" 2>&1; echo "### rc=$?"; }
|
||||||
|
run --dms-get-operating-mode
|
||||||
|
run --dms-get-revision
|
||||||
|
run --dms-uim-get-state
|
||||||
|
run --uim-get-card-status
|
||||||
|
echo "### --dms-uim-get-iccid (masked)"; timeout 30 $Q --dms-uim-get-iccid 2>&1 | mask_iccid
|
||||||
|
echo "### --dms-uim-get-imsi (masked)"; timeout 30 $Q --dms-uim-get-imsi 2>&1 | mask_imsi
|
||||||
|
run --nas-get-home-network
|
||||||
|
run --nas-get-serving-system
|
||||||
|
run --nas-get-system-info
|
||||||
|
run --nas-get-signal-info
|
||||||
|
run --nas-get-system-selection-preference
|
||||||
|
run --dms-get-operating-mode
|
||||||
44
b12/b12q/alpine-overlay/usr/sbin/aurora-display
Normal file
44
b12/b12q/alpine-overlay/usr/sbin/aurora-display
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Aurora display controller (B9C). ST7735S on SPI via panel-mipi-dbi (DRM) -> fb0 -> fbcon (tty1) + MPP4 backlight.
|
||||||
|
# aurora-display start : wait for fb0, make sure the display pipe is enabled (fbcon takeover modeset, or one fbdev
|
||||||
|
# unblank if nothing enabled it), then switch the backlight on through the gpio-backlight driver.
|
||||||
|
# aurora-display status : one-line state summary
|
||||||
|
# aurora-display bl on|off
|
||||||
|
# Never writes PMIC/GPIO registers directly: only fb0 'blank' and backlight sysfs attributes of the kernel drivers.
|
||||||
|
D=/run/aurora-display; L=$D/display.log; mkdir -p $D
|
||||||
|
FB=/sys/class/graphics/fb0; CON=/sys/class/drm/card0-SPI-1; BL=/sys/class/backlight/backlight
|
||||||
|
t() { cut -d' ' -f1 /proc/uptime; }
|
||||||
|
log() { echo "[$(t)] $*" >> $L; echo "[aurora-display] $*" > /dev/kmsg 2>/dev/null; }
|
||||||
|
fbcon_bound() { for v in /sys/class/vtconsole/vtcon*; do grep -q "frame buffer" $v/name 2>/dev/null && [ "$(cat $v/bind)" = 1 ] && return 0; done; return 1; }
|
||||||
|
l17_users() { for r in /sys/class/regulator/regulator.*; do [ "$(cat $r/name 2>/dev/null)" = l17 ] && { cat $r/num_users; return; }; done; echo 0; }
|
||||||
|
pipe_on() { [ "$(cat $CON/enabled 2>/dev/null)" = enabled ] && [ "$(cat $CON/dpms 2>/dev/null)" = On ] && [ "$(l17_users)" -ge 1 ]; }
|
||||||
|
state() { echo "fb0=$([ -e $FB ] && cat $FB/name) fbcon=$(fbcon_bound && echo bound || echo no) conn=$(cat $CON/enabled 2>/dev/null)/$(cat $CON/dpms 2>/dev/null) l17_users=$(l17_users) bl_power=$(cat $BL/bl_power 2>/dev/null) bl=$(cat $BL/actual_brightness 2>/dev/null)"; }
|
||||||
|
wait_for() { n=$1; shift; i=0; until "$@"; do i=$((i+1)); [ $i -ge $n ] && return 1; sleep 0.2; done; }
|
||||||
|
bl() {
|
||||||
|
[ -d $BL ] || { log "FAIL: no backlight device"; return 1; }
|
||||||
|
case $1 in
|
||||||
|
on) echo 0 > $BL/bl_power; echo 1 > $BL/brightness;;
|
||||||
|
off) echo 0 > $BL/brightness;;
|
||||||
|
esac
|
||||||
|
log "backlight $1 -> bl_power=$(cat $BL/bl_power) actual_brightness=$(cat $BL/actual_brightness)"
|
||||||
|
}
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
log "start: $(state)"
|
||||||
|
wait_for 100 test -e $FB || { log "FAIL: fb0 did not appear within 20 s"; exit 1; }
|
||||||
|
fbcon_bound && log "fbcon bound to fb0" || log "fbcon NOT bound (no framebuffer console)"
|
||||||
|
if wait_for 25 pipe_on; then
|
||||||
|
log "display pipe already enabled (by fbcon takeover) - no unblank needed"
|
||||||
|
else
|
||||||
|
log "display pipe not enabled -> fbdev unblank"
|
||||||
|
echo 0 > $FB/blank
|
||||||
|
wait_for 25 pipe_on || { log "FAIL: pipe still not enabled after unblank: $(state)"; exit 1; }
|
||||||
|
log "display pipe enabled by unblank"
|
||||||
|
fi
|
||||||
|
bl on
|
||||||
|
[ "$(cat $BL/actual_brightness)" = 1 ] || { log "FAIL: backlight did not turn on: $(state)"; exit 1; }
|
||||||
|
log "=== DISPLAY READY $(state)";;
|
||||||
|
status) state;;
|
||||||
|
bl) bl "$2";;
|
||||||
|
*) echo "usage: $0 start|status|bl on|off"; exit 2;;
|
||||||
|
esac
|
||||||
399
b12/b12q/alpine-overlay/usr/sbin/aurora-modem
Normal file
399
b12/b12q/alpine-overlay/usr/sbin/aurora-modem
Normal file
|
|
@ -0,0 +1,399 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Aurora (JZ08AU, MSM8916) modem lifecycle controller - B6P production build of the B6N-proven controller (b6j/aurora-modem).
|
||||||
|
# aurora-modem start | disconnect | stop | status | addroute <ipv4>
|
||||||
|
# start: [rmtfs -r -P -s -v -> MSS -> wwan0qmi0 (+2 s port-race guard) -> SIM ready -> DMS online (one SET, retried only on DeviceNotReady)
|
||||||
|
# -> registration state machine (registered + PS attached, deadline REG_TIMEOUT, default 600 s)] (skipped when rmtfs+MSS already run)
|
||||||
|
# -> udevd/dbus/polkitd/ModemManager (reused if running) -> ONE simple-connect -> bearer IPv4 on wwanN + /32 routes only (no default route).
|
||||||
|
# disconnect: simple-disconnect, our routes, flush+down all wwan*, wait BAM-DMUX suspended. MSS, rmtfs, MM and radio stay up; 'start' reconnects.
|
||||||
|
# stop: disconnect -> stop MM (+qmi-proxy) -> BAM-DMUX suspended -> SIGTERM rmtfs (rmtfs writes 'stop' -> MSS offline) -> rmtfs exits last.
|
||||||
|
# Never writes eMMC/NV: rmtfs -r keeps EFS writes in RAM; refuses to start unless modemst1/2, fsc, fsg, persist, mmcblk0 are getro=1 and /firmware is ro.
|
||||||
|
# Does not need a valid wall clock (all timing from /proc/uptime). No automatic MSS/rmtfs retry.
|
||||||
|
# B7C: time bootstrap. At fixed points of start (QMI_READY, SIM_READY, RADIO_ONLINE, each REG transition, REGISTERED, BEARER_CONNECTED) logs QMI DMS
|
||||||
|
# + 3GPP NITZ. The first valid DMS (>= 2026, >= image build, plausible, |DMS-NITZ| < 2 s; NITZ required unless TIME_REQUIRE_NITZ=0) steps
|
||||||
|
# CLOCK_REALTIME once with date -s (never backwards, never RTC). After START OK, a background SNTP check (VNIIFTRI, query only) logs the residual
|
||||||
|
# and steps only if |offset| >= TIME_NTP_STEP s. No slew/discipline: STA_UNSYNC stays set, so the kernel RTC_SYSTOHC 11-min RTC write never engages.
|
||||||
|
# Exit: 0 ok, 1 failure/timeout (start rolls back with a full stop unless MODEM_KEEP_ON_FAIL=1), 2 usage/config error.
|
||||||
|
|
||||||
|
CONF=${MODEM_CONF:-/etc/aurora/modem.conf}
|
||||||
|
D=/run/aurora-modem; mkdir -p $D
|
||||||
|
LOG=$D/lifecycle.log; STATE=$D/state; ROUTES=$D/routes; BEARER=$D/bearer
|
||||||
|
RPNAME=4080000.remoteproc
|
||||||
|
BAM=/sys/bus/platform/devices/4080000.remoteproc:bam-dmux
|
||||||
|
Q="qmicli -p -d /dev/wwan0qmi0"
|
||||||
|
|
||||||
|
# --- timeouts (s); override in $CONF
|
||||||
|
T_RMTFS=5 T_MSS=60 T_QMI_DEV=30 T_QMI=45 T_SIM=60 T_ONLINE=30 T_REG=180 T_MM_DETECT=150 T_MM_REG=60 T_CONNECT=150
|
||||||
|
T_DISCONNECT=60 T_DISABLE=30 T_MM_EXIT=30 T_BAM_IDLE=15 T_MSS_STOP=30 T_RMTFS_EXIT=15
|
||||||
|
APN= USER= PASSWORD= AUTH= IP_TYPE=ipv4 REG_TIMEOUT=600 ROUTES= KEEP=${MODEM_KEEP_ON_FAIL:-0}
|
||||||
|
TIME_BOOTSTRAP=1 TIME_REQUIRE_NITZ=1 TIME_MAX_DMS_NITZ=2 TIME_NTP="ntp1.vniiftri.ru ntp2.vniiftri.ru ntp3.vniiftri.ru" TIME_NTP_STEP=1
|
||||||
|
[ -f "$CONF" ] && . "$CONF"
|
||||||
|
MODEM_APN=$APN MODEM_USER=$USER MODEM_PASSWORD=$PASSWORD MODEM_AUTH=$AUTH MODEM_IP_TYPE=${IP_TYPE:-ipv4} MODEM_TEST_ROUTES=$ROUTES T_REG=${REG_TIMEOUT:-600}
|
||||||
|
MODEM_KEEP_ON_FAIL=${MODEM_KEEP_ON_FAIL:-$KEEP}
|
||||||
|
|
||||||
|
mmc() { mmcli "$@" 2>/dev/null | tr -d '\033' | sed 's/\[[0-9;]*m//g'; } # mmcli colours values even without a tty
|
||||||
|
now() { cut -d' ' -f1 /proc/uptime; }
|
||||||
|
log() { m="[$(now)] $*"; echo "$m" >> $LOG; echo "$m"; echo "<5>[aurora-modem] $*" > /dev/kmsg 2>/dev/null; }
|
||||||
|
setstate() { o=$(cat $STATE 2>/dev/null); echo "$1" > $STATE; log "STATE ${o:-OFF} -> $1"; }
|
||||||
|
die() { log "FAIL: $*"; exit 1; }
|
||||||
|
# wait_for TIMEOUT INTERVAL cmd... : poll a real condition, no blind sleeps
|
||||||
|
wait_for() { _to=$1; _iv=$2; shift 2; _t0=$(now)
|
||||||
|
while :; do "$@" && return 0
|
||||||
|
[ "$(awk -v a="$(now)" -v b="$_t0" -v t="$_to" 'BEGIN{print (a-b>=t)}')" = 1 ] && return 1
|
||||||
|
sleep $_iv; done; }
|
||||||
|
since() { awk -v a="$(now)" -v b="$1" 'BEGIN{printf "%.1f", a-b}'; }
|
||||||
|
|
||||||
|
rp() { for r in /sys/class/remoteproc/remoteproc*; do [ "$(cat $r/name 2>/dev/null)" = $RPNAME ] && echo $r && return; done; }
|
||||||
|
mss_state() { r=$(rp); [ -n "$r" ] && cat $r/state || echo none; }
|
||||||
|
mss_is() { [ "$(mss_state)" = "$1" ]; }
|
||||||
|
rmtfs_pid() { pidof rmtfs; }
|
||||||
|
mm_pid() { pidof ModemManager; }
|
||||||
|
bam_pm() { cat $BAM/power/runtime_status 2>/dev/null || echo none; }
|
||||||
|
bam_suspended() { [ "$(bam_pm)" = suspended ]; }
|
||||||
|
qmi_dev() { [ -e /dev/wwan0qmi0 ] && [ -e /sys/class/net/wwan0 ]; }
|
||||||
|
link_up() { [ $(( $(cat /sys/class/net/$1/flags) & 1 )) -ne 0 ]; }
|
||||||
|
mm_idx() { mmc -L | grep -oE "Modem/[0-9]+" | head -1 | cut -d/ -f2; }
|
||||||
|
mm_has_modem() { [ -n "$(mm_idx)" ]; }
|
||||||
|
mm_state() { mmc -m "$(mm_idx)" | awk -F': ' '/\| +state: /{gsub(/ /,"",$2); print $2; exit}'; }
|
||||||
|
# MM initialized: proven session 22 pass 1 connected from 'disabled' (Simple.Connect enables the modem itself)
|
||||||
|
mm_usable() { case "$(mm_state)" in disabled|enabling|enabled|searching|registered|connected|connecting) return 0;; esac; return 1; }
|
||||||
|
qmi_ok() { timeout 20 $Q --dms-get-operating-mode > $D/qmi-mode.txt 2>&1 && grep -q "Mode:" $D/qmi-mode.txt; }
|
||||||
|
qmi_reg() { timeout 20 $Q --nas-get-serving-system > $D/qmi-ss.txt 2>&1
|
||||||
|
grep -q "Registration state: 'registered'" $D/qmi-ss.txt && grep -q "PS: 'attached'" $D/qmi-ss.txt; }
|
||||||
|
sim_ready() { timeout 20 $Q --uim-get-card-status > $D/qmi-uim.txt 2>&1
|
||||||
|
grep -q "Card state: 'present'" $D/qmi-uim.txt && grep -q "Application state: 'ready'" $D/qmi-uim.txt; }
|
||||||
|
set_online() { timeout 20 $Q --dms-set-operating-mode=online > $D/qmi-set.txt 2>&1; r=$?; cat $D/qmi-set.txt >> $LOG
|
||||||
|
[ $r = 0 ] && return 0; grep -q "DeviceNotReady" $D/qmi-set.txt || { echo hard > $D/qmi-set.err; return 0; }; return 1; }
|
||||||
|
# this mmcli has no --list-bearers ("no actions specified"); use 'Bearer | paths:' of mmcli -m, not the initial (attach) bearer
|
||||||
|
bearers() { mmc -m "$(mm_idx)" | grep -v "initial bearer" | grep -oE "Bearer/[0-9]+" | cut -d/ -f2; }
|
||||||
|
any_bearer_connected() { for b in $(bearers); do mmc -b $b | grep -q "connected: yes" && return 0; done; return 1; }
|
||||||
|
qv() { grep -m1 -oE "$1: *'[^']*'" $2 2>/dev/null | sed -E "s/.*'([^']*)'/\1/"; }
|
||||||
|
# B6M registration state machine. rc 0 = registered+PS attached, 1 = REGISTRATION_TIMEOUT, 2 = local failure (reason in $D/reg-fail)
|
||||||
|
reg_sm() {
|
||||||
|
T=$D/reg-trans.tsv; t0=$1; last=; n=0; nd=0; rm -f $D/reg-fail; D0=$(dmesg | wc -l)
|
||||||
|
printf 'uptime t_online reg ps status true_status domain plmn earfcn pci si_tac si_eci cl_tac cl_eci rsrp rsrq snr
|
||||||
|
' > $T
|
||||||
|
lf() { echo "$*" > $D/reg-fail; return 2; }
|
||||||
|
while :; do n=$((n+1))
|
||||||
|
mss_is running || { lf "MSS state $(mss_state)"; return 2; }
|
||||||
|
[ -e /dev/wwan0qmi0 ] || { lf "wwan0qmi0 disappeared"; return 2; }
|
||||||
|
[ -n "$(rmtfs_pid)" ] || { lf "rmtfs died"; return 2; }
|
||||||
|
[ "$(bam_pm)" = error ] && { lf "BAM-DMUX runtime_status=error"; return 2; }
|
||||||
|
dmesg | tail -n +$((D0+1)) | grep -qE 'crash detected|fatal error|[Ww]atchdog|wdog|Oops|BUG:|Failed to resume' && { lf "dmesg: $(dmesg | tail -n +$((D0+1)) | grep -m1 -E 'crash detected|fatal error|[Ww]atchdog|wdog|Oops|BUG:|Failed to resume')"; return 2; }
|
||||||
|
if [ $((n % 5)) = 1 ]; then
|
||||||
|
sim_ready || { lf "SIM not ready: $(grep -E 'Card state|Application state' $D/qmi-uim.txt | head -2 | tr -s ' \t\n' ' ')"; return 2; }
|
||||||
|
ping -c1 -W2 172.16.42.2 >/dev/null 2>&1 || { sleep 1; ping -c1 -W2 172.16.42.2 >/dev/null 2>&1 || { lf "USB management (usb0 ping) lost"; return 2; }; }
|
||||||
|
fi
|
||||||
|
timeout 20 $Q --nas-get-serving-system > $D/qmi-ss.txt 2>&1
|
||||||
|
timeout 20 $Q --nas-get-system-info > $D/qmi-si-all.txt 2>&1; sed -n '/LTE service:/,/SIM reject/p' $D/qmi-si-all.txt > $D/qmi-si.txt
|
||||||
|
RG=$(qv 'Registration state' $D/qmi-ss.txt); PS=$(qv PS $D/qmi-ss.txt); ST=$(qv Status $D/qmi-si.txt); TS=$(qv 'True Status' $D/qmi-si.txt)
|
||||||
|
DM=$(qv Domain $D/qmi-si.txt); PL=$(qv MCC $D/qmi-si.txt)-$(qv MNC $D/qmi-si.txt); SIT=$(qv 'Tracking Area Code' $D/qmi-si.txt); SIE=$(qv 'Cell ID' $D/qmi-si.txt)
|
||||||
|
key="$RG|$PS|$ST|$TS|$DM|$PL|$SIT|$SIE"
|
||||||
|
if [ "$key" != "$last" ]; then
|
||||||
|
timeout 20 $Q --nas-get-cell-location-info > $D/qmi-cl.txt 2>&1; timeout 20 $Q --nas-get-signal-info > $D/qmi-sig.txt 2>&1
|
||||||
|
[ "$RG" = registration-denied ] && [ "${last%%|*}" != registration-denied ] && nd=$((nd+1))
|
||||||
|
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' $(now) $(since $t0) "$RG" "$PS" "$ST" "$TS" "$DM" "$PL" \
|
||||||
|
"$(qv 'EUTRA Absolute RF Channel Number' $D/qmi-cl.txt)" "$(qv 'Serving Cell ID' $D/qmi-cl.txt)" "$SIT" "$SIE" \
|
||||||
|
"$(qv 'Tracking Area Code' $D/qmi-cl.txt)" "$(qv 'Global Cell ID' $D/qmi-cl.txt)" "$(qv RSRP $D/qmi-sig.txt)" "$(qv RSRQ $D/qmi-sig.txt)" "$(qv SNR $D/qmi-sig.txt)" >> $T
|
||||||
|
log "REG t+$(since $t0)s: $RG / PS $PS / $ST ($TS, $DM) $PL pci=$(qv 'Serving Cell ID' $D/qmi-cl.txt) si=$SIT/$SIE cl=$(qv 'Tracking Area Code' $D/qmi-cl.txt)/$(qv 'Global Cell ID' $D/qmi-cl.txt)"
|
||||||
|
last=$key; tprobe "REG:$RG/$PS"
|
||||||
|
fi
|
||||||
|
echo $nd > $D/reg-denied-count
|
||||||
|
[ "$RG" = registered ] && [ "$PS" = attached ] && return 0
|
||||||
|
[ "$(awk -v a="$(now)" -v b="$t0" -v t="$T_REG" 'BEGIN{print (a-b>=t)}')" = 1 ] && { lf "REGISTRATION_TIMEOUT after ${T_REG}s ($RG, PS $PS)"; return 1; }
|
||||||
|
sleep 3
|
||||||
|
done
|
||||||
|
}
|
||||||
|
bearer_field() { awk -F': ' -v k="$1" '$1 ~ " "k"$" {gsub(/ /,"",$2); print $2; exit}' $BEARER.txt; }
|
||||||
|
|
||||||
|
# --- B7C time bootstrap. Variables are _t-prefixed: tprobe runs inside reg_sm (n, T, last, t0 belong to it).
|
||||||
|
NTPBB=/usr/libexec/aurora/busybox; GPS_EPOCH=315964800; Y2026=1767225600
|
||||||
|
time_floor() { _tf=$(cat /etc/aurora/build-epoch 2>/dev/null); case "$_tf" in ''|*[!0-9]*) _tf=$Y2026;; esac; [ $_tf -lt $Y2026 ] && _tf=$Y2026; echo $_tf; }
|
||||||
|
# tprobe PHASE: read DMS + NITZ (raw kept in $D/time-probe-N.*), validate, log; first VALID sample while the clock is still pre-build -> tset
|
||||||
|
tprobe() {
|
||||||
|
[ "$TIME_BOOTSTRAP" = 1 ] || return 0
|
||||||
|
_tn=$(( $(cat $D/time-probes 2>/dev/null || echo 0) + 1 )); echo $_tn > $D/time-probes; _tp=$D/time-probe-$_tn
|
||||||
|
_u0=$(now); timeout 5 $Q --dms-get-time > $_tp.dms 2>&1; _u1=$(now); timeout 5 $Q --nas-get-network-time > $_tp.nitz 2>&1; _u2=$(now)
|
||||||
|
_ms=$(sed -n "s/.*System time: '\([0-9]*\).*/\1/p" $_tp.dms); _nd=$(qv '3GPP Date' $_tp.nitz); _nt=$(qv '3GPP Time' $_tp.nitz)
|
||||||
|
_ne=; [ -n "$_nd" ] && [ -n "$_nt" ] && _ne=$(date -u -d "$_nd $_nt" +%s 2>/dev/null); _clk=$(date -u +%s)
|
||||||
|
# -> "VERDICT dms_utc dms_uptime dms-nitz reason"; dms-nitz compares DMS projected to the NITZ read instant with whole-second NITZ
|
||||||
|
_v=$(awk -v ms="$_ms" -v g=$GPS_EPOCH -v u0=$_u0 -v u1=$_u1 -v u2=$_u2 -v ne="$_ne" -v fl=$(time_floor) -v y=$Y2026 -v rn=$TIME_REQUIRE_NITZ -v mx=$TIME_MAX_DMS_NITZ 'BEGIN{
|
||||||
|
if (ms !~ /^[0-9]+$/) { print "INVALID - - - dms-unreadable"; exit }
|
||||||
|
dms=ms/1000+g; at=(u0+u1)/2; r="ok"; d="-"
|
||||||
|
if (dms < y) r="year<2026"; else if (dms < fl) r="before-build"; else if (dms > fl+5*365*86400) r="implausible"
|
||||||
|
if (ne ~ /^[0-9]+$/) { dd=dms+((u1+u2)/2-at)-ne; d=sprintf("%+.2f", dd); if (r=="ok" && (dd<-mx || dd>mx)) r="dms-nitz-mismatch" }
|
||||||
|
else if (r=="ok" && rn==1) r="no-nitz"
|
||||||
|
printf "%s %.3f %.2f %s %s\n", (r=="ok" ? "VALID" : "INVALID"), dms, at, d, r }')
|
||||||
|
set -- "$1" $_v
|
||||||
|
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' $_tn "$1" $_u0 "${_ms:--}" "$3" "${_nd:--}T${_nt:--}" "$5" $_clk "$2/$6" >> $D/time.tsv
|
||||||
|
log "TIME probe $_tn [$1]: dms_ms=${_ms:-none} dms_utc=$3 nitz=${_nd:-none} ${_nt} dms-nitz=$5 clock=$_clk -> $2 ($6)"
|
||||||
|
[ "$2" = VALID ] && [ ! -f $D/time-set ] && [ $_clk -lt $(time_floor) ] && tset "$1" $3 $4 $5
|
||||||
|
return 0; }
|
||||||
|
# tset PHASE DMS_UTC DMS_UPTIME DIFF: step CLOCK_REALTIME once, landing on a whole UTC second (uptime-based wait, no fixed bias correction)
|
||||||
|
tset() {
|
||||||
|
_N=$(awk -v d=$2 -v a=$3 -v u=$(now) 'BEGIN{printf "%d", int(d+(u-a))+1}')
|
||||||
|
_w=$(awk -v N=$_N -v d=$2 -v a=$3 -v u=$(now) 'BEGIN{w=N-(d+(u-a)); printf "%.3f", (w>0 ? w : 0)}')
|
||||||
|
sleep $_w; _old=$(date -u +%s); [ $_N -gt $_old ] || { log "TIME SET skipped: target $_N not after clock $_old (never backwards)"; return 0; }
|
||||||
|
date -u -s @$_N > /dev/null 2>&1; _rc=$?
|
||||||
|
[ $_rc = 0 ] && echo "$_N $(now) $1 qmi-dms" > $D/time-set
|
||||||
|
log "TIME SET rc=$_rc source=qmi-dms phase=$1 old=$_old ($(date -u -d @$_old '+%F %T')) new=$_N ($(date -u '+%F %T')) uptime=$(now) dms-nitz=$4 validation=VALID rtc=untouched"; }
|
||||||
|
# after START OK, background: resolve VNIIFTRI via bearer DNS, /32 routes via addroute (removed by stop/disconnect), ntpd -w (query only)
|
||||||
|
time_sntp() {
|
||||||
|
[ "$TIME_BOOTSTRAP" = 1 ] && [ -x $NTPBB ] && [ -n "$TIME_NTP" ] || { log "SNTP: skipped (bootstrap=$TIME_BOOTSTRAP bin=$([ -x $NTPBB ] && echo yes || echo no))"; return 0; }
|
||||||
|
. $D/ipcfg 2>/dev/null || return 0; _dns=${DNS%%,*}; _ips=
|
||||||
|
for _h in $TIME_NTP; do _ip=$(nslookup $_h $_dns 2>/dev/null | awk '/^Name:/{f=1} f && /^Address/{print $2; exit}')
|
||||||
|
case "$_ip" in [0-9]*.[0-9]*.[0-9]*.[0-9]*) addroute $_ip && _ips="$_ips $_ip";; *) log "SNTP: $_h not resolved via $_dns";; esac; done
|
||||||
|
[ -n "$_ips" ] || return 0
|
||||||
|
_a=; for _ip in $_ips; do _a="$_a -p $_ip"; done
|
||||||
|
timeout 15 $NTPBB ntpd -w -d $_a > $D/sntp.txt 2>&1
|
||||||
|
_b=$(awk '/reply from/{o="";d=""; for(i=1;i<=NF;i++){ if($i~/^offset:/) o=substr($i,8); if($i~/^delay:/) d=substr($i,7) } if(o!="" && (bd=="" || d+0<bd+0)){b=o; bd=d; s=$4}}
|
||||||
|
END{ if (b!="") print b, bd, s }' $D/sntp.txt)
|
||||||
|
log "SNTP check ($_ips): $(grep -c 'reply from' $D/sntp.txt) replies; best offset delay server: ${_b:-none} (offset > 0 = clock behind)"
|
||||||
|
[ -n "$_b" ] || return 0
|
||||||
|
if [ "$(awk -v o=${_b%% *} -v s=$TIME_NTP_STEP 'BEGIN{print (o>=s || o<=-s)}')" = 1 ]; then
|
||||||
|
_old=$(date -u +%s); _N=$(awk -v c=$_old -v o=${_b%% *} 'BEGIN{printf "%d", c+o+0.5}'); date -u -s @$_N > /dev/null 2>&1
|
||||||
|
log "SNTP STEP rc=$? old=$_old new=$_N (|offset| >= ${TIME_NTP_STEP}s) rtc=untouched"
|
||||||
|
else log "SNTP: |offset| < ${TIME_NTP_STEP}s - clock kept (no slew: STA_UNSYNC stays, RTC_SYSTOHC never engages)"; fi; }
|
||||||
|
|
||||||
|
check_safety() {
|
||||||
|
for p in modemst1 modemst2 fsc fsg persist; do
|
||||||
|
d=/dev/disk/by-partlabel/$p; [ -e $d ] || return 1
|
||||||
|
[ "$(blockdev --getro $(readlink -f $d))" = 1 ] || { log "SAFETY: $p not RO"; return 1; }
|
||||||
|
done
|
||||||
|
if [ "$(blockdev --getro /dev/mmcblk0)" != 1 ]; then # B12P: the disk flag may be lifted only for the Alpine userdata mount
|
||||||
|
_ud=$(readlink -f /dev/disk/by-partlabel/userdata 2>/dev/null)
|
||||||
|
for x in /dev/mmcblk0p* /dev/mmcblk0boot0 /dev/mmcblk0boot1; do [ "$x" = "$_ud" ] && continue
|
||||||
|
[ "$(blockdev --getro $x)" = 1 ] || { log "SAFETY: mmcblk0 not RO ($x rw)"; return 1; }; done
|
||||||
|
fi
|
||||||
|
grep -q " /firmware .* ro," /proc/mounts || { log "SAFETY: /firmware not mounted ro"; return 1; }
|
||||||
|
[ "$(cat /sys/module/firmware_class/parameters/path)" = /firmware/image ] || { log "SAFETY: firmware path"; return 1; }
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
connect_args() {
|
||||||
|
for v in "$MODEM_APN" "$MODEM_USER" "$MODEM_PASSWORD" "$MODEM_AUTH" "$MODEM_IP_TYPE"; do
|
||||||
|
case "$v" in *[,\"\'=]*) echo "BAD"; return;; esac; done
|
||||||
|
a="apn=$MODEM_APN"
|
||||||
|
[ -n "$MODEM_USER" ] && a="$a,user=$MODEM_USER"
|
||||||
|
[ -n "$MODEM_PASSWORD" ] && a="$a,password=$MODEM_PASSWORD"
|
||||||
|
[ -n "$MODEM_AUTH" ] && a="$a,allowed-auth=$MODEM_AUTH"
|
||||||
|
echo "$a,ip-type=$MODEM_IP_TYPE"
|
||||||
|
}
|
||||||
|
addroute() { # /32 via the bearer interface, recorded so stop removes exactly what we added
|
||||||
|
ip=$1; . $D/ipcfg 2>/dev/null || { echo "no bearer ipcfg"; return 1; }
|
||||||
|
grep -qx "$ip" $ROUTES 2>/dev/null && return 0
|
||||||
|
ip route add $ip/32 dev $IF src $A && echo $ip >> $ROUTES
|
||||||
|
}
|
||||||
|
diag() { # snapshot before rollback
|
||||||
|
{ echo "### diag $(now) state=$(cat $STATE 2>/dev/null) mss=$(mss_state) rmtfs=$(rmtfs_pid) mm=$(mm_pid) bam=$(bam_pm)"
|
||||||
|
[ -n "$(mm_pid)" ] && { mmc -L; mmc -m "$(mm_idx)"; }
|
||||||
|
cat $D/qmi-mode.txt $D/qmi-ss.txt 2>/dev/null; dmesg | tail -40; } > $D/diag-$(now).txt 2>&1
|
||||||
|
}
|
||||||
|
fail_start() { log "FAIL in $(cat $STATE 2>/dev/null): $*"; diag
|
||||||
|
if [ "$MODEM_KEEP_ON_FAIL" = 1 ]; then log "MODEM_KEEP_ON_FAIL=1: leaving stack as is"
|
||||||
|
else log "rollback: full stop"; do_stop; fi
|
||||||
|
exit 1; }
|
||||||
|
|
||||||
|
do_start() {
|
||||||
|
T0=$(now); log "=== START (conf $CONF, apn '${MODEM_APN}', ip-type $MODEM_IP_TYPE)"
|
||||||
|
[ -n "$MODEM_APN" ] || { log "config: MODEM_APN empty - refusing (no APN guessing)"; exit 2; }
|
||||||
|
CA=$(connect_args); [ "$CA" = BAD ] && { log "config: forbidden character in APN/user/password/auth"; exit 2; }
|
||||||
|
check_safety || { log "FAIL: safety gate (RO) - nothing started"; exit 1; }
|
||||||
|
[ -n "$(rp)" ] || { log "FAIL: remoteproc $RPNAME not found"; exit 1; }
|
||||||
|
|
||||||
|
# OFF -> RMTFS_READY -> MPSS_BOOTING -> MPSS_RUNNING
|
||||||
|
if [ -n "$(rmtfs_pid)" ] && mss_is running; then log "rmtfs $(rmtfs_pid) + MSS running already - reuse"
|
||||||
|
elif [ -n "$(rmtfs_pid)" ] || ! mss_is offline; then
|
||||||
|
log "FAIL: inconsistent (rmtfs='$(rmtfs_pid)' MSS=$(mss_state)); run stop first"; exit 1
|
||||||
|
else
|
||||||
|
: > $ROUTES; rm -f $D/ipcfg
|
||||||
|
n0=$(grep -c 'registering services' $D/rmtfs.log 2>/dev/null)
|
||||||
|
LD_PRELOAD=/usr/lib/linebuf.so rmtfs -r -P -s -v >> $D/rmtfs.log 2>&1 &
|
||||||
|
echo $! > $D/rmtfs.pid
|
||||||
|
wait_for $T_RMTFS 0.2 sh -c "kill -0 $(cat $D/rmtfs.pid) 2>/dev/null && [ \$(grep -c 'registering services' $D/rmtfs.log) -gt ${n0:-0} ]" \
|
||||||
|
|| fail_start "rmtfs did not start (pid $(cat $D/rmtfs.pid))"
|
||||||
|
setstate RMTFS_READY
|
||||||
|
setstate MPSS_BOOTING
|
||||||
|
t=$(now); wait_for $T_MSS 0.2 mss_is running || fail_start "MSS not running after ${T_MSS}s (state $(mss_state))"
|
||||||
|
log "MSS running after $(since $t)s"
|
||||||
|
fi
|
||||||
|
setstate MPSS_RUNNING
|
||||||
|
|
||||||
|
# -> QMI_READY
|
||||||
|
t=$(now); wait_for $T_QMI_DEV 0.2 qmi_dev || fail_start "wwan0qmi0/wwan0 missing after ${T_QMI_DEV}s"
|
||||||
|
log "wwan0qmi0 + wwan0 present after $(since $t)s; +2 s (JZ02 rpmsg_wwan_ctrl port-race guard, proven start_post)"
|
||||||
|
sleep 2
|
||||||
|
[ "$(bam_pm)" = error ] && fail_start "BAM-DMUX runtime_status=error"
|
||||||
|
|
||||||
|
# -> RADIO_ONLINE -> REGISTERED (Aurora-proven: qmicli online + NAS poll before ModemManager)
|
||||||
|
if [ -n "$(mm_pid)" ]; then
|
||||||
|
log "ModemManager already running - skip qmicli, use MM state"
|
||||||
|
setstate QMI_READY
|
||||||
|
else
|
||||||
|
t=$(now); wait_for $T_QMI 1 qmi_ok || fail_start "QMI DMS not answering after ${T_QMI}s"
|
||||||
|
setstate QMI_READY; log "DMS $(grep -o "Mode: '[^']*'" $D/qmi-mode.txt) after $(since $t)s"; tprobe QMI_READY
|
||||||
|
t=$(now); wait_for $T_SIM 1 sim_ready || fail_start "SIM/USIM not ready after ${T_SIM}s ($(grep -E "Card state|Application state" $D/qmi-uim.txt | head -2 | tr -s ' \t\n' ' '))"
|
||||||
|
setstate SIM_READY; log "UIM card present, USIM app ready after $(since $t)s"; tprobe SIM_READY
|
||||||
|
if ! grep -q "Mode: 'online'" $D/qmi-mode.txt; then
|
||||||
|
log "SET: $Q --dms-set-operating-mode=online (retried only on DeviceNotReady, <= ${T_ONLINE}s)"
|
||||||
|
rm -f $D/qmi-set.err; t=$(now); wait_for $T_ONLINE 1 set_online || fail_start "SET online: DeviceNotReady for ${T_ONLINE}s"
|
||||||
|
[ -f $D/qmi-set.err ] && fail_start "SET online failed: $(grep -i error $D/qmi-set.txt | head -1)"
|
||||||
|
qmi_ok && grep -q "Mode: 'online'" $D/qmi-mode.txt || fail_start "mode not online after SET"
|
||||||
|
log "DMS online after $(since $t)s"
|
||||||
|
fi
|
||||||
|
setstate RADIO_ONLINE; tprobe RADIO_ONLINE
|
||||||
|
t=$(now); reg_sm $t; rr=$?
|
||||||
|
[ $rr = 2 ] && fail_start "LOCAL FAILURE during registration: $(cat $D/reg-fail)"
|
||||||
|
[ $rr = 1 ] && fail_start "$(cat $D/reg-fail)"
|
||||||
|
|
||||||
|
log "registered: $(grep -oE "(MCC|MNC|Description): '[^']*'" $D/qmi-ss.txt | tr '\n' ' ')after $(since $t)s"
|
||||||
|
setstate REGISTERED; tprobe REGISTERED
|
||||||
|
killall qmi-proxy 2>/dev/null; wait_for 5 0.2 sh -c '! pidof qmi-proxy >/dev/null'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# -> MM_READY (mm-up order: udevd, trigger, settle, dbus, polkitd, ModemManager)
|
||||||
|
pidof udevd >/dev/null || { udevd --daemon; udevadm trigger --action=add; udevadm settle --timeout=15; log "udevd started"; }
|
||||||
|
if ! pidof dbus-daemon >/dev/null; then
|
||||||
|
mkdir -p /run/dbus /var/lib/dbus /var/lib/polkit; rm -f /run/dbus/pid; dbus-uuidgen --ensure
|
||||||
|
dbus-daemon --system --fork || fail_start "dbus-daemon"; log "dbus started"; fi
|
||||||
|
pidof polkitd >/dev/null || { /usr/lib/polkit-1/polkitd --no-debug >> $D/polkitd.log 2>&1 & log "polkitd started"; }
|
||||||
|
if [ -z "$(mm_pid)" ]; then
|
||||||
|
N=$(ls $D/mm-*.log 2>/dev/null | wc -l)
|
||||||
|
ModemManager --debug > $D/mm-$N.log 2>&1 &
|
||||||
|
echo $! > $D/mm.pid; log "ModemManager started pid $! (log mm-$N.log)"
|
||||||
|
fi
|
||||||
|
t=$(now); wait_for $T_MM_DETECT 2 mm_has_modem || fail_start "MM: no modem after ${T_MM_DETECT}s"
|
||||||
|
log "MM modem $(mm_idx) detected after $(since $t)s"
|
||||||
|
mmc -m "$(mm_idx)" > $D/mm-modem.txt
|
||||||
|
grep -q "plugin: qcom-soc" $D/mm-modem.txt || fail_start "MM plugin is not qcom-soc"
|
||||||
|
grep -q "primary port: wwan0qmi0" $D/mm-modem.txt || fail_start "MM primary port is not wwan0qmi0"
|
||||||
|
setstate MM_READY
|
||||||
|
t=$(now); wait_for $T_MM_REG 2 mm_usable || fail_start "MM state '$(mm_state)' not usable after ${T_MM_REG}s"
|
||||||
|
log "MM state $(mm_state) after $(since $t)s"
|
||||||
|
|
||||||
|
# -> BEARER_CONNECTED (exactly one simple-connect)
|
||||||
|
if any_bearer_connected; then log "bearer already connected - reuse"
|
||||||
|
else
|
||||||
|
log "mmcli -m $(mm_idx) --simple-connect=\"$(echo "$CA" | sed 's/password=[^,]*/password=***/')\""
|
||||||
|
timeout $T_CONNECT mmcli -m "$(mm_idx)" --simple-connect="$CA" >> $LOG 2>&1 || fail_start "simple-connect failed/timeout"
|
||||||
|
fi
|
||||||
|
BR=; for b in $(bearers); do mmc -b $b | grep -q "connected: yes" && BR=$b; done
|
||||||
|
[ -n "$BR" ] || fail_start "no connected bearer after simple-connect"
|
||||||
|
mmc -m "$(mm_idx)" > $D/mm-modem.txt
|
||||||
|
grep -qE "registration: (home|roaming)" $D/mm-modem.txt || fail_start "MM registration not home/roaming after connect"
|
||||||
|
log "MM state $(mm_state), $(grep -oE "registration: [a-z]+" $D/mm-modem.txt)"
|
||||||
|
mmc -b $BR > $BEARER.txt
|
||||||
|
IF=$(bearer_field interface); A=$(bearer_field address); PF=$(bearer_field prefix); GW=$(bearer_field gateway)
|
||||||
|
DNS=$(bearer_field dns); MTU=$(bearer_field mtu)
|
||||||
|
echo "$IF" | grep -qE '^wwan[0-7]$' && [ -n "$A" ] && [ -n "$PF" ] || fail_start "bearer $BR bad ipv4 config IF=$IF A=$A PF=$PF"
|
||||||
|
printf 'BR=%s\nIF=%s\nA=%s\nPF=%s\nGW=%s\nDNS=%s\nMTU=%s\n' "$BR" "$IF" "$A" "$PF" "$GW" "$DNS" "$MTU" > $D/ipcfg
|
||||||
|
log "bearer $BR: $IF $A/$PF gw $GW dns $DNS mtu $MTU"
|
||||||
|
ip addr flush dev $IF; ip addr add $A/$PF dev $IF || fail_start "ip addr add"
|
||||||
|
[ -n "$MTU" ] && ip link set $IF mtu $MTU
|
||||||
|
ip link set $IF up || fail_start "ip link set $IF up (bam-dmux runtime PM?)"
|
||||||
|
link_up $IF || fail_start "$IF not UP"
|
||||||
|
for h in $(echo "$DNS" | tr ',' ' ') $MODEM_TEST_ROUTES; do addroute $h || fail_start "route $h"; done
|
||||||
|
ip route get 172.16.42.2 2>&1 | grep -q "dev usb0" || fail_start "management route no longer via usb0"
|
||||||
|
ip route | grep -q "^default" && log "WARNING: a default route exists (not created by us)"
|
||||||
|
setstate BEARER_CONNECTED
|
||||||
|
log "=== START OK in $(since $T0)s ($IF $A/$PF, routes: $(tr '\n' ' ' < $ROUTES))"
|
||||||
|
tprobe BEARER_CONNECTED; ( time_sntp ) &
|
||||||
|
}
|
||||||
|
|
||||||
|
do_stop() {
|
||||||
|
T0=$(now); log "=== STOP (from $(cat $STATE 2>/dev/null || echo OFF): mss=$(mss_state) rmtfs=$(rmtfs_pid) mm=$(mm_pid) bam=$(bam_pm))"
|
||||||
|
rc=0
|
||||||
|
# 1. disconnect bearer(s)
|
||||||
|
if [ -n "$(mm_pid)" ] && mm_has_modem; then
|
||||||
|
timeout $T_DISCONNECT mmcli -m "$(mm_idx)" --simple-disconnect >> $LOG 2>&1; log "simple-disconnect rc=$? (bearers: $(bearers | tr '\n' ' '))"
|
||||||
|
wait_for 15 1 sh -c "! sh $0 _anyconn" && log "no bearer connected" || { log "WARNING: bearer still connected"; rc=1; }
|
||||||
|
fi
|
||||||
|
# 2. our /32 routes, 3. flush + DOWN every wwan*
|
||||||
|
for h in $(cat $ROUTES 2>/dev/null); do ip route del $h/32 2>/dev/null; done; : > $ROUTES
|
||||||
|
for d in /sys/class/net/wwan*; do [ -e "$d" ] || continue; w=${d##*/}
|
||||||
|
ip addr flush dev $w 2>/dev/null; ip link set $w down 2>/dev/null
|
||||||
|
link_up $w && { log "ERROR: $w still UP"; rc=1; }; done
|
||||||
|
rm -f $D/ipcfg
|
||||||
|
ip route | grep -q " dev wwan" && { log "ERROR: routes via wwan remain: $(ip route | grep ' dev wwan' | tr '\n' ';')"; rc=1; }
|
||||||
|
log "wwan links down, addresses/routes removed"
|
||||||
|
[ -n "$(cat $STATE 2>/dev/null)" ] && setstate WWAN_DOWN
|
||||||
|
# 4. stop ModemManager (+ its qmi-proxy)
|
||||||
|
if [ -n "$(mm_pid)" ]; then
|
||||||
|
kill -TERM $(mm_pid); wait_for $T_MM_EXIT 0.5 sh -c '! pidof ModemManager >/dev/null' \
|
||||||
|
|| { log "MM did not exit in ${T_MM_EXIT}s - SIGKILL"; kill -KILL $(mm_pid) 2>/dev/null; rc=1; }
|
||||||
|
log "ModemManager stopped"
|
||||||
|
fi
|
||||||
|
pidof qmi-proxy >/dev/null && { killall qmi-proxy; wait_for 5 0.2 sh -c '! pidof qmi-proxy >/dev/null'; log "qmi-proxy stopped"; }
|
||||||
|
setstate MM_STOPPED
|
||||||
|
# 5. BAM-DMUX idle
|
||||||
|
if [ -e $BAM ] && ! mss_is offline; then
|
||||||
|
t=$(now); if wait_for $T_BAM_IDLE 0.5 bam_suspended; then log "BAM-DMUX suspended after $(since $t)s"
|
||||||
|
else log "ERROR: BAM-DMUX '$(bam_pm)' not suspended after ${T_BAM_IDLE}s - NOT stopping MSS"; exit 1; fi
|
||||||
|
fi
|
||||||
|
# 6. MSS stop via rmtfs -s (SIGTERM -> pwrite "stop" to remoteproc state -> exit), 7. rmtfs exits last
|
||||||
|
P=$(rmtfs_pid)
|
||||||
|
if [ -n "$P" ]; then
|
||||||
|
t=$(now); kill -TERM $P; log "SIGTERM rmtfs $P (rmtfs stops MSS, then exits)"
|
||||||
|
wait_for $T_MSS_STOP 0.2 mss_is offline && log "MSS offline after $(since $t)s (rmtfs alive: $(kill -0 $P 2>/dev/null && echo yes || echo no))" \
|
||||||
|
|| { log "ERROR: MSS '$(mss_state)' after ${T_MSS_STOP}s"; rc=1; }
|
||||||
|
setstate MPSS_STOPPED
|
||||||
|
wait_for $T_RMTFS_EXIT 0.2 sh -c "! kill -0 $P 2>/dev/null" && log "rmtfs exited after $(since $t)s" \
|
||||||
|
|| { log "rmtfs still alive - second SIGTERM"; kill -TERM $P; wait_for 5 0.2 sh -c "! kill -0 $P 2>/dev/null" || { kill -KILL $P; rc=1; }; }
|
||||||
|
elif ! mss_is offline && [ -n "$(rp)" ]; then
|
||||||
|
log "MSS $(mss_state) without rmtfs - echo stop > state"; echo stop > $(rp)/state
|
||||||
|
wait_for $T_MSS_STOP 0.2 mss_is offline || rc=1
|
||||||
|
fi
|
||||||
|
mss_is offline || mss_is none || { log "ERROR: MSS state $(mss_state)"; rc=1; }
|
||||||
|
setstate OFF
|
||||||
|
log "=== STOP done rc=$rc in $(since $T0)s (mss=$(mss_state) rmtfs='$(rmtfs_pid)' mm='$(mm_pid)' bam=$(bam_pm))"
|
||||||
|
return $rc
|
||||||
|
}
|
||||||
|
|
||||||
|
do_disconnect() { # B6N: bearer down only; MSS, rmtfs, MM (and DMS radio) stay up. Next 'start' reuses them and only simple-connects.
|
||||||
|
T0=$(now); log "=== DISCONNECT (from $(cat $STATE 2>/dev/null || echo OFF): mss=$(mss_state) rmtfs=$(rmtfs_pid) mm=$(mm_pid) bam=$(bam_pm))"; rc=0
|
||||||
|
[ -n "$(mm_pid)" ] && mm_has_modem || { log "DISCONNECT: no MM modem"; return 1; }
|
||||||
|
timeout $T_DISCONNECT mmcli -m "$(mm_idx)" --simple-disconnect >> $LOG 2>&1; log "simple-disconnect rc=$? (bearers: $(bearers | tr '\n' ' '))"
|
||||||
|
wait_for 15 1 sh -c "! sh $0 _anyconn" && log "no bearer connected" || { log "ERROR: bearer still connected"; rc=1; }
|
||||||
|
for h in $(cat $ROUTES 2>/dev/null); do ip route del $h/32 2>/dev/null; done; : > $ROUTES
|
||||||
|
for d in /sys/class/net/wwan*; do [ -e "$d" ] || continue; w=${d##*/}
|
||||||
|
ip addr flush dev $w 2>/dev/null; ip link set $w down 2>/dev/null
|
||||||
|
link_up $w && { log "ERROR: $w still UP"; rc=1; }; done
|
||||||
|
rm -f $D/ipcfg
|
||||||
|
ip route | grep -q " dev wwan" && { log "ERROR: routes via wwan remain: $(ip route | grep ' dev wwan' | tr '\n' ';')"; rc=1; }
|
||||||
|
t=$(now); wait_for $T_BAM_IDLE 0.5 bam_suspended && log "BAM-DMUX suspended after $(since $t)s" || { log "ERROR: BAM-DMUX '$(bam_pm)' not suspended"; rc=1; }
|
||||||
|
setstate MM_IDLE
|
||||||
|
log "=== DISCONNECT done rc=$rc in $(since $T0)s (mss=$(mss_state) rmtfs='$(rmtfs_pid)' mm='$(mm_pid)' mm_state=$(mm_state) bam=$(bam_pm))"
|
||||||
|
return $rc
|
||||||
|
}
|
||||||
|
|
||||||
|
do_status() {
|
||||||
|
r=$(rp)
|
||||||
|
echo "controller: $(cat $STATE 2>/dev/null || echo OFF)"
|
||||||
|
echo "remoteproc: $RPNAME $(mss_state) ($r) fw=$(cat $r/firmware 2>/dev/null)"
|
||||||
|
echo "rmtfs: pid='$(rmtfs_pid)' writes_logged=$(grep -c 'write ' $D/rmtfs.log 2>/dev/null)"
|
||||||
|
echo "qmi dev: $(ls /dev/wwan0qmi0 2>/dev/null || echo absent) qmi-proxy='$(pidof qmi-proxy)'"
|
||||||
|
echo "daemons: udevd='$(pidof udevd)' dbus='$(pidof dbus-daemon)' polkitd='$(pidof polkitd)' ModemManager='$(mm_pid)'"
|
||||||
|
if [ -n "$(mm_pid)" ] && mm_has_modem; then
|
||||||
|
mmc -m "$(mm_idx)" | grep -E "\| +(state|power state|registration|operator name|access tech|signal quality|plugin|primary port): " \
|
||||||
|
| sed -E 's/^[^|]*\| */ mm /'
|
||||||
|
for b in $(bearers); do echo " bearer $b: $(mmc -b $b | grep -E 'connected:|interface:|address:' | tr -s ' |' ' ' | tr '\n' ';')"; done
|
||||||
|
else echo " mm: n/a"; fi
|
||||||
|
for d in /sys/class/net/wwan*; do [ -e "$d" ] || continue; w=${d##*/}
|
||||||
|
link_up $w && echo "wwan: $w UP $(ip -4 addr show $w | awk '/inet /{print $2}')"; done
|
||||||
|
echo "wwan up: $(n=0; for d in /sys/class/net/wwan*; do [ -e $d ] && link_up ${d##*/} && n=$((n+1)); done; echo $n) of $(ls -d /sys/class/net/wwan* 2>/dev/null | wc -l)"
|
||||||
|
echo "routes: $(ip route | grep ' dev wwan' | tr '\n' ';')"
|
||||||
|
echo "bam-dmux: $(bam_pm) active_ms=$(cat $BAM/power/runtime_active_time 2>/dev/null) suspended_ms=$(cat $BAM/power/runtime_suspended_time 2>/dev/null) control=$(cat $BAM/power/control 2>/dev/null)"
|
||||||
|
echo "usb0: $(ip -4 addr show usb0 | awk '/inet /{print $2}') route-to-host: $(ip route get 172.16.42.2 2>&1 | head -1)"
|
||||||
|
echo "emmc: $(awk '{print "writes_completed="$5" sectors_written="$7}' /sys/block/mmcblk0/stat)"
|
||||||
|
echo "time: $(date -u '+%F %T') UTC; set: $(cat $D/time-set 2>/dev/null || echo no); probes: $(cat $D/time-probes 2>/dev/null || echo 0)"
|
||||||
|
echo "dmesg-errs: $(dmesg | grep -cE 'Failed to resume|Resource temporarily|crash detected|fatal error|[Ww]atchdog|Oops|Kernel panic|Unable to handle')"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start) do_start;;
|
||||||
|
stop) do_stop; exit $?;;
|
||||||
|
disconnect) do_disconnect; exit $?;;
|
||||||
|
status) do_status;;
|
||||||
|
addroute) [ -n "$2" ] || exit 2; addroute "$2";;
|
||||||
|
_anyconn) any_bearer_connected;;
|
||||||
|
_mmstate) mm_state;;
|
||||||
|
*) echo "usage: $0 start|stop|status|addroute <ipv4>"; exit 2;;
|
||||||
|
esac
|
||||||
67
b12/b12q/alpine-overlay/usr/sbin/aurora-wifi
Normal file
67
b12/b12q/alpine-overlay/usr/sbin/aurora-wifi
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Aurora Wi-Fi controller (B8F). Pronto/WCNSS remoteproc -> wcn36xx wlan0 -> minimal hostapd AP (WPA2-PSK/CCMP).
|
||||||
|
# No DHCP/NAT/DNS/firewall. Everything proven in B8B..B8E; order = B8C..B8E: WCNSS is started after the modem reached
|
||||||
|
# START OK (or FAIL/rollback, or WAIT_MODEM s elapsed), from the RO modem FAT (/firmware/image/wcnss.mdt), NV from initramfs.
|
||||||
|
# aurora-wifi start | stop | status
|
||||||
|
D=/run/aurora-wifi; LOG=$D/wifi.log; CONF=/etc/aurora/wifi.conf; X=/usr/libexec/aurora/wifi
|
||||||
|
ML=/run/aurora-modem/lifecycle.log; RPNAME=a204000.remoteproc
|
||||||
|
mkdir -p $D
|
||||||
|
now() { cut -d' ' -f1 /proc/uptime; }
|
||||||
|
log() { m="[$(now)] $*"; echo "$m" >> $LOG; echo "$m"; echo "<5>[aurora-wifi] $*" > /dev/kmsg 2>/dev/null; }
|
||||||
|
rp() { for r in /sys/class/remoteproc/remoteproc*; do [ "$(cat $r/name 2>/dev/null)" = $RPNAME ] && echo $r && return; done; }
|
||||||
|
hpid() { ps w | grep "[h]ostapd -t .*$D/hostapd.conf" | awk '{print $1}'; }
|
||||||
|
WAIT_MODEM=300; SSID=; PSK=; CHANNEL=6
|
||||||
|
[ -f $CONF ] && . $CONF
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
T0=$(now); log "=== WIFI START (wait for modem START OK/FAIL up to ${WAIT_MODEM}s)"
|
||||||
|
i=0; while [ $i -lt $WAIT_MODEM ]; do
|
||||||
|
grep -qE "=== START OK|FAIL in|rollback" $ML 2>/dev/null && break; sleep 1; i=$((i+1)); done
|
||||||
|
log "modem gate after ${i}s: $(grep -E '=== START OK|FAIL in|rollback' $ML 2>/dev/null | tail -1 | cut -c1-80)"
|
||||||
|
[ "$(cat /sys/module/firmware_class/parameters/path)" = /firmware/image ] && [ -f /firmware/image/wcnss.mdt ] || { log "FAIL: /firmware/image/wcnss.mdt not available"; exit 1; }
|
||||||
|
[ -f /lib/firmware/wlan/prima/WCNSS_qcom_wlan_nv.bin ] || { log "FAIL: NV missing"; exit 1; }
|
||||||
|
R=$(rp); [ -n "$R" ] || { log "FAIL: remoteproc $RPNAME not found"; exit 1; }
|
||||||
|
if [ "$(cat $R/state)" = offline ]; then echo start > $R/state || { log "FAIL: WCNSS start write"; exit 1; }; fi
|
||||||
|
log "WCNSS $R state=$(cat $R/state)"
|
||||||
|
i=0; while [ ! -e /sys/class/net/wlan0 ] && [ $i -lt 30 ]; do sleep 1; i=$((i+1)); done
|
||||||
|
[ -e /sys/class/net/wlan0 ] || { log "FAIL: wlan0 did not appear in 30 s"; exit 1; }
|
||||||
|
ip link set wlan0 up || { log "FAIL: wlan0 up"; exit 1; }
|
||||||
|
log "wlan0 up addr=$(cat /sys/class/net/wlan0/address) ($(dmesg | grep -o "wcn36xx: firmware WLAN version.*XO'" | tail -1))"
|
||||||
|
[ -n "$SSID" ] && [ ${#PSK} -ge 8 ] || { log "AP not configured (SSID/PSK) - wlan0 left up, managed"; exit 0; }
|
||||||
|
umask 077; cat > $D/hostapd.conf <<C
|
||||||
|
interface=wlan0
|
||||||
|
driver=nl80211
|
||||||
|
ctrl_interface=$D/ctrl
|
||||||
|
ssid=$SSID
|
||||||
|
hw_mode=g
|
||||||
|
channel=$CHANNEL
|
||||||
|
ieee80211n=1
|
||||||
|
wmm_enabled=1
|
||||||
|
auth_algs=1
|
||||||
|
ignore_broadcast_ssid=0
|
||||||
|
wpa=2
|
||||||
|
wpa_key_mgmt=WPA-PSK
|
||||||
|
rsn_pairwise=CCMP
|
||||||
|
wpa_passphrase=$PSK
|
||||||
|
logger_stdout=-1
|
||||||
|
logger_stdout_level=2
|
||||||
|
C
|
||||||
|
printf 'trap "" HUP\nexport LD_LIBRARY_PATH=%s/lib\nexec %s/hostapd -t %s/hostapd.conf >> %s/hostapd.log 2>&1\n' $X $X $D $D > $D/hostapd.run
|
||||||
|
setsid sh $D/hostapd.run < /dev/null > /dev/null 2>&1 &
|
||||||
|
i=0; while ! grep -q "AP-ENABLED" $D/hostapd.log 2>/dev/null && [ $i -lt 20 ]; do sleep 1; i=$((i+1)); done
|
||||||
|
if grep -q "AP-ENABLED" $D/hostapd.log; then log "=== AP ENABLED ssid=$SSID ch=$CHANNEL pid=$(hpid) in $(awk "BEGIN{print $(now)-$T0}")s"
|
||||||
|
else log "FAIL: hostapd did not reach AP-ENABLED: $(tail -3 $D/hostapd.log | tr '\n' ' ')"; exit 1; fi;;
|
||||||
|
stop)
|
||||||
|
P=$(hpid); [ -n "$P" ] && kill $P; sleep 1
|
||||||
|
[ -e /sys/class/net/wlan0 ] && ip link set wlan0 down
|
||||||
|
R=$(rp); [ -n "$R" ] && [ "$(cat $R/state)" = running ] && echo stop > $R/state
|
||||||
|
log "=== WIFI STOP (hostapd=${P:-none}, WCNSS $(cat $R/state 2>/dev/null))";;
|
||||||
|
status)
|
||||||
|
R=$(rp); echo "remoteproc: $RPNAME $(cat $R/state 2>/dev/null) ($R)"
|
||||||
|
echo "crash=$(dmesg | grep -cE 'crash detected in a204000') watchdog=$(dmesg | grep -cE 'Watchdog startup') fatal=$(dmesg | grep -cE 'qcom-wcnss-pil.*fatal')"
|
||||||
|
echo "wlan0: $(ip -o link show wlan0 2>/dev/null | cut -d' ' -f2-3) $(iw dev wlan0 info 2>/dev/null | grep -E 'ssid|type|channel' | tr -s '\t\n' ' ')"
|
||||||
|
echo "hostapd: pid=$(hpid) $(grep -cE 'AP-STA-CONNECTED' $D/hostapd.log 2>/dev/null) connects, $(grep -cE 'AP-STA-DISCONNECTED' $D/hostapd.log 2>/dev/null) disconnects"
|
||||||
|
iw dev wlan0 station dump 2>/dev/null | grep -E "^Station|authorized|signal:|connected time"
|
||||||
|
tail -3 $LOG;;
|
||||||
|
*) echo "usage: $0 start|stop|status"; exit 2;;
|
||||||
|
esac
|
||||||
45
b12/b12q/b12q-boot.sh
Normal file
45
b12/b12q/b12q-boot.sh
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# 480s: B12Q RAM test. b12q-boot.sh K normal|off|failtest — waits for lk1st fastboot, `fastboot boot` the variant, then checks over telnet.
|
||||||
|
# Nothing is flashed. normal: expect Alpine PID1 on p27; off/failtest: expect LFS rescue (stage0 fallback) with p27 untouched/relocked.
|
||||||
|
K=$1; V=$2; case "$V" in normal) IMG=aurora-b12q.img;; off) IMG=aurora-b12q-off.img;; failtest) IMG=aurora-b12q-failtest.img;; cold) IMG=;; *) echo "usage: $0 K normal|off|failtest"; exit 2;; esac
|
||||||
|
cd ~/doc/modem/jz08-aurora; O=logs/b12/b12q/$V$K; mkdir -p $O; [ -n "$IMG" ] && IMG=b12/b12q/out/$IMG
|
||||||
|
A=$O/host-actions.txt; act() { echo "$(date -u +%H:%M:%S) $*" | tee -a $A; }
|
||||||
|
tn() { { sleep 1; sed "s/\$/\r/" "$1"; sleep $2; } | ncat 172.16.42.1 23 | tr -d "\000\r"; }
|
||||||
|
if [ $V != cold ]; then
|
||||||
|
grep " $(basename $IMG)\$" b12/b12q/out/SHA256SUMS | sed "s| | b12/b12q/out/|" | sha256sum -c || exit 1
|
||||||
|
act "B12Q $V$K: waiting for fastboot <EMMC_SERIAL> (RESET held at power-on)"
|
||||||
|
i=0; until fastboot devices 2>/dev/null | grep -q <EMMC_SERIAL>; do i=$((i+1)); [ $i -ge 900 ] && { act "ABORT: no fastboot"; exit 1; }; sleep 2; done
|
||||||
|
act "fastboot present"; { fastboot boot $IMG 2>&1; echo "rc=$?"; } | tee -a $A
|
||||||
|
else
|
||||||
|
act "B12Q cold$K: waiting for normal power-on WITHOUT RESET (cache B12Q 59272cd3)"
|
||||||
|
i=0; until ping -c1 -W1 172.16.42.1 >/dev/null 2>&1; do fastboot devices 2>/dev/null | grep -q <EMMC_SERIAL> && { act "ABORT: board in fastboot - RESET held?"; exit 1; }; i=$((i+1)); [ $i -ge 1800 ] && { act "ABORT: no NCM"; exit 1; }; sleep 1; done
|
||||||
|
fi
|
||||||
|
i=0; until ping -c1 -W1 172.16.42.1 >/dev/null 2>&1; do i=$((i+1)); [ $i -ge 240 ] && { act "ABORT: NCM not up"; exit 1; }; sleep 1; done; act "NCM ping ok"
|
||||||
|
printf 'grep -E "START OK|FAIL in|rollback|SAFETY" /run/aurora-modem/lifecycle.log | tail -2\n' > $O/.w
|
||||||
|
i=0; until tn $O/.w 3 | grep -qE "^\[[0-9.]+\] .*(=== START OK|FAIL in|rollback)"; do i=$((i+1)); [ $i -ge 80 ] && { act "no START OK/FAIL after ~12 min"; break; }; sleep 6; done
|
||||||
|
act "modem: $(tn $O/.w 3 | grep -E '^\[[0-9.]+\]' | tail -2 | tr '\n' ' ')"
|
||||||
|
printf 'grep -E "AP ENABLED|FAIL" /run/aurora-wifi/wifi.log | tail -1\n' > $O/.a
|
||||||
|
i=0; until tn $O/.a 3 | grep -qE "^\[[0-9.]+\] (=== AP ENABLED|FAIL)"; do i=$((i+1)); [ $i -ge 30 ] && break; sleep 6; done
|
||||||
|
act "wifi: $(tn $O/.a 3 | grep -E '^\[[0-9.]+\]' | tail -1)"
|
||||||
|
cat > $O/.c <<'C'
|
||||||
|
echo SNAP-BEGIN; cat /proc/uptime; uname -a; cat /proc/cmdline
|
||||||
|
echo ---pid1; ls -l /proc/1/exe; cat /proc/1/cmdline | tr '\0' ' '; echo; ls -l /sbin/init; cat /etc/alpine-release 2>/dev/null; cat /etc/os-release 2>/dev/null | head -2
|
||||||
|
echo ---root; grep -E " / |mmcblk0p27|/alpine" /proc/mounts; df -k / | tail -1; cat /proc/mounts
|
||||||
|
echo ---stage0; dmesg | grep -E "aurora-stage0|aurora-ro|aurora-bootok|stage0"; cat /var/lib/aurora/boot-attempts 2>/dev/null; cat /var/lib/aurora/stage0-fsck.txt 2>/dev/null | tail -1
|
||||||
|
echo ---openrc; rc-status -a 2>/dev/null; rc-status --crashed 2>/dev/null
|
||||||
|
echo ---ro; for x in /dev/mmcblk0 /dev/mmcblk0p* /dev/mmcblk0boot0 /dev/mmcblk0boot1; do printf "%s=%s " ${x#/dev/} $(blockdev --getro $x); done; echo
|
||||||
|
echo ---modem; /usr/libexec/aurora/svc/aurora-modem status 2>/dev/null || /etc/init.d/aurora-modem status; grep -E "SAFETY|START OK" /run/aurora-modem/lifecycle.log
|
||||||
|
echo ---ping; ping -c4 -W3 -I wwan0 77.88.8.8 | tail -2
|
||||||
|
echo ---wifi; iw dev; grep -E "AP ENABLED" /run/aurora-wifi/wifi.log; for r in /sys/class/remoteproc/*; do echo "RP $(cat $r/name)=$(cat $r/state)"; done
|
||||||
|
echo ---display; cat /run/aurora-display/display.log 2>/dev/null | tail -3; cat /sys/class/tty/tty0/active; cat /sys/class/backlight/backlight/bl_power; cat /sys/class/drm/card0-SPI-1/enabled
|
||||||
|
echo ---charger; grep -q " /sys/kernel/debug " /proc/mounts || mount -t debugfs debugfs /sys/kernel/debug; head -3 /sys/kernel/debug/pm8916_lbc/state
|
||||||
|
echo ---apk; apk --version 2>/dev/null && apk info 2>/dev/null | wc -l; cat /root/persist-test.txt 2>/dev/null
|
||||||
|
echo ---procs; ps -o pid,user,args 2>/dev/null | grep -vE "\[|ps -o" | head -40
|
||||||
|
echo ---mem; free
|
||||||
|
echo ---emmc; cat /sys/block/mmcblk0/stat; for p in /sys/class/block/mmcblk0p* /sys/class/block/mmcblk0boot0 /sys/class/block/mmcblk0boot1; do s=$(awk '{print $5}' $p/stat); [ "$s" != 0 ] && echo "$(basename $p) writes=$s"; done
|
||||||
|
echo SNAP-END
|
||||||
|
C
|
||||||
|
tn $O/.c 30 > $O/snapshot.txt; act "snapshot: $(grep -c SNAP-END $O/snapshot.txt) end"
|
||||||
|
grep -A3 -- "---pid1" $O/snapshot.txt | tail -3 | tee -a $A; grep -E "^/dev/mmcblk0p27 / |^rootfs / " $O/snapshot.txt | tee -a $A; grep -E "writes=" $O/snapshot.txt | tee -a $A
|
||||||
|
grep -E "aurora-stage0" $O/snapshot.txt | tail -2 | tee -a $A
|
||||||
|
act "B12Q $V$K END"
|
||||||
25
b12/b12q/build-b12q.sh
Normal file
25
b12/b12q/build-b12q.sh
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B12Q RAM images: B10 production kernel/DTB unchanged, B9C cmdline (+ test switches), initramfs = B10 (B9C) initramfs + overlay:
|
||||||
|
# /init = stage0 (switch_root into Alpine on p27, fallback -> /init.lfs), /init.lfs = exact B9C/B10 LFS init (rescue),
|
||||||
|
# aurora-modem (B12P relaxed disk-flag gate), aurora-alpine (manual p27 mount from rescue), e2fsck bundle.
|
||||||
|
# Images: aurora-b12q.img (normal), aurora-b12q-off.img (aurora.alpine=off), aurora-b12q-failtest.img (aurora.b12q.failtest=init).
|
||||||
|
set -e; cd "$(dirname "$0")"; O=out; F=../../b10/b10b3/out-v4; GEN=../../linux/out/usr/gen_init_cpio; TS=1790726400
|
||||||
|
mkdir -p $O
|
||||||
|
echo "b0ea04666c4ab979067fe9c0015bda0e9c8ac742678321e57b18e841c9c69f95 $F/Image.gz-dtb" | sha256sum -c
|
||||||
|
echo "ac518e27e2957ad5e4515969b9a3808024e11ef8d1a79433a899a67dbc644558 $F/initramfs.cpio.gz" | sha256sum -c
|
||||||
|
echo "0fef41b262917c8ae308fa222da0017e2b3cb3ec5da1ca8ba18d0318476761a3 $F/cmdline.txt" | sha256sum -c
|
||||||
|
cmp rootfs/init.lfs ../../b9/b9c/rootfs/init || { echo "STOP: init.lfs != B9C init"; exit 1; }
|
||||||
|
cp $F/Image.gz-dtb $F/aurora-b10b3.dtb $O/
|
||||||
|
{ echo "file /init rootfs/init 0755 0 0"; echo "file /init.lfs rootfs/init.lfs 0755 0 0"; echo "dir /newroot 0755 0 0"
|
||||||
|
echo "file /usr/sbin/aurora-modem ../b12p/rootfs/usr/sbin/aurora-modem 0755 0 0"
|
||||||
|
echo "file /usr/sbin/aurora-alpine ../b12p/rootfs/usr/sbin/aurora-alpine 0755 0 0"
|
||||||
|
echo "file /etc/init.d/aurora-alpine ../b12p/rootfs/etc/init.d/aurora-alpine 0755 0 0"; echo "dir /alpine 0755 0 0"
|
||||||
|
echo "dir /usr/libexec/aurora/e2fs 0755 0 0"; echo "dir /usr/libexec/aurora/e2fs/lib 0755 0 0"; echo "dir /usr/libexec/aurora/e2fs/sbin 0755 0 0"
|
||||||
|
for f in e2fs/lib/* e2fs/sbin/*; do echo "file /usr/libexec/aurora/$f $f 0755 0 0"; done; } > $O/overlay-b12q.list
|
||||||
|
$GEN -t $TS $O/overlay-b12q.list > $O/overlay-b12q.cpio; gzip -9 -n -c $O/overlay-b12q.cpio > $O/overlay-b12q.cpio.gz
|
||||||
|
cat $F/initramfs.cpio.gz $O/overlay-b12q.cpio.gz > $O/initramfs-b12q.cpio.gz
|
||||||
|
cp $F/cmdline.txt $O/cmdline.txt
|
||||||
|
printf '%s aurora.alpine=off' "$(cat $F/cmdline.txt)" > $O/cmdline-off.txt
|
||||||
|
printf '%s aurora.b12q.failtest=init' "$(cat $F/cmdline.txt)" > $O/cmdline-failtest.txt
|
||||||
|
for v in "" -off -failtest; do python3 ../../b6p/mkbootimg.py $O/Image.gz-dtb $O/initramfs-b12q.cpio.gz $O/cmdline$v.txt $O/aurora-b12q$v.img; done
|
||||||
|
(cd $O && sha256sum Image.gz-dtb aurora-b10b3.dtb cmdline*.txt overlay-b12q.cpio.gz initramfs-b12q.cpio.gz aurora-b12q*.img > SHA256SUMS; cat SHA256SUMS)
|
||||||
6
b12/b12q/cache/extlinux-b12q.conf
vendored
Normal file
6
b12/b12q/cache/extlinux-b12q.conf
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
default b12q
|
||||||
|
label b12q
|
||||||
|
linux /Image.gz-dtb
|
||||||
|
fdt /aurora-b10b3.dtb
|
||||||
|
initrd /initramfs-b12q.cpio.gz
|
||||||
|
append earlycon console=tty0 console=ttyMSM0,115200n8 ignore_loglevel loglevel=8 rdinit=/init fbcon=font:6x8 consoleblank=0
|
||||||
27
b12/b12q/cache/mkfs-cache-b12q.sh
vendored
Normal file
27
b12/b12q/cache/mkfs-cache-b12q.sh
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# B12Q cache CANDIDATE (Alpine primary root: stage0 switch_root, LFS rescue) (NOT for writing without a separate GO): exact recipe of b10/b10b3/cache-v4/mkfs-cache-b10b5.sh (c3732515);
|
||||||
|
# differs only in the initrd (B9C initramfs + B12P overlay: aurora-alpine autostart, modem safety gate, e2fsck bundle), file names,
|
||||||
|
# extlinux label, fs label and UUIDs. Kernel/DTB/append = B10 production unchanged. Runs on 480s (mke2fs 1.47.2). Offline only.
|
||||||
|
# The image contains the AP PSK (in the initramfs) - never publish it.
|
||||||
|
set -e
|
||||||
|
cd ~/doc/modem/jz08-aurora/b12/b12q/cache
|
||||||
|
OUT=${1:-cache-extlinux-b12q.img}; F=../out
|
||||||
|
echo "0fef41b262917c8ae308fa222da0017e2b3cb3ec5da1ca8ba18d0318476761a3 $F/cmdline.txt" | sha256sum -c
|
||||||
|
echo "b0ea04666c4ab979067fe9c0015bda0e9c8ac742678321e57b18e841c9c69f95 $F/Image.gz-dtb" | sha256sum -c
|
||||||
|
echo "e47762d1dcd0af6e2acb711fa47ecc13769cd6bcb81259ce50635e8b18b6514a $F/aurora-b10b3.dtb" | sha256sum -c
|
||||||
|
echo "9ade7cffb1f3f19e86acc8869565a88b960abba543385a2fddcebd27bd529e79 $F/initramfs-b12q.cpio.gz" | sha256sum -c
|
||||||
|
ST=$(mktemp -d); mkdir -p $ST/extlinux
|
||||||
|
cp $F/Image.gz-dtb $F/aurora-b10b3.dtb $F/initramfs-b12q.cpio.gz $ST/
|
||||||
|
printf "default b12q\nlabel b12q\n\tlinux /Image.gz-dtb\n\tfdt /aurora-b10b3.dtb\n\tinitrd /initramfs-b12q.cpio.gz\n\tappend %s\n" "$(cat $F/cmdline.txt)" > $ST/extlinux/extlinux.conf
|
||||||
|
cp $ST/extlinux/extlinux.conf extlinux-b12q.conf
|
||||||
|
chmod 0644 $ST/*.* $ST/extlinux/extlinux.conf; chmod 0755 $ST $ST/extlinux
|
||||||
|
find $ST -exec touch -h -d @1790726400 {} +
|
||||||
|
rm -f $OUT; truncate -s 134217728 $OUT
|
||||||
|
E2FSPROGS_FAKE_TIME=1790726400 /sbin/mke2fs -F -q -t ext2 -O none,filetype,sparse_super \
|
||||||
|
-b 4096 -I 128 -N 64 -m 0 -L aurora-b12q -U 4a5a3038-b6f0-4000-8000-0000b12b1300 \
|
||||||
|
-E root_owner=0:0,hash_seed=4a5a3038-b6f0-4000-8000-0000b12b1301 -d $ST $OUT 32768
|
||||||
|
rm -rf $ST
|
||||||
|
for f in / /lost+found /extlinux /extlinux/extlinux.conf /Image.gz-dtb /aurora-b10b3.dtb /initramfs-b12q.cpio.gz; do for t in atime ctime mtime; do echo "sif $f $t @1790726400"; done; done > /tmp/b12q-sif.$$
|
||||||
|
/sbin/debugfs -w -f /tmp/b12q-sif.$$ $OUT >/dev/null 2>&1; rm -f /tmp/b12q-sif.$$
|
||||||
|
/sbin/e2fsck -fn $OUT >/dev/null 2>&1 && echo "e2fsck -fn clean"
|
||||||
|
stat -c "%n %s" $OUT; sha256sum $OUT
|
||||||
14
b12/b12q/install-p27.sh
Normal file
14
b12/b12q/install-p27.sh
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B12Q-2 (board, under B12P production with /alpine mounted): install the real-boot packages from a local repo (no network)
|
||||||
|
# and the Aurora overlay into p27. Writes only p27. Idempotent.
|
||||||
|
set -e; R=/alpine; T=/tmp/b12
|
||||||
|
grep -q " $R ext4 rw" /proc/mounts || { echo "INSTALL FAIL: /alpine not mounted rw"; exit 1; }
|
||||||
|
rm -rf $R/var/cache/b12q; mkdir -p $R/var/cache/b12q; tar xzf $T/b12q-pkgs.tar.gz -C $R/var/cache/b12q; mkdir $R/var/cache/b12q/pkgs/aarch64; mv $R/var/cache/b12q/pkgs/*.apk $R/var/cache/b12q/pkgs/APKINDEX.tar.gz $R/var/cache/b12q/pkgs/aarch64/; ln -s aarch64 $R/var/cache/b12q/pkgs/noarch
|
||||||
|
N="openrc busybox-extras eudev dbus polkit modemmanager modemmanager-udev libqmi qmi-utils libqrtr-glib rmtfs hostapd iw mobile-broadband-provider-info"
|
||||||
|
chroot $R apk add --no-network --allow-untrusted --repositories-file /dev/null --repository /var/cache/b12q/pkgs $N > $T/apk-add.log 2>&1 || { tail -20 $T/apk-add.log; echo "INSTALL FAIL apk"; exit 1; }
|
||||||
|
tail -3 $T/apk-add.log
|
||||||
|
tar xzf $T/b12q-overlay.tar.gz -C $R
|
||||||
|
rm -rf $R/var/cache/b12q; echo 0 > $R/var/lib/aurora/boot-attempts; sync
|
||||||
|
echo "pkgs=$(chroot $R apk info | wc -l) openrc=$(chroot $R openrc --version | head -1) users=$(grep -cE '^(messagebus|polkitd):' $R/etc/passwd)"
|
||||||
|
ls $R/etc/runlevels/*; ls -l $R/sbin/init $R/sbin/openrc
|
||||||
|
echo "INSTALL OK"
|
||||||
12
b12/b12r/B12R-rollback.sh
Normal file
12
b12/b12r/B12R-rollback.sh
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# B12R rollback - restore the B12Q cache (59272cd3: Alpine primary root, kernel b10b5 without nf_tables). Needs 9008 via HW EDL. boot/aboot/userdata untouched
|
||||||
|
# (if aurora-router was added to the default runlevel it just logs "kernel has no nf_tables" under b10b5). Deeper: b12/b12q/B12Q-rollback.sh (B12P).
|
||||||
|
cd ~/doc/modem/jz08-aurora || exit 1
|
||||||
|
L=firehose/007050e100000000_394a2e47cf830150_fhprg_peek.bin ; O=logs/b12/b12r/rollback ; mkdir -p $O
|
||||||
|
B=b12/b12q/cache/cache-extlinux-b12q.img
|
||||||
|
[ "$(sha256sum $B | cut -d' ' -f1)" = 59272cd3fb45a9388934110b345a0e320d62a3199b52aa0c47ec10eb79352aae ] || { echo "STOP: rollback image hash"; exit 1; }
|
||||||
|
lsusb | grep -q 05c6:9008 || { echo "STOP: no 9008"; exit 1; }
|
||||||
|
edl --loader=$L printgpt > $O/00-printgpt.log 2>&1
|
||||||
|
edl --loader=$L w cache $B > $O/cache-w.log 2>&1
|
||||||
|
edl --loader=$L r cache $O/cache-rb.bin > /dev/null 2>&1 ; cmp $B $O/cache-rb.bin && echo CACHE_RESTORED_B12Q
|
||||||
|
sha256sum $B $O/cache-rb.bin
|
||||||
52
b12/b12r/B12R-write.sh
Normal file
52
b12/b12r/B12R-write.sh
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# B12R — the ONLY write: cache := B12R candidate (= B12Q + kernel 7.2.7-aurora-b12: b10b5 production config + nf_tables/NAT, same source tree).
|
||||||
|
# Run on 480s ONLY after explicit GO. Derived 1:1 from b12/b12q/B12Q-write.sh (B12Q_CACHE_WRITE_VERIFIED 2026-10-04); changed: image/hashes,
|
||||||
|
# rollback refs, log dir. The pre-write readback of the live cache (must be B12Q 59272cd3) is kept as backup.
|
||||||
|
# Entry: HW EDL (battery on, D+->GND, plug USB, release). Never `edl reset`. Stops at first failed gate.
|
||||||
|
cd ~/doc/modem/jz08-aurora || exit 1
|
||||||
|
L=firehose/007050e100000000_394a2e47cf830150_fhprg_peek.bin
|
||||||
|
O=logs/b12/b12r/W ; A3=logs/b5a/A3 ; P=logs/b5a/A4pre ; mkdir -p $O
|
||||||
|
NEW=b12/b12r/cache/cache-extlinux-b12r.img ; NEW_SHA=e85d862e463aa4affd7ec1cea9b1f2c7f765bb08e2a6bdce4af9539278f80d33
|
||||||
|
OLD_SHA=59272cd3fb45a9388934110b345a0e320d62a3199b52aa0c47ec10eb79352aae # current cache = B12Q extlinux
|
||||||
|
BOOT_SHA=e9579f33c7304cd47f487f2b61cd9226dc04fd3a63775d62b4b95fc15bd3ebff
|
||||||
|
ABOOT_SHA=15208dbb4feafccd72d2b06db5714cd746c216701f0ef8822c58bb47105d37c4 # aboot = lk1st-b9l (B9L-PERSIST)
|
||||||
|
die(){ echo "STOP: $*"; exit 1; }
|
||||||
|
sha(){ sha256sum "$1" | cut -d" " -f1; }
|
||||||
|
E(){ edl --loader=$L "$@"; }
|
||||||
|
echo "== G0 inputs"
|
||||||
|
[ "$(sha $L)" = 53f193500c03248f0d671ab57bfe9ca8a42967e97f28403294b4b3f854075aca ] || die loader
|
||||||
|
[ "$(sha $NEW)" = $NEW_SHA ] && [ $(stat -c %s $NEW) = 134217728 ] || die candidate
|
||||||
|
[ "$(sha b12/b12q/cache/cache-extlinux-b12q.img)" = $OLD_SHA ] || die rollback-image
|
||||||
|
[ "$(sha logs/b12/b12q/W/11-cache-readback.bin)" = $OLD_SHA ] || die b12q-readback-backup
|
||||||
|
lsusb | grep -q 05c6:9008 || die "no 9008"
|
||||||
|
echo "== G1 identity + geometry + baseline"
|
||||||
|
E printgpt > $O/00-printgpt.log 2>&1 || die printgpt
|
||||||
|
grep -aq "Serial: *0x<SAHARA_SERIAL>" $O/00-printgpt.log || grep -aq "Mode detected: firehose" $O/00-printgpt.log || die serial
|
||||||
|
grep -a "^cache:" $O/00-printgpt.log | grep -q "Offset 0x000000004118c000, Length 0x0000000008000000" || die cache-geometry
|
||||||
|
E rs 0 34 $O/pre-gptp.bin >/dev/null 2>&1; cmp $O/pre-gptp.bin $A3/gpt-primary-34.bin || die gpt-changed
|
||||||
|
E r boot $O/pre-boot.bin >/dev/null 2>&1; [ "$(sha $O/pre-boot.bin)" = $BOOT_SHA ] || die boot-not-emmc1
|
||||||
|
E r aboot $O/pre-aboot.bin >/dev/null 2>&1; [ "$(sha $O/pre-aboot.bin)" = $ABOOT_SHA ] || die aboot-not-b9l
|
||||||
|
E r cache $O/pre-cache.bin >/dev/null 2>&1; [ "$(sha $O/pre-cache.bin)" = $OLD_SHA ] || die cache-not-backup
|
||||||
|
echo "== W cache := candidate (LBA 2133088, 262144 sectors)"
|
||||||
|
E w cache $NEW > $O/10-cache-write.log 2>&1; echo "rc=$?"; grep -a "Wrote" $O/10-cache-write.log
|
||||||
|
E r cache $O/11-cache-readback.bin > $O/11-cache-readback.log 2>&1 || die readback-rc
|
||||||
|
sha256sum $NEW $O/11-cache-readback.bin
|
||||||
|
cmp $NEW $O/11-cache-readback.bin || die "CACHE READBACK MISMATCH — do NOT reboot; run b12/b12r/B12R-rollback.sh"
|
||||||
|
echo CACHE_MATCH
|
||||||
|
echo "== V everything else unchanged"
|
||||||
|
E rs 0 34 $O/post-gptp.bin >/dev/null 2>&1; cmp $O/post-gptp.bin $A3/gpt-primary-34.bin || die gptp
|
||||||
|
E rs 7634911 33 $O/post-gptb.bin >/dev/null 2>&1; cmp $O/post-gptb.bin $A3/gpt-backup-33.bin || die gptb
|
||||||
|
E rs 305184 1024 $O/post-tzbak.bin >/dev/null 2>&1; cmp $O/post-tzbak.bin $A3/tzbak-305184.bin || die tzbak
|
||||||
|
E r boot $O/post-boot.bin >/dev/null 2>&1; [ "$(sha $O/post-boot.bin)" = $BOOT_SHA ] || die boot
|
||||||
|
E r aboot $O/post-aboot.bin >/dev/null 2>&1; [ "$(sha $O/post-aboot.bin)" = $ABOOT_SHA ] || die aboot
|
||||||
|
for p in sbl1 rpm tz hyp recovery modemst1 modemst2 fsg fsc persist; do
|
||||||
|
E r $p $O/post-$p.bin >/dev/null 2>&1; cmp $O/post-$p.bin $A3/$p.bin || die "$p changed"; echo "$p == A3"
|
||||||
|
done
|
||||||
|
for p in modem system; do
|
||||||
|
E r $p $O/post-$p.bin >/dev/null 2>&1; cmp $O/post-$p.bin $P/$p.bin || die "$p changed"; echo "$p == A4pre"; rm -f $O/post-$p.bin
|
||||||
|
done
|
||||||
|
E rs 2428000 8 $O/post-userdata-sb.bin >/dev/null 2>&1
|
||||||
|
[ "$(dd if=$O/post-userdata-sb.bin bs=1 skip=1080 count=2 2>/dev/null | od -An -tx1 | tr -d ' \n')" = 53ef ] && [ "$(dd if=$O/post-userdata-sb.bin bs=1 skip=1144 count=16 2>/dev/null | tr -d '\000')" = aurora-alpine ] || die "userdata superblock is not ext4 aurora-alpine"
|
||||||
|
echo "userdata = ext4 aurora-alpine (superblock)"
|
||||||
|
(cd $O && sha256sum *.bin > SHA256SUMS)
|
||||||
|
echo "B12R_CACHE_WRITE_VERIFIED — power off fully (USB, then battery) before first boot"
|
||||||
45
b12/b12r/b12r-boot.sh
Normal file
45
b12/b12r/b12r-boot.sh
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# 480s: B12R RAM test. b12q-boot.sh K normal|off|failtest — waits for lk1st fastboot, `fastboot boot` the variant, then checks over telnet.
|
||||||
|
# Nothing is flashed. normal: expect Alpine PID1 on p27; off/failtest: expect LFS rescue (stage0 fallback) with p27 untouched/relocked.
|
||||||
|
K=$1; V=$2; case "$V" in normal) IMG=aurora-b12r.img;; off) IMG=aurora-b12q-off.img;; failtest) IMG=aurora-b12q-failtest.img;; cold) IMG=;; *) echo "usage: $0 K normal|off|failtest"; exit 2;; esac
|
||||||
|
cd ~/doc/modem/jz08-aurora; O=logs/b12/b12r/$V$K; mkdir -p $O; [ -n "$IMG" ] && IMG=b12/b12r/out/$IMG
|
||||||
|
A=$O/host-actions.txt; act() { echo "$(date -u +%H:%M:%S) $*" | tee -a $A; }
|
||||||
|
tn() { { sleep 1; sed "s/\$/\r/" "$1"; sleep $2; } | ncat 172.16.42.1 23 | tr -d "\000\r"; }
|
||||||
|
if [ $V != cold ]; then
|
||||||
|
grep " $(basename $IMG)\$" b12/b12r/out/SHA256SUMS | sed "s| | b12/b12r/out/|" | sha256sum -c || exit 1
|
||||||
|
act "B12R $V$K: waiting for fastboot <EMMC_SERIAL> (RESET held at power-on)"
|
||||||
|
i=0; until fastboot devices 2>/dev/null | grep -q <EMMC_SERIAL>; do i=$((i+1)); [ $i -ge 900 ] && { act "ABORT: no fastboot"; exit 1; }; sleep 2; done
|
||||||
|
act "fastboot present"; { fastboot boot $IMG 2>&1; echo "rc=$?"; } | tee -a $A
|
||||||
|
else
|
||||||
|
act "B12R cold$K: waiting for normal power-on WITHOUT RESET (cache B12R 59272cd3)"
|
||||||
|
i=0; until ping -c1 -W1 172.16.42.1 >/dev/null 2>&1; do fastboot devices 2>/dev/null | grep -q <EMMC_SERIAL> && { act "ABORT: board in fastboot - RESET held?"; exit 1; }; i=$((i+1)); [ $i -ge 1800 ] && { act "ABORT: no NCM"; exit 1; }; sleep 1; done
|
||||||
|
fi
|
||||||
|
i=0; until ping -c1 -W1 172.16.42.1 >/dev/null 2>&1; do i=$((i+1)); [ $i -ge 240 ] && { act "ABORT: NCM not up"; exit 1; }; sleep 1; done; act "NCM ping ok"
|
||||||
|
printf 'grep -E "START OK|FAIL in|rollback|SAFETY" /run/aurora-modem/lifecycle.log | tail -2\n' > $O/.w
|
||||||
|
i=0; until tn $O/.w 3 | grep -qE "^\[[0-9.]+\] .*(=== START OK|FAIL in|rollback)"; do i=$((i+1)); [ $i -ge 80 ] && { act "no START OK/FAIL after ~12 min"; break; }; sleep 6; done
|
||||||
|
act "modem: $(tn $O/.w 3 | grep -E '^\[[0-9.]+\]' | tail -2 | tr '\n' ' ')"
|
||||||
|
printf 'grep -E "AP ENABLED|FAIL" /run/aurora-wifi/wifi.log | tail -1\n' > $O/.a
|
||||||
|
i=0; until tn $O/.a 3 | grep -qE "^\[[0-9.]+\] (=== AP ENABLED|FAIL)"; do i=$((i+1)); [ $i -ge 30 ] && break; sleep 6; done
|
||||||
|
act "wifi: $(tn $O/.a 3 | grep -E '^\[[0-9.]+\]' | tail -1)"
|
||||||
|
cat > $O/.c <<'C'
|
||||||
|
echo SNAP-BEGIN; cat /proc/uptime; uname -a; cat /proc/cmdline
|
||||||
|
echo ---pid1; ls -l /proc/1/exe; cat /proc/1/cmdline | tr '\0' ' '; echo; ls -l /sbin/init; cat /etc/alpine-release 2>/dev/null; cat /etc/os-release 2>/dev/null | head -2
|
||||||
|
echo ---root; grep -E " / |mmcblk0p27|/alpine" /proc/mounts; df -k / | tail -1; cat /proc/mounts
|
||||||
|
echo ---stage0; dmesg | grep -E "aurora-stage0|aurora-ro|aurora-bootok|stage0"; cat /var/lib/aurora/boot-attempts 2>/dev/null; cat /var/lib/aurora/stage0-fsck.txt 2>/dev/null | tail -1
|
||||||
|
echo ---openrc; rc-status -a 2>/dev/null; rc-status --crashed 2>/dev/null
|
||||||
|
echo ---ro; for x in /dev/mmcblk0 /dev/mmcblk0p* /dev/mmcblk0boot0 /dev/mmcblk0boot1; do printf "%s=%s " ${x#/dev/} $(blockdev --getro $x); done; echo
|
||||||
|
echo ---modem; /usr/libexec/aurora/svc/aurora-modem status 2>/dev/null || /etc/init.d/aurora-modem status; grep -E "SAFETY|START OK" /run/aurora-modem/lifecycle.log
|
||||||
|
echo ---ping; ping -c4 -W3 -I wwan0 77.88.8.8 | tail -2
|
||||||
|
echo ---wifi; iw dev; grep -E "AP ENABLED" /run/aurora-wifi/wifi.log; for r in /sys/class/remoteproc/*; do echo "RP $(cat $r/name)=$(cat $r/state)"; done
|
||||||
|
echo ---display; cat /run/aurora-display/display.log 2>/dev/null | tail -3; cat /sys/class/tty/tty0/active; cat /sys/class/backlight/backlight/bl_power; cat /sys/class/drm/card0-SPI-1/enabled
|
||||||
|
echo ---charger; grep -q " /sys/kernel/debug " /proc/mounts || mount -t debugfs debugfs /sys/kernel/debug; head -3 /sys/kernel/debug/pm8916_lbc/state
|
||||||
|
echo ---apk; apk --version 2>/dev/null && apk info 2>/dev/null | wc -l; cat /root/persist-test.txt 2>/dev/null
|
||||||
|
echo ---procs; ps -o pid,user,args 2>/dev/null | grep -vE "\[|ps -o" | head -40
|
||||||
|
echo ---mem; free
|
||||||
|
echo ---emmc; cat /sys/block/mmcblk0/stat; for p in /sys/class/block/mmcblk0p* /sys/class/block/mmcblk0boot0 /sys/class/block/mmcblk0boot1; do s=$(awk '{print $5}' $p/stat); [ "$s" != 0 ] && echo "$(basename $p) writes=$s"; done
|
||||||
|
echo SNAP-END
|
||||||
|
C
|
||||||
|
tn $O/.c 30 > $O/snapshot.txt; act "snapshot: $(grep -c SNAP-END $O/snapshot.txt) end"
|
||||||
|
grep -A3 -- "---pid1" $O/snapshot.txt | tail -3 | tee -a $A; grep -E "^/dev/mmcblk0p27 / |^rootfs / " $O/snapshot.txt | tee -a $A; grep -E "writes=" $O/snapshot.txt | tee -a $A
|
||||||
|
grep -E "aurora-stage0" $O/snapshot.txt | tail -2 | tee -a $A
|
||||||
|
act "B12R $V$K END"
|
||||||
12
b12/b12r/build-b12r.sh
Normal file
12
b12/b12r/build-b12r.sh
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B12R RAM image: kernel 7.2.7-aurora-b12 (= b10b5 production config + nf_tables/NAT, same tree src-b10b5) + prod DTB e47762d1 + B9C cmdline
|
||||||
|
# + B12Q initramfs (stage0 -> Alpine on p27) unchanged. fastboot boot only.
|
||||||
|
set -e; cd "$(dirname "$0")"; O=out; KB=/home/q/aurora-kbuild/out-b12; Q=../b12q/out; mkdir -p $O
|
||||||
|
echo "9ade7cffb1f3f19e86acc8869565a88b960abba543385a2fddcebd27bd529e79 $Q/initramfs-b12q.cpio.gz" | sha256sum -c
|
||||||
|
echo "e47762d1dcd0af6e2acb711fa47ecc13769cd6bcb81259ce50635e8b18b6514a $Q/aurora-b10b3.dtb" | sha256sum -c
|
||||||
|
echo "0fef41b262917c8ae308fa222da0017e2b3cb3ec5da1ca8ba18d0318476761a3 $Q/cmdline.txt" | sha256sum -c
|
||||||
|
for s in NF_TABLES=y NFT_NAT=y NFT_MASQ=y NF_CONNTRACK=y CHARGER_PM8916_LBC=y 'LOCALVERSION="-aurora-b12"'; do grep -q "^CONFIG_$s\$" $KB/.config || { echo "STOP $s"; exit 1; }; done
|
||||||
|
cp $KB/arch/arm64/boot/Image.gz $O/Image-b12.gz; cp $KB/.config $O/config-b12; cp $Q/aurora-b10b3.dtb $Q/initramfs-b12q.cpio.gz $Q/cmdline.txt $O/
|
||||||
|
cat $O/Image-b12.gz $O/aurora-b10b3.dtb > $O/Image.gz-dtb
|
||||||
|
python3 ../../b6p/mkbootimg.py $O/Image.gz-dtb $O/initramfs-b12q.cpio.gz $O/cmdline.txt $O/aurora-b12r.img
|
||||||
|
(cd $O && sha256sum Image-b12.gz config-b12 aurora-b10b3.dtb Image.gz-dtb initramfs-b12q.cpio.gz cmdline.txt aurora-b12r.img > SHA256SUMS; cat SHA256SUMS)
|
||||||
6
b12/b12r/cache/extlinux-b12r.conf
vendored
Normal file
6
b12/b12r/cache/extlinux-b12r.conf
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
default b12r
|
||||||
|
label b12r
|
||||||
|
linux /Image.gz-dtb
|
||||||
|
fdt /aurora-b10b3.dtb
|
||||||
|
initrd /initramfs-b12q.cpio.gz
|
||||||
|
append earlycon console=tty0 console=ttyMSM0,115200n8 ignore_loglevel loglevel=8 rdinit=/init fbcon=font:6x8 consoleblank=0
|
||||||
27
b12/b12r/cache/mkfs-cache-b12r.sh
vendored
Normal file
27
b12/b12r/cache/mkfs-cache-b12r.sh
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# B12R cache CANDIDATE (= B12Q + kernel 7.2.7-aurora-b12 with nf_tables for the Alpine router) (NOT for writing without a separate GO): exact recipe of b10/b10b3/cache-v4/mkfs-cache-b10b5.sh (c3732515);
|
||||||
|
# differs only in the initrd (B9C initramfs + B12P overlay: aurora-alpine autostart, modem safety gate, e2fsck bundle), file names,
|
||||||
|
# extlinux label, fs label and UUIDs. Kernel/DTB/append = B10 production unchanged. Runs on 480s (mke2fs 1.47.2). Offline only.
|
||||||
|
# The image contains the AP PSK (in the initramfs) - never publish it.
|
||||||
|
set -e
|
||||||
|
cd ~/doc/modem/jz08-aurora/b12/b12r/cache
|
||||||
|
OUT=${1:-cache-extlinux-b12r.img}; F=../out
|
||||||
|
echo "0fef41b262917c8ae308fa222da0017e2b3cb3ec5da1ca8ba18d0318476761a3 $F/cmdline.txt" | sha256sum -c
|
||||||
|
echo "19a53b6f4f6689fe20da8f2fc87f1f683b5b8c086537ef94ed8818ed47fd7d05 $F/Image.gz-dtb" | sha256sum -c
|
||||||
|
echo "e47762d1dcd0af6e2acb711fa47ecc13769cd6bcb81259ce50635e8b18b6514a $F/aurora-b10b3.dtb" | sha256sum -c
|
||||||
|
echo "9ade7cffb1f3f19e86acc8869565a88b960abba543385a2fddcebd27bd529e79 $F/initramfs-b12q.cpio.gz" | sha256sum -c
|
||||||
|
ST=$(mktemp -d); mkdir -p $ST/extlinux
|
||||||
|
cp $F/Image.gz-dtb $F/aurora-b10b3.dtb $F/initramfs-b12q.cpio.gz $ST/
|
||||||
|
printf "default b12r\nlabel b12r\n\tlinux /Image.gz-dtb\n\tfdt /aurora-b10b3.dtb\n\tinitrd /initramfs-b12q.cpio.gz\n\tappend %s\n" "$(cat $F/cmdline.txt)" > $ST/extlinux/extlinux.conf
|
||||||
|
cp $ST/extlinux/extlinux.conf extlinux-b12r.conf
|
||||||
|
chmod 0644 $ST/*.* $ST/extlinux/extlinux.conf; chmod 0755 $ST $ST/extlinux
|
||||||
|
find $ST -exec touch -h -d @1790726400 {} +
|
||||||
|
rm -f $OUT; truncate -s 134217728 $OUT
|
||||||
|
E2FSPROGS_FAKE_TIME=1790726400 /sbin/mke2fs -F -q -t ext2 -O none,filetype,sparse_super \
|
||||||
|
-b 4096 -I 128 -N 64 -m 0 -L aurora-b12r -U 4a5a3038-b6f0-4000-8000-0000b12b1400 \
|
||||||
|
-E root_owner=0:0,hash_seed=4a5a3038-b6f0-4000-8000-0000b12b1401 -d $ST $OUT 32768
|
||||||
|
rm -rf $ST
|
||||||
|
for f in / /lost+found /extlinux /extlinux/extlinux.conf /Image.gz-dtb /aurora-b10b3.dtb /initramfs-b12q.cpio.gz; do for t in atime ctime mtime; do echo "sif $f $t @1790726400"; done; done > /tmp/b12r-sif.$$
|
||||||
|
/sbin/debugfs -w -f /tmp/b12r-sif.$$ $OUT >/dev/null 2>&1; rm -f /tmp/b12r-sif.$$
|
||||||
|
/sbin/e2fsck -fn $OUT >/dev/null 2>&1 && echo "e2fsck -fn clean"
|
||||||
|
stat -c "%n %s" $OUT; sha256sum $OUT
|
||||||
8
b12/b12r/install-p27.sh
Normal file
8
b12/b12r/install-p27.sh
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B12R (board, Alpine primary root): install nftables + dnsmasq from a local repo (no network) + aurora-router. Writes only p27. Idempotent.
|
||||||
|
set -e; T=/tmp/b12r
|
||||||
|
rm -rf /var/cache/b12r; mkdir -p /var/cache/b12r; tar xzf $T/b12r-pkgs.tar.gz -C /var/cache/b12r
|
||||||
|
apk add --no-network --allow-untrusted --repositories-file /dev/null --repository /var/cache/b12r/pkgs nftables dnsmasq > $T/apk.log 2>&1 || { tail -15 $T/apk.log; echo "INSTALL FAIL"; exit 1; }
|
||||||
|
tail -2 $T/apk.log; tar xzf $T/b12r-overlay.tar.gz -C /; rm -rf /var/cache/b12r; sync
|
||||||
|
rc-update show default | grep -q aurora-router && echo "WARN: aurora-router is in a runlevel"
|
||||||
|
echo "nft=$(nft --version) dnsmasq=$(dnsmasq --version | head -1 | cut -d' ' -f3)"; echo "INSTALL OK"
|
||||||
10
b12/b12r/overlay/etc/aurora/router.conf
Normal file
10
b12/b12r/overlay/etc/aurora/router.conf
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
# Aurora router (B12R). Read by /usr/sbin/aurora-router. Wi-Fi LAN -> NAT -> LTE; USB NCM management stays isolated.
|
||||||
|
LAN_IF=wlan0
|
||||||
|
LAN_ADDR=192.168.77.1
|
||||||
|
LAN_PFX=24
|
||||||
|
LAN_NET=192.168.77.0/24
|
||||||
|
DHCP_RANGE=192.168.77.100,192.168.77.199,255.255.255.0,1h
|
||||||
|
WAN_IF=wwan0
|
||||||
|
MGMT_IF=usb0
|
||||||
|
MGMT_NET=172.16.42.0/24
|
||||||
|
FALLBACK_DNS="77.88.8.8" # only if /run/aurora-modem/ipcfg has no bearer DNS
|
||||||
13
b12/b12r/overlay/etc/init.d/aurora-router
Normal file
13
b12/b12r/overlay/etc/init.d/aurora-router
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
# B12R: Wi-Fi LAN router on top of aurora-modem (bearer) + aurora-wifi (AP). Waits for both in the background, then 'aurora-router up'.
|
||||||
|
# NOT in any runlevel until the cache kernel has nf_tables (7.2.7-aurora-b12); start manually: rc-service aurora-router start
|
||||||
|
description="Aurora Wi-Fi -> LTE router (nftables NAT + dnsmasq)"
|
||||||
|
depend() { need aurora-modem aurora-wifi; }
|
||||||
|
start() {
|
||||||
|
ebegin "aurora-router (waits for START OK + AP ENABLED)"
|
||||||
|
( i=0; while [ $i -lt 600 ]; do grep -q "=== START OK" /run/aurora-modem/lifecycle.log 2>/dev/null && grep -q "=== AP ENABLED" /run/aurora-wifi/wifi.log 2>/dev/null && break; sleep 2; i=$((i+2)); done
|
||||||
|
/usr/sbin/aurora-router up >> /run/aurora-router.service.log 2>&1 ) &
|
||||||
|
eend 0
|
||||||
|
}
|
||||||
|
stop() { ebegin "aurora-router down"; /usr/sbin/aurora-router down >> /run/aurora-router.service.log 2>&1; eend $?; }
|
||||||
|
status() { /usr/sbin/aurora-router status; }
|
||||||
91
b12/b12r/overlay/usr/sbin/aurora-router
Normal file
91
b12/b12r/overlay/usr/sbin/aurora-router
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Aurora router (B12R, runtime state only in /run): aurora-router up | down | status
|
||||||
|
# up: wlan0 192.168.77.1/24, default route via wwan0 (only if none), nftables table inet aurora_router (NAT LAN->wwan0, default-deny forward,
|
||||||
|
# no LTE->LAN, Wi-Fi blocked from the USB mgmt subnet and from every board address except 192.168.77.1 DHCP/DNS/ping), ip_forward=1,
|
||||||
|
# dnsmasq bound to wlan0 only (upstream = bearer DNS).
|
||||||
|
# down: undo exactly that. Needs kernel nf_tables (7.2.7-aurora-b12).
|
||||||
|
. /etc/aurora/router.conf
|
||||||
|
S=/run/aurora-router; LOG=$S/router.log; mkdir -p $S
|
||||||
|
now() { cut -d' ' -f1 /proc/uptime; }
|
||||||
|
log() { m="[$(now)] $*"; echo "$m"; echo "$m" >> $LOG; echo "<5>[aurora-router] $*" > /dev/kmsg 2>/dev/null; }
|
||||||
|
fail() { log "FAIL: $*"; exit 1; }
|
||||||
|
dpid() { [ -f $S/dnsmasq.pid ] && kill -0 "$(cat $S/dnsmasq.pid)" 2>/dev/null && cat $S/dnsmasq.pid; }
|
||||||
|
case "$1" in
|
||||||
|
up)
|
||||||
|
log "=== ROUTER UP"
|
||||||
|
nft list tables >/dev/null 2>&1 || fail "kernel has no nf_tables ($(uname -r))"
|
||||||
|
[ -e /sys/class/net/$LAN_IF ] || fail "$LAN_IF absent"; [ -e /sys/class/net/$WAN_IF ] || fail "$WAN_IF absent"
|
||||||
|
DNS=$(sed -n 's/^DNS=//p' /run/aurora-modem/ipcfg 2>/dev/null | tr ',' ' '); [ -n "$DNS" ] || DNS=$FALLBACK_DNS
|
||||||
|
[ -f $S/ip_forward.saved ] || cat /proc/sys/net/ipv4/ip_forward > $S/ip_forward.saved
|
||||||
|
ip -4 addr show dev $LAN_IF | grep -q "inet $LAN_ADDR/" || ip addr add $LAN_ADDR/$LAN_PFX dev $LAN_IF || fail "addr $LAN_IF"
|
||||||
|
if ! ip route | grep -q "^default"; then ip route add default dev $WAN_IF && echo $WAN_IF > $S/default.added || fail "default route"; fi
|
||||||
|
cat > $S/ruleset.nft <<N
|
||||||
|
table inet aurora_router
|
||||||
|
delete table inet aurora_router
|
||||||
|
table inet aurora_router {
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority filter; policy accept;
|
||||||
|
ct state established,related accept
|
||||||
|
iifname "lo" accept
|
||||||
|
iifname "$MGMT_IF" accept
|
||||||
|
iifname "$LAN_IF" jump lan_in
|
||||||
|
iifname "$WAN_IF" jump wan_in
|
||||||
|
}
|
||||||
|
chain lan_in {
|
||||||
|
udp sport 68 udp dport 67 accept comment "DHCP (incl. broadcast)"
|
||||||
|
ip daddr != $LAN_ADDR counter drop comment "Wi-Fi may not touch mgmt/WAN addresses of the board"
|
||||||
|
udp dport 53 accept
|
||||||
|
tcp dport 53 accept
|
||||||
|
icmp type echo-request limit rate 20/second accept
|
||||||
|
meta l4proto ipv6-icmp accept
|
||||||
|
counter drop
|
||||||
|
}
|
||||||
|
chain wan_in {
|
||||||
|
icmp type { echo-reply, destination-unreachable, time-exceeded } accept
|
||||||
|
counter drop comment "no unsolicited inbound from LTE"
|
||||||
|
}
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority filter; policy drop;
|
||||||
|
ct state invalid counter drop
|
||||||
|
iifname "$LAN_IF" oifname "$WAN_IF" ip saddr $LAN_NET counter accept
|
||||||
|
iifname "$WAN_IF" oifname "$LAN_IF" ct state established,related counter accept
|
||||||
|
iifname "$LAN_IF" oifname "$MGMT_IF" counter drop comment "Wi-Fi -> USB mgmt blocked"
|
||||||
|
iifname "$MGMT_IF" oifname "$LAN_IF" counter drop
|
||||||
|
counter drop comment "default deny (incl. LTE -> LAN)"
|
||||||
|
}
|
||||||
|
chain postrouting {
|
||||||
|
type nat hook postrouting priority srcnat; policy accept;
|
||||||
|
oifname "$WAN_IF" ip saddr $LAN_NET counter masquerade
|
||||||
|
}
|
||||||
|
}
|
||||||
|
N
|
||||||
|
nft -f $S/ruleset.nft || fail "nft ruleset"
|
||||||
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||||
|
if [ -z "$(dpid)" ]; then
|
||||||
|
{ echo "interface=$LAN_IF"; echo "except-interface=lo"; echo "bind-interfaces"; echo "no-resolv"; echo "no-hosts"
|
||||||
|
for d in $DNS; do echo "server=$d"; done
|
||||||
|
echo "dhcp-range=$DHCP_RANGE"; echo "dhcp-option=option:router,$LAN_ADDR"; echo "dhcp-option=option:dns-server,$LAN_ADDR"
|
||||||
|
echo "dhcp-leasefile=$S/dnsmasq.leases"; echo "dhcp-authoritative"; echo "cache-size=300"; echo "domain-needed"; echo "bogus-priv"
|
||||||
|
echo "pid-file=$S/dnsmasq.pid"; echo "log-facility=$S/dnsmasq.log"; echo "log-dhcp"; echo "user=root"; } > $S/dnsmasq.conf
|
||||||
|
dnsmasq --conf-file=$S/dnsmasq.conf || fail "dnsmasq"; sleep 1
|
||||||
|
fi
|
||||||
|
[ -n "$(dpid)" ] || fail "dnsmasq not running"
|
||||||
|
log "=== ROUTER UP OK lan $LAN_IF $LAN_ADDR/$LAN_PFX dhcp $DHCP_RANGE dns [$DNS] wan $WAN_IF default=[$(ip route | grep "^default")] fwd=$(cat /proc/sys/net/ipv4/ip_forward) dnsmasq=$(dpid)";;
|
||||||
|
down)
|
||||||
|
log "=== ROUTER DOWN"
|
||||||
|
p=$(dpid); [ -n "$p" ] && { kill $p; sleep 1; }; rm -f $S/dnsmasq.pid
|
||||||
|
nft list table inet aurora_router >/dev/null 2>&1 && nft delete table inet aurora_router
|
||||||
|
[ -f $S/ip_forward.saved ] && { cat $S/ip_forward.saved > /proc/sys/net/ipv4/ip_forward; rm -f $S/ip_forward.saved; }
|
||||||
|
ip addr del $LAN_ADDR/$LAN_PFX dev $LAN_IF 2>/dev/null
|
||||||
|
[ -f $S/default.added ] && { ip route del default dev "$(cat $S/default.added)" 2>/dev/null; rm -f $S/default.added; }
|
||||||
|
log "=== ROUTER DOWN OK fwd=$(cat /proc/sys/net/ipv4/ip_forward) tables=[$(nft list tables 2>/dev/null | tr '\n' ' ')] default=[$(ip route | grep "^default")]";;
|
||||||
|
status)
|
||||||
|
echo "kernel $(uname -r) ip_forward=$(cat /proc/sys/net/ipv4/ip_forward) dnsmasq=$(dpid)"
|
||||||
|
ip -4 addr show dev $LAN_IF | grep inet; ip route | grep "^default"
|
||||||
|
echo "-- leases"; cat $S/dnsmasq.leases 2>/dev/null
|
||||||
|
echo "-- stations"; iw dev $LAN_IF station dump 2>/dev/null | grep -E "^Station|signal:|connected time"
|
||||||
|
echo "-- conntrack $(cat /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null)"
|
||||||
|
nft list table inet aurora_router 2>&1 | grep -E "counter|chain"
|
||||||
|
tail -3 $LOG 2>/dev/null;;
|
||||||
|
*) echo "usage: $0 up|down|status"; exit 2;;
|
||||||
|
esac
|
||||||
23
b12/mk-alpine-rootfs.sh
Normal file
23
b12/mk-alpine-rootfs.sh
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Build the B12/B13 Alpine 3.24.2 aarch64 chroot tarball (RAM-only use on the board: /tmp/alpine tmpfs).
|
||||||
|
# minirootfs (sha-checked) + apk add X stack + prune of mesa/LLVM (Xorg does not link them; fbdev/modesetting w/o glamor) + overlay.
|
||||||
|
# Ownership/modes are preserved through fakeroot state. -> out/alpine-b13.tar.gz
|
||||||
|
set -e; cd "$(dirname "$0")"; A=$PWD/dl/apkst/sbin/apk.static; C=$PWD/dl/apkcache; W=${TMPDIR:-/tmp}/b12-alp.$$; R=$W/root; FS=$W/fakeroot.state
|
||||||
|
PKGS="xorg-server xf86-video-fbdev x11vnc xterm twm font-misc-misc xsetroot xdpyinfo e2fsprogs"
|
||||||
|
echo "9bf70a7f18ea44094cbb5f70c58f9af129c8214745743db0e68e5502cc2ce773 dl/alpine-minirootfs-3.24.2-aarch64.tar.gz" | sha256sum -c
|
||||||
|
mkdir -p $R out; touch $FS
|
||||||
|
fakeroot -s $FS tar xzf dl/alpine-minirootfs-3.24.2-aarch64.tar.gz -C $R
|
||||||
|
fakeroot -i $FS -s $FS $A --root $R --arch aarch64 --keys-dir $R/etc/apk/keys --cache-dir $C --no-scripts add $PKGS > $W/apk.log
|
||||||
|
tail -1 $W/apk.log; grep Installing $W/apk.log | sed 's/.*Installing //' > out/alpine-b13.pkgs
|
||||||
|
# prune (documented: apk db still lists mesa/llvm/spirv; files removed to fit RAM)
|
||||||
|
P="usr/lib/libLLVM* usr/lib/libgallium-* usr/lib/libSPIRV-Tools* usr/lib/gbm usr/lib/dri usr/lib/xorg/modules/libglamoregl.so usr/lib/xorg/modules/extensions/libglx.so usr/share/hwdata"
|
||||||
|
(cd $R && for p in $P; do ls -d $p 2>/dev/null; done) > out/alpine-b13.pruned
|
||||||
|
(cd $R && fakeroot -i $FS -s $FS rm -rf $P)
|
||||||
|
fakeroot -i $FS -s $FS cp -a alpine/overlay/. $R/
|
||||||
|
fakeroot -i $FS -s $FS sh -c "chown -R 0:0 $R/etc/X11/xorg.conf $R/etc/X11/xorg-modesetting.conf $R/usr/local/bin/aurora-x"
|
||||||
|
echo "aurora-b13-chroot" > $R/etc/hostname
|
||||||
|
# all NEEDED of Xorg, its modules and the X clients must still resolve (catch over-pruning)
|
||||||
|
for f in $R/usr/libexec/Xorg $R/usr/lib/xorg/modules/*.so $R/usr/lib/xorg/modules/*/*.so $R/usr/bin/x11vnc $R/usr/bin/xterm $R/usr/bin/twm; do aarch64-linux-gnu-readelf -d $f | sed -n 's/.*NEEDED.*\[\(.*\)\]/\1/p'; done | sort -u | while read n; do [ -e $R/usr/lib/$n ] || [ -e $R/lib/$n ] || { echo "UNRESOLVED $n"; exit 1; }; done
|
||||||
|
du -sm $R | awk '{print "rootfs MiB:", $1}'
|
||||||
|
(cd $R && fakeroot -i $FS tar --numeric-owner -czf - .) > out/alpine-b13.tar.gz; rm -rf $W
|
||||||
|
sha256sum out/alpine-b13.tar.gz; ls -l out/alpine-b13.tar.gz
|
||||||
14
b12/mk-e2fs-bundle.sh
Normal file
14
b12/mk-e2fs-bundle.sh
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Host-side e2fsprogs bundle (mke2fs/e2fsck/tune2fs/dumpe2fs from Alpine 3.24 aarch64, own musl loader) -> out/e2fs-bundle.tar.gz
|
||||||
|
# Board: /tmp/aurora-e2fs (provisioning) or initramfs /usr/libexec/aurora/e2fs (boot fsck). Run: $B/lib/ld-musl-aarch64.so.1 --library-path $B/lib $B/sbin/X
|
||||||
|
set -e; cd "$(dirname "$0")"; A=$PWD/dl/apkst/sbin/apk.static; W=${TMPDIR:-/tmp}/b12-e2.$$; R=$W/root; C=$PWD/dl/apkcache
|
||||||
|
mkdir -p $R/etc/apk out; tar xzf dl/alpine-minirootfs-3.24.2-aarch64.tar.gz -C $W ./etc/apk/keys ./etc/apk/repositories 2>/dev/null; cp -a $W/etc/apk/keys $W/etc/apk/repositories $R/etc/apk/
|
||||||
|
$A --root $R --arch aarch64 --keys-dir $R/etc/apk/keys --cache-dir $C --usermode --initdb --no-scripts add e2fsprogs > $W/apk.log
|
||||||
|
grep Installing $W/apk.log | sed 's/.*Installing //' > out/e2fs-bundle.pkgs
|
||||||
|
T=$W/aurora-e2fs; mkdir -p $T/lib $T/sbin; cp -L $R/lib/ld-musl-aarch64.so.1 $T/lib/
|
||||||
|
for b in mke2fs e2fsck; do cp -L $R/sbin/$b $T/sbin/ 2>/dev/null || cp -L $R/usr/sbin/$b $T/sbin/; done
|
||||||
|
need() { for f in "$@"; do aarch64-linux-gnu-readelf -d $f | sed -n 's/.*NEEDED.*\[\(.*\)\]/\1/p'; done | sort -u | grep -v '^libc.musl'; }
|
||||||
|
for i in 1 2 3; do for n in $(need $T/sbin/* $T/lib/*.so* 2>/dev/null); do [ -e $T/lib/$n ] || cp -L $(find $R/lib $R/usr/lib -name $n | head -1) $T/lib/; done; done
|
||||||
|
for n in $(need $T/sbin/* $T/lib/*.so*); do [ -e $T/lib/$n ] || { echo "UNRESOLVED $n"; exit 1; }; done
|
||||||
|
(cd $W && tar --owner=0 --group=0 --numeric-owner -czf - aurora-e2fs) > out/e2fs-bundle.tar.gz
|
||||||
|
ls $T/lib | tr '\n' ' '; echo; rm -rf $W; sha256sum out/e2fs-bundle.tar.gz
|
||||||
17
b12/mk-router-bundle.sh
Normal file
17
b12/mk-router-bundle.sh
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Build the B12 host-side router bundle (nft + dnsmasq from Alpine 3.24 aarch64, own musl loader) -> out/router-bundle.tar.gz
|
||||||
|
# Board: extracted to /tmp/aurora-router; binaries run as $B/lib/ld-musl-aarch64.so.1 --library-path $B/lib $B/sbin/X (host musl untouched).
|
||||||
|
set -e; cd "$(dirname "$0")"; A=$PWD/dl/apkst/sbin/apk.static; W=${TMPDIR:-/tmp}/b12-rt.$$; R=$W/root; C=$PWD/dl/apkcache
|
||||||
|
mkdir -p $R/etc/apk $C out; tar xzf dl/alpine-minirootfs-3.24.2-aarch64.tar.gz -C $W ./etc/apk/keys ./etc/apk/repositories 2>/dev/null; cp -a $W/etc/apk/keys $W/etc/apk/repositories $R/etc/apk/
|
||||||
|
$A --root $R --arch aarch64 --keys-dir $R/etc/apk/keys --cache-dir $C --usermode --initdb --no-scripts add nftables dnsmasq > $W/apk.log
|
||||||
|
grep -E "Installing" $W/apk.log | sed 's/.*Installing //' > out/router-bundle.pkgs
|
||||||
|
T=$W/aurora-router; mkdir -p $T/lib $T/sbin
|
||||||
|
cp -L $R/lib/ld-musl-aarch64.so.1 $T/lib/
|
||||||
|
for l in libnftables.so.1 libnftnl.so.11 libmnl.so.0 libjansson.so.4 libgmp.so.10 libreadline.so.8 libncursesw.so.6; do f=$(find $R/usr/lib $R/lib -name "$l" | head -1); [ -n "$f" ] || { echo "missing $l"; exit 1; }; cp -L $f $T/lib/; done
|
||||||
|
cp $R/usr/sbin/nft $R/usr/sbin/dnsmasq $T/sbin/
|
||||||
|
cp router/router.conf router/router-common.sh router/router-up.sh router/router-down.sh router/router-status.sh $T/
|
||||||
|
# every NEEDED must be in lib/
|
||||||
|
for f in $T/sbin/* $T/lib/*.so*; do aarch64-linux-gnu-readelf -d $f 2>/dev/null | sed -n 's/.*NEEDED.*\[\(.*\)\]/\1/p'; done | sort -u | while read n; do [ "$n" = libc.musl-aarch64.so.1 ] || [ -e $T/lib/$n ] || { echo "UNRESOLVED $n"; exit 1; }; done
|
||||||
|
(cd $W && tar --owner=0 --group=0 --numeric-owner -czf - aurora-router) > out/router-bundle.tar.gz
|
||||||
|
(cd $T && find . -type f | sort | xargs sha256sum) > out/router-bundle.files; rm -rf $W
|
||||||
|
sha256sum out/router-bundle.tar.gz; cat out/router-bundle.pkgs | tr '\n' ' '; echo
|
||||||
34
b12/persist/alpine-provision.sh
Normal file
34
b12/persist/alpine-provision.sh
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B12P-1 (board, ONE-TIME, DESTRUCTIVE to userdata only): format eMMC userdata as ext4 'aurora-alpine' and install the Alpine rootfs.
|
||||||
|
# alpine-provision.sh /tmp/b12/alpine-b13.tar.gz YES-FORMAT-USERDATA
|
||||||
|
# Gates: PARTNAME=userdata, expected start/size (S2 GPT), only this partition is switched RW and back to RO at the end.
|
||||||
|
TAR=$1; [ "$2" = YES-FORMAT-USERDATA ] || { echo "usage: $0 TAR YES-FORMAT-USERDATA"; exit 2; }
|
||||||
|
E=/tmp/aurora-e2fs; M=/mnt/aurora-alpine; LABEL=aurora-alpine
|
||||||
|
e2() { _b=$1; shift; $E/lib/ld-musl-aarch64.so.1 --library-path $E/lib $E/sbin/$_b "$@"; }
|
||||||
|
log() { echo "[$(cut -d' ' -f1 /proc/uptime)] P1 $*"; }
|
||||||
|
relock() { [ -n "$D" ] && blockdev --setro $D; blockdev --setro /dev/mmcblk0; }
|
||||||
|
fail() { log "FAIL: $*"; grep -q " $M " /proc/mounts && umount $M; relock; echo "PROVISION FAIL"; exit 1; }
|
||||||
|
others_ro() { for x in /dev/mmcblk0p*; do [ $x = $D ] && continue; [ "$(blockdev --getro $x)" = 1 ] || return 1; done; for x in /dev/mmcblk0boot*; do [ "$(blockdev --getro $x)" = 1 ] || return 1; done; }
|
||||||
|
D=; for p in /sys/class/block/mmcblk0p*; do [ "$(sed -n 's/^PARTNAME=//p' $p/uevent)" = userdata ] && D=/dev/$(basename $p); done
|
||||||
|
[ "$D" = /dev/mmcblk0p27 ] || fail "userdata is '$D', expected /dev/mmcblk0p27"
|
||||||
|
P=/sys/class/block/mmcblk0p27; [ "$(cat $P/start)" = 2428000 ] && [ "$(cat $P/size)" = 5206911 ] || fail "p27 geometry $(cat $P/start)/$(cat $P/size) unexpected"
|
||||||
|
grep -q "^/dev/mmcblk0" /proc/mounts && grep "^/dev/mmcblk0" /proc/mounts | grep -qv "^/dev/mmcblk0p1 " && fail "unexpected eMMC mount: $(grep ^/dev/mmcblk0 /proc/mounts)"
|
||||||
|
[ -f "$TAR" ] && [ -x $E/sbin/mke2fs ] || fail "missing $TAR or $E"
|
||||||
|
log "pre: stat=$(cat /sys/block/mmcblk0/stat | awk '{print "w="$5" ws="$7}') ro: disk=$(blockdev --getro /dev/mmcblk0) p27=$(blockdev --getro $D) p25=$(blockdev --getro /dev/mmcblk0p25)"
|
||||||
|
# disk-level RO masks partition RW: lift it on the disk, every other partition keeps its own RO flag (checked), RW only on p27
|
||||||
|
others_ro || fail "some other partition is not RO before start"
|
||||||
|
blockdev --setrw /dev/mmcblk0 && blockdev --setrw $D || fail "setrw"
|
||||||
|
[ "$(blockdev --getro $D)" = 0 ] || fail "p27 still RO"
|
||||||
|
others_ro || fail "other devices lost RO"
|
||||||
|
log "rw only on $D (disk flag lifted, p1..p26 + boot0/1 RO verified)"
|
||||||
|
e2 mke2fs -F -q -t ext4 -L $LABEL -m 1 -E nodiscard -O ^metadata_csum_seed $D || fail "mke2fs"
|
||||||
|
log "mke2fs ok"
|
||||||
|
mkdir -p $M; mount -t ext4 -o noatime $D $M || fail "mount"
|
||||||
|
tar xzf "$TAR" -C $M || fail "extract"
|
||||||
|
date -u +"provisioned %Y-%m-%dT%H:%M:%SZ from $(basename $TAR) $(sha256sum $TAR | cut -c1-8)" > $M/etc/aurora-alpine-release
|
||||||
|
sync; log "extracted: $(du -sk $M | cut -f1)k files=$(find $M -xdev | wc -l)"
|
||||||
|
umount $M || fail "umount"
|
||||||
|
e2 e2fsck -fn $D > /tmp/b12/p1-fsck.txt 2>&1; rc=$?; log "e2fsck -fn rc=$rc $(tail -1 /tmp/b12/p1-fsck.txt)"
|
||||||
|
relock; others_ro || log "WARN others_ro"; log "post: disk ro=$(blockdev --getro /dev/mmcblk0) p27 ro=$(blockdev --getro $D) stat=$(cat /sys/block/mmcblk0/stat | awk '{print "w="$5" ws="$7}')"
|
||||||
|
mount -t ext4 -o ro $D $M && { log "ro-mount ok: $(cat $M/etc/alpine-release) $(cat $M/etc/aurora-alpine-release)"; ls $M/usr/libexec/Xorg >/dev/null && log "Xorg present"; umount $M; }
|
||||||
|
[ $rc = 0 ] && echo "PROVISION OK" || echo "PROVISION FAIL fsck"
|
||||||
3
b12/pull.sh
Normal file
3
b12/pull.sh
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# 480s: fetch a small file from the board over NCM (port 9962). pull.sh BOARD_PATH LOCAL_PATH
|
||||||
|
cd "$(dirname "$0")"; ./tn.sh 2 "nc -l -p 9962 < $1 &" > /dev/null; sleep 1; ncat --recv-only 172.16.42.1 9962 > "$2"; ls -l "$2"
|
||||||
16
b12/push.sh
Normal file
16
b12/push.sh
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# 480s: push FILE to the board as DEST over NCM in 4 MiB chunks, each sha256-verified (retry up to 3x). Port 9943.
|
||||||
|
F=$1; DEST=$2; [ -f "$F" ] && [ -n "$DEST" ] || { echo "usage: $0 FILE DEST"; exit 2; }
|
||||||
|
cd "$(dirname "$0")"; W=$(mktemp -d); split -b 4M -d -a 3 "$F" $W/p.
|
||||||
|
./tn.sh 2 "rm -f $DEST.part.*" > /dev/null
|
||||||
|
for p in $W/p.*; do n=${p##*.}; h=$(sha256sum < $p | cut -c1-64); ok=
|
||||||
|
for t in 1 2 3; do
|
||||||
|
./tn.sh 2 "nc -l -p 9943 > $DEST.part.$n &" > /dev/null; sleep 1
|
||||||
|
timeout 60 ncat --send-only 172.16.42.1 9943 < $p
|
||||||
|
r=$(./tn.sh 3 "sha256sum $DEST.part.$n" | grep -o "^[0-9a-f]\{64\}")
|
||||||
|
[ "$r" = "$h" ] && { ok=1; break; }; echo "chunk $n try $t mismatch (${r:-none})"; ./tn.sh 2 "pkill -f 'nc -l -p 9943'" >/dev/null
|
||||||
|
done; [ -n "$ok" ] || { echo "PUSH FAIL chunk $n"; rm -rf $W; exit 1; }
|
||||||
|
done
|
||||||
|
H=$(sha256sum < "$F" | cut -c1-64)
|
||||||
|
r=$(./tn.sh 5 "cat $DEST.part.* > $DEST && rm -f $DEST.part.* && sha256sum $DEST" | grep -o "^[0-9a-f]\{64\}")
|
||||||
|
rm -rf $W; [ "$r" = "$H" ] && echo "PUSH OK $DEST $H" || { echo "PUSH FAIL final ($r)"; exit 1; }
|
||||||
7
b12/router/router-common.sh
Normal file
7
b12/router/router-common.sh
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# shellcheck shell=sh
|
||||||
|
. "$(dirname "$0")/router.conf"
|
||||||
|
now() { cut -d' ' -f1 /proc/uptime; }
|
||||||
|
log() { m="[$(now)] $*"; echo "$m"; mkdir -p $S; echo "$m" >> $S/router.log; }
|
||||||
|
bx() { _b=$1; shift; "$B/lib/ld-musl-aarch64.so.1" --library-path "$B/lib" "$B/sbin/$_b" "$@"; }
|
||||||
|
nft() { bx nft "$@"; }
|
||||||
|
dnsmasq_pid() { [ -f $S/dnsmasq.pid ] && kill -0 "$(cat $S/dnsmasq.pid)" 2>/dev/null && cat $S/dnsmasq.pid; }
|
||||||
11
b12/router/router-down.sh
Normal file
11
b12/router/router-down.sh
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B12 router-down: undo exactly what router-up did (dnsmasq, nft table, ip_forward, LAN addr, default route if we added it).
|
||||||
|
. "$(dirname "$0")/router-common.sh"
|
||||||
|
log "=== ROUTER DOWN"
|
||||||
|
p=$(dnsmasq_pid); [ -n "$p" ] && kill "$p" && sleep 1; [ -n "$(dnsmasq_pid)" ] && kill -9 "$(cat $S/dnsmasq.pid)"; rm -f $S/dnsmasq.pid
|
||||||
|
nft list table inet aurora_router >/dev/null 2>&1 && nft delete table inet aurora_router
|
||||||
|
F=0; [ -f $S/sysctl.saved ] && F=$(sed -n 's/^ip_forward=//p' $S/sysctl.saved); echo "${F:-0}" > /proc/sys/net/ipv4/ip_forward; rm -f $S/sysctl.saved
|
||||||
|
ip addr del $LAN_ADDR/$LAN_PFX dev $LAN_IF 2>/dev/null
|
||||||
|
[ -f $S/default.added ] && { ip route del default dev "$(cat $S/default.added)" 2>/dev/null; rm -f $S/default.added; }
|
||||||
|
log "down: fwd=$(cat /proc/sys/net/ipv4/ip_forward) tables=[$(nft list tables 2>/dev/null | tr '\n' ' ')] default=[$(ip route show default)]"
|
||||||
|
echo "ROUTER-DOWN OK"
|
||||||
12
b12/router/router-status.sh
Normal file
12
b12/router/router-status.sh
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B12 router-status: read-only.
|
||||||
|
. "$(dirname "$0")/router-common.sh"
|
||||||
|
echo "== kernel $(uname -r) ip_forward=$(cat /proc/sys/net/ipv4/ip_forward)"
|
||||||
|
echo "== addrs"; ip -4 addr show | grep -E "^[0-9]+:|inet "
|
||||||
|
echo "== routes"; ip route
|
||||||
|
echo "== dnsmasq pid=$(dnsmasq_pid)"; [ -f $S/dnsmasq.leases ] && cat $S/dnsmasq.leases
|
||||||
|
echo "== stations"; iw dev $LAN_IF station dump 2>/dev/null | grep -E "^Station|signal:|rx bytes|tx bytes|connected time"
|
||||||
|
echo "== conntrack $(cat /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null)/$(cat /proc/sys/net/netfilter/nf_conntrack_max 2>/dev/null)"
|
||||||
|
[ -r /proc/net/nf_conntrack ] && grep -c . /proc/net/nf_conntrack
|
||||||
|
echo "== nft"; nft list table inet aurora_router 2>&1
|
||||||
|
echo "== log"; tail -5 $S/router.log 2>/dev/null
|
||||||
77
b12/router/router-up.sh
Normal file
77
b12/router/router-up.sh
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B12 router-up (runtime-only, nothing persistent): Wi-Fi LAN -> DHCP/DNS (dnsmasq, LAN only) -> nftables NAT -> wwan0.
|
||||||
|
# USB NCM management (usb0) untouched; Wi-Fi clients cannot reach the board except DHCP/DNS/ping, nor the mgmt subnet.
|
||||||
|
. "$(dirname "$0")/router-common.sh"
|
||||||
|
set -u
|
||||||
|
fail() { log "FAIL: $*"; echo "ROUTER-UP FAIL"; exit 1; }
|
||||||
|
log "=== ROUTER UP"
|
||||||
|
[ -x $B/sbin/nft ] && [ -x $B/sbin/dnsmasq ] || fail "bundle $B missing"
|
||||||
|
nft list tables >/dev/null 2>&1 || fail "kernel has no nf_tables (needs 7.2.7-aurora-b12)"
|
||||||
|
[ -e /sys/class/net/$LAN_IF ] || fail "$LAN_IF absent"
|
||||||
|
[ -e /sys/class/net/$WAN_IF ] || fail "$WAN_IF absent"
|
||||||
|
DNS=; [ -f /run/aurora-modem/ipcfg ] && DNS=$(sed -n 's/^DNS=//p' /run/aurora-modem/ipcfg | tr ',' ' ')
|
||||||
|
[ -n "$DNS" ] || DNS=$FALLBACK_DNS
|
||||||
|
mkdir -p $S
|
||||||
|
# 1. sysctl (save originals once)
|
||||||
|
[ -f $S/sysctl.saved ] || { echo "ip_forward=$(cat /proc/sys/net/ipv4/ip_forward)" > $S/sysctl.saved; }
|
||||||
|
# 2. LAN address
|
||||||
|
ip -4 addr show dev $LAN_IF | grep -q "inet $LAN_ADDR/" || ip addr add $LAN_ADDR/$LAN_PFX dev $LAN_IF || fail "addr $LAN_IF"
|
||||||
|
# 3. default route via LTE (only if none); remember that we added it
|
||||||
|
if ! ip route show default | grep -q .; then ip route add default dev $WAN_IF && echo $WAN_IF > $S/default.added || fail "default route"; fi
|
||||||
|
# 4. nftables (own table only; flushed/recreated atomically)
|
||||||
|
cat > $S/ruleset.nft <<N
|
||||||
|
table inet aurora_router
|
||||||
|
delete table inet aurora_router
|
||||||
|
table inet aurora_router {
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority filter; policy accept;
|
||||||
|
ct state established,related accept
|
||||||
|
iifname "lo" accept
|
||||||
|
iifname "$MGMT_IF" accept
|
||||||
|
iifname "$LAN_IF" jump lan_in
|
||||||
|
iifname "$WAN_IF" jump wan_in
|
||||||
|
}
|
||||||
|
chain lan_in {
|
||||||
|
udp sport 68 udp dport 67 accept comment "DHCP (incl. broadcast)"
|
||||||
|
ip daddr != $LAN_ADDR counter drop comment "LAN may not touch mgmt/WAN addresses of the board"
|
||||||
|
udp dport 53 accept
|
||||||
|
tcp dport 53 accept
|
||||||
|
icmp type echo-request limit rate 20/second accept
|
||||||
|
meta l4proto ipv6-icmp accept
|
||||||
|
udp dport 547 drop
|
||||||
|
counter drop
|
||||||
|
}
|
||||||
|
chain wan_in {
|
||||||
|
icmp type { echo-reply, destination-unreachable, time-exceeded } accept
|
||||||
|
counter drop comment "no unsolicited inbound from LTE"
|
||||||
|
}
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority filter; policy drop;
|
||||||
|
ct state invalid counter drop
|
||||||
|
iifname "$LAN_IF" oifname "$WAN_IF" ip saddr $LAN_NET counter accept
|
||||||
|
iifname "$WAN_IF" oifname "$LAN_IF" ct state established,related counter accept
|
||||||
|
iifname "$LAN_IF" oifname "$MGMT_IF" counter drop comment "Wi-Fi -> USB mgmt blocked"
|
||||||
|
iifname "$MGMT_IF" oifname "$LAN_IF" counter drop
|
||||||
|
counter drop comment "default deny (incl. LTE -> LAN)"
|
||||||
|
}
|
||||||
|
chain postrouting {
|
||||||
|
type nat hook postrouting priority srcnat; policy accept;
|
||||||
|
oifname "$WAN_IF" ip saddr $LAN_NET counter masquerade
|
||||||
|
}
|
||||||
|
}
|
||||||
|
N
|
||||||
|
nft -f $S/ruleset.nft || fail "nft ruleset"
|
||||||
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||||
|
# 5. dnsmasq on LAN only
|
||||||
|
if [ -z "$(dnsmasq_pid)" ]; then
|
||||||
|
{ echo "interface=$LAN_IF"; echo "except-interface=lo"; echo "bind-interfaces"; echo "no-resolv"; echo "no-hosts"
|
||||||
|
for d in $DNS; do echo "server=$d"; done
|
||||||
|
echo "dhcp-range=$DHCP_RANGE"; echo "dhcp-option=option:router,$LAN_ADDR"; echo "dhcp-option=option:dns-server,$LAN_ADDR"
|
||||||
|
echo "dhcp-leasefile=$S/dnsmasq.leases"; echo "dhcp-authoritative"; echo "cache-size=300"; echo "domain-needed"; echo "bogus-priv"
|
||||||
|
echo "pid-file=$S/dnsmasq.pid"; echo "log-facility=$S/dnsmasq.log"; echo "log-dhcp"; echo "user=root"; } > $S/dnsmasq.conf
|
||||||
|
bx dnsmasq --conf-file=$S/dnsmasq.conf || fail "dnsmasq start"
|
||||||
|
sleep 1
|
||||||
|
fi
|
||||||
|
[ -n "$(dnsmasq_pid)" ] || fail "dnsmasq not running"
|
||||||
|
log "LAN $LAN_IF $LAN_ADDR/$LAN_PFX dhcp $DHCP_RANGE dns-up [$DNS] wan $WAN_IF fwd=$(cat /proc/sys/net/ipv4/ip_forward) dnsmasq=$(dnsmasq_pid)"
|
||||||
|
echo "ROUTER-UP OK"
|
||||||
12
b12/router/router.conf
Normal file
12
b12/router/router.conf
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
# B12 router (runtime-only). Sourced by router-*.sh on the board.
|
||||||
|
B=/tmp/aurora-router # bundle: lib/ld-musl + libs, sbin/nft, sbin/dnsmasq (Alpine 3.24)
|
||||||
|
S=/run/aurora-router # state: saved sysctls, pids, leases, log
|
||||||
|
LAN_IF=wlan0
|
||||||
|
LAN_ADDR=192.168.77.1
|
||||||
|
LAN_PFX=24
|
||||||
|
LAN_NET=192.168.77.0/24
|
||||||
|
DHCP_RANGE=192.168.77.100,192.168.77.199,255.255.255.0,1h
|
||||||
|
WAN_IF=wwan0
|
||||||
|
MGMT_IF=usb0
|
||||||
|
MGMT_NET=172.16.42.0/24
|
||||||
|
FALLBACK_DNS="77.88.8.8" # used only if /run/aurora-modem/ipcfg has no DNS
|
||||||
3
b12/tn.sh
Normal file
3
b12/tn.sh
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# 480s: run board commands over telnet. tn.sh WAIT 'cmd'... (one command per arg)
|
||||||
|
W=$1; shift; { sleep 1; for c in "$@"; do printf '%s\r\n' "$c"; done; sleep $W; } | ncat 172.16.42.1 23 | tr -d "\000\r" | sed -n '/# /,$p'
|
||||||
38
b12/vncshot.py
Normal file
38
b12/vncshot.py
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# Minimal RFB 3.8 client (security None, Raw encoding, 32bpp) -> PPM. Usage: vncshot.py HOST PORT OUT.ppm
|
||||||
|
import socket, struct, sys
|
||||||
|
h, p, out = sys.argv[1], int(sys.argv[2]), sys.argv[3]
|
||||||
|
s = socket.create_connection((h, p), 10)
|
||||||
|
def rx(n):
|
||||||
|
b = b''
|
||||||
|
while len(b) < n:
|
||||||
|
c = s.recv(n - len(b))
|
||||||
|
if not c: raise SystemExit('eof')
|
||||||
|
b += c
|
||||||
|
return b
|
||||||
|
ver = rx(12); s.sendall(b'RFB 003.008\n')
|
||||||
|
n = rx(1)[0]; types = rx(n)
|
||||||
|
if 1 not in types: raise SystemExit('no None auth: %r' % types)
|
||||||
|
s.sendall(b'\x01'); assert struct.unpack('>I', rx(4))[0] == 0
|
||||||
|
s.sendall(b'\x01')
|
||||||
|
w, hh = struct.unpack('>HH', rx(4)); rx(16); name = rx(struct.unpack('>I', rx(4))[0])
|
||||||
|
s.sendall(struct.pack('>BxxxBBBBHHHBBBxxx', 0, 32, 24, 0, 1, 255, 255, 255, 16, 8, 0))
|
||||||
|
s.sendall(struct.pack('>BxHi', 2, 1, 0))
|
||||||
|
s.sendall(struct.pack('>BBHHHH', 3, 0, 0, 0, w, hh))
|
||||||
|
img = bytearray(w * hh * 3)
|
||||||
|
got = 0
|
||||||
|
while got < w * hh:
|
||||||
|
t = rx(1)[0]
|
||||||
|
if t != 0: raise SystemExit('msg %d' % t)
|
||||||
|
rx(1); nr = struct.unpack('>H', rx(2))[0]
|
||||||
|
for _ in range(nr):
|
||||||
|
x, y, rw, rh, enc = struct.unpack('>HHHHi', rx(12))
|
||||||
|
px = rx(rw * rh * 4)
|
||||||
|
for j in range(rh):
|
||||||
|
for i in range(rw):
|
||||||
|
v = px[(j * rw + i) * 4:(j * rw + i) * 4 + 4]
|
||||||
|
o = ((y + j) * w + x + i) * 3
|
||||||
|
img[o:o + 3] = bytes((v[2], v[1], v[0]))
|
||||||
|
got += rw * rh
|
||||||
|
open(out, 'wb').write(b'P6 %d %d 255\n' % (w, hh) + img)
|
||||||
|
print('server', ver.strip().decode(), 'name', name.decode(), 'size %dx%d' % (w, hh))
|
||||||
9
b13/b13w-vnc-sway.txt
Normal file
9
b13/b13w-vnc-sway.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
tls TLSv1.3 TLS_AES_256_GCM_SHA384 cert sha256 d4469db93b0b5671
|
||||||
|
AUTH FAIL Invalid username or password
|
||||||
|
security types: [19, 129, 5] None offered: False
|
||||||
|
vencrypt subtypes: [262]
|
||||||
|
tls TLSv1.3 TLS_AES_256_GCM_SHA384 cert sha256 d4469db93b0b5671 pinned-match
|
||||||
|
AUTH OK subtype 262
|
||||||
|
desktop WayVNC 128 x 128
|
||||||
|
saved sway-vnc.ppm
|
||||||
|
saved sway-vnc-typed.ppm
|
||||||
4
b13/run/cage-down.sh
Normal file
4
b13/run/cage-down.sh
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
. /usr/local/lib/b13/run/wl-common.sh
|
||||||
|
pidof cage >/dev/null && { kill $(pidof cage); i=0; while pidof cage >/dev/null && [ $i -lt 50 ]; do sleep 0.1; i=$((i+1)); done; pidof cage >/dev/null && kill -9 $(pidof cage); }
|
||||||
|
rm -f $S/cage.pid $S/wayland-display; log "CAGE DOWN vt=$(cat /sys/class/tty/tty0/active)"
|
||||||
8
b13/run/cage-up.sh
Normal file
8
b13/run/cage-up.sh
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B13W: Cage (wlroots 0.20, Pixman) fullscreen on the ST7735S with the test UI. STOP_X=1 stops X11 first (X11 itself untouched).
|
||||||
|
. /usr/local/lib/b13/run/wl-common.sh
|
||||||
|
x_guard; seatd_up; t0=$(now)
|
||||||
|
setsid cage -d -s -- foot -o font=DejaVu\ Sans\ Mono:pixelsize=9 -o pad=0x0 -o colors.background=000000 -o csd.preferred=none -a b13 sh /usr/local/lib/b13/run/pattern.sh CAGE > $S/cage.log 2>&1 < /dev/null &
|
||||||
|
echo $! > $S/cage.pid; W=$(wait_socket) || { log "FAIL: cage socket (see $S/cage.log)"; tail -20 $S/cage.log; exit 1; }
|
||||||
|
echo $W > $S/wayland-display; i=0; while ! pidof foot >/dev/null && [ $i -lt 100 ]; do sleep 0.1; i=$((i+1)); done
|
||||||
|
log "CAGE UP socket=$W pid=$(pidof cage) foot=$(pidof foot) start=$(awk -v a=$t0 -v b=$(now) 'BEGIN{printf "%.2f", b-a}')s"
|
||||||
19
b13/run/pattern.sh
Normal file
19
b13/run/pattern.sh
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B13W test UI for 128x128 (inside foot): coloured corners (TL red, TR green, BL blue, BR white) + centre label + 1-cell white frame,
|
||||||
|
# so orientation, crop and colour order are visible at a glance; a typed line (VNC keyboard test) is echoed in green. Arg 1 = label.
|
||||||
|
L=${1:-WAYLAND}; T=
|
||||||
|
draw() {
|
||||||
|
set -- $(stty size 2>/dev/null); R=${1:-16}; C=${2:-21}
|
||||||
|
printf '\033[?25l\033[0m\033[2J'
|
||||||
|
cell() { printf '\033[%d;%dH\033[%sm \033[0m' $1 $2 "$3"; }
|
||||||
|
for c in $(seq 1 $C); do printf '\033[1;%dH\033[47m \033[%d;%dH\033[47m \033[0m' $c $R $c; done
|
||||||
|
for r in $(seq 1 $R); do printf '\033[%d;1H\033[47m \033[%d;%dH\033[47m \033[0m' $r $r $C; done
|
||||||
|
cell 2 2 41; cell 2 $((C-2)) 42; cell $((R-1)) 2 44; cell $((R-1)) $((C-2)) 107
|
||||||
|
printf '\033[%d;%dH\033[1;93m%s\033[0m' $((R/2-1)) $(( (C-${#L})/2 + 1 )) "$L"
|
||||||
|
printf '\033[%d;%dH\033[96m%sx%s\033[0m' $((R/2+1)) $(( (C-${#C}-${#R}-1)/2 + 1 )) "$C" "$R"
|
||||||
|
printf '\033[%d;3H\033[92m%s\033[0m' $((R-3)) "$T"
|
||||||
|
}
|
||||||
|
trap draw WINCH
|
||||||
|
s0=; for i in 1 2 3 4 5 6 7 8 9 10; do s=$(stty size 2>/dev/null); [ -n "$s" ] && [ "$s" = "$s0" ] && break; s0=$s; sleep 0.3; done
|
||||||
|
draw; stty -echo -icanon 2>/dev/null
|
||||||
|
while :; do c=$(dd bs=1 count=1 2>/dev/null) || continue; case "$c" in '') T=;; *) T="$T$c";; esac; R=$(stty size | cut -d' ' -f1); printf '\033[%d;3H\033[K\033[92m%s\033[0m' $((R-3)) "$T"; done
|
||||||
4
b13/run/sway-down.sh
Normal file
4
b13/run/sway-down.sh
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
. /usr/local/lib/b13/run/wl-common.sh
|
||||||
|
pidof sway >/dev/null && { WAYLAND_DISPLAY=$(cat $S/wayland-display 2>/dev/null) SWAYSOCK=$(ls /run/user/0/sway-ipc.* 2>/dev/null | head -1) swaymsg exit >/dev/null 2>&1; i=0; while pidof sway >/dev/null && [ $i -lt 50 ]; do sleep 0.1; i=$((i+1)); done; pidof sway >/dev/null && kill $(pidof sway); }
|
||||||
|
rm -f $S/sway.pid $S/wayland-display; log "SWAY DOWN vt=$(cat /sys/class/tty/tty0/active)"
|
||||||
8
b13/run/sway-up.sh
Normal file
8
b13/run/sway-up.sh
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B13W: Sway (debug/remote compositor) with /usr/local/lib/b13/run/sway.conf. STOP_X=1 stops X11 first.
|
||||||
|
. /usr/local/lib/b13/run/wl-common.sh
|
||||||
|
x_guard; seatd_up; t0=$(now)
|
||||||
|
setsid sway -c /usr/local/lib/b13/run/sway.conf > $S/sway.log 2>&1 < /dev/null &
|
||||||
|
echo $! > $S/sway.pid; W=$(wait_socket) || { log "FAIL: sway socket (see $S/sway.log)"; tail -20 $S/sway.log; exit 1; }
|
||||||
|
echo $W > $S/wayland-display; i=0; while ! pidof foot >/dev/null && [ $i -lt 100 ]; do sleep 0.1; i=$((i+1)); done
|
||||||
|
log "SWAY UP socket=$W pid=$(pidof sway) foot=$(pidof foot) start=$(awk -v a=$t0 -v b=$(now) 'BEGIN{printf "%.2f", b-a}')s"
|
||||||
15
b13/run/sway.conf
Normal file
15
b13/run/sway.conf
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
# B13W minimal sway for 128x128: no bar, no wallpaper (no swaybg), no borders/titles, one workspace, fullscreen test client.
|
||||||
|
xwayland disable
|
||||||
|
swaybg_command -
|
||||||
|
default_border none
|
||||||
|
default_floating_border none
|
||||||
|
titlebar_padding 1
|
||||||
|
titlebar_border_thickness 0
|
||||||
|
gaps inner 0
|
||||||
|
focus_follows_mouse no
|
||||||
|
font pango:DejaVu Sans Mono 6
|
||||||
|
output * scale 1
|
||||||
|
seat * hide_cursor 5000
|
||||||
|
workspace_auto_back_and_forth no
|
||||||
|
for_window [app_id="b13"] fullscreen enable
|
||||||
|
exec foot -o font=DejaVu\ Sans\ Mono:pixelsize=9 -o pad=0x0 -o colors.background=000000 -o csd.preferred=none -a b13 sh /usr/local/lib/b13/run/pattern.sh SWAY
|
||||||
4
b13/run/wayvnc-down.sh
Normal file
4
b13/run/wayvnc-down.sh
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/sh
|
||||||
|
. /usr/local/lib/b13/run/wl-common.sh
|
||||||
|
pidof wayvnc >/dev/null && { kill $(pidof wayvnc); sleep 1; pidof wayvnc >/dev/null && kill -9 $(pidof wayvnc); }
|
||||||
|
rm -f $S/wayvnc.pid; log "WAYVNC DOWN"
|
||||||
10
b13/run/wayvnc-up.sh
Normal file
10
b13/run/wayvnc-up.sh
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B13W: wayvnc on the running compositor's physical output (SPI-1). Bind 172.16.42.1 (USB NCM mgmt) only; auth = VeNCrypt TLS + user/password.
|
||||||
|
# Config /etc/aurora/wayvnc/config (root 600): address, port, enable_auth, username, password, private_key_file, certificate_file.
|
||||||
|
. /usr/local/lib/b13/run/wl-common.sh
|
||||||
|
W=$(cat $S/wayland-display 2>/dev/null); [ -n "$W" ] && [ -S $XDG_RUNTIME_DIR/$W ] || { log "FAIL: no compositor running"; exit 1; }
|
||||||
|
pidof wayvnc >/dev/null && { log "wayvnc already running"; exit 0; }
|
||||||
|
WAYLAND_DISPLAY=$W setsid wayvnc -C /etc/aurora/wayvnc/config -o SPI-1 -S $S/wayvnc.sock -v > $S/wayvnc.log 2>&1 < /dev/null &
|
||||||
|
echo $! > $S/wayvnc.pid; sleep 3
|
||||||
|
pidof wayvnc >/dev/null || { log "FAIL: wayvnc exited"; tail -15 $S/wayvnc.log; exit 1; }
|
||||||
|
log "WAYVNC UP on $W pid=$(pidof wayvnc) listen=[$(netstat -ltn | awk '$4 ~ /:5900$/ {printf "%s ", $4}')]"
|
||||||
19
b13/run/wl-common.sh
Normal file
19
b13/run/wl-common.sh
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# B13W common environment (sourced). Software rendering only (wlroots Pixman), DRM backend on the ST7735S card0, seatd seat.
|
||||||
|
# X11 (aurora-x: Xorg fbdev + x11vnc) is never modified; it is only stopped while a compositor holds the display (STOP_X=1).
|
||||||
|
B13=/usr/local/lib/b13; S=/run/b13; mkdir -p $S
|
||||||
|
export XDG_RUNTIME_DIR=/run/user/0; mkdir -p -m 0700 $XDG_RUNTIME_DIR
|
||||||
|
export WLR_RENDERER=pixman WLR_BACKENDS=drm,libinput WLR_DRM_DEVICES=/dev/dri/card0 WLR_LIBINPUT_NO_DEVICES=1 LIBSEAT_BACKEND=seatd
|
||||||
|
now() { cut -d' ' -f1 /proc/uptime; }
|
||||||
|
log() { echo "[$(now)] $*" | tee -a $S/b13.log; }
|
||||||
|
x_guard() {
|
||||||
|
if pidof Xorg >/dev/null; then
|
||||||
|
[ "${STOP_X:-0}" = 1 ] || { log "FAIL: Xorg is running (holds the panel); rerun with STOP_X=1"; exit 1; }
|
||||||
|
log "stopping X11 (aurora-x stop) for the compositor test"; /usr/local/bin/aurora-x stop >> $S/b13.log 2>&1; echo 1 > $S/x-was-running
|
||||||
|
fi
|
||||||
|
for c in cage sway; do pidof $c >/dev/null && { log "FAIL: $c already running"; exit 1; }; done
|
||||||
|
}
|
||||||
|
seatd_up() { pidof seatd >/dev/null || { seatd -g video > $S/seatd.log 2>&1 & i=0; while [ ! -S /run/seatd.sock ] && [ $i -lt 50 ]; do sleep 0.1; i=$((i+1)); done; }; [ -S /run/seatd.sock ] || { log "FAIL: seatd"; exit 1; }; }
|
||||||
|
wait_socket() { i=0; while [ $i -lt 300 ]; do for w in $XDG_RUNTIME_DIR/wayland-*; do case $w in *.lock) ;; *) [ -S "$w" ] && { basename $w; return 0; };; esac; done; sleep 0.1; i=$((i+1)); done; return 1; }
|
||||||
|
# RSS kB and CPU% (utime+stime over N s) of a pid
|
||||||
|
measure() { p=$1; n=${2:-30}; hz=100; a=$(awk '{print $14+$15}' /proc/$p/stat); t0=$(now); sleep $n; b=$(awk '{print $14+$15}' /proc/$p/stat); t1=$(now)
|
||||||
|
echo "pid=$p rss_kB=$(awk '/VmRSS/{print $2}' /proc/$p/status) cpu%=$(awk -v a=$a -v b=$b -v t0=$t0 -v t1=$t1 -v hz=$hz 'BEGIN{printf "%.2f", (b-a)/hz/(t1-t0)*100}') over ${n}s"; }
|
||||||
60
b13/vnc-vencrypt.py
Normal file
60
b13/vnc-vencrypt.py
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# B13W test client: RFB 3.8 + VeNCrypt X509Plain/TLSPlain (wayvnc enable_auth), raw 32bpp screenshot -> PPM, optional key/pointer input.
|
||||||
|
# vnc-vencrypt.py HOST PORT USER PASSFILE OUT.ppm [TEXT_TO_TYPE] [CERT_SHA256]
|
||||||
|
import socket, ssl, struct, sys, time, hashlib
|
||||||
|
h, p, user, pwf, out = sys.argv[1], int(sys.argv[2]), sys.argv[3], sys.argv[4], sys.argv[5]
|
||||||
|
text = sys.argv[6] if len(sys.argv) > 6 else ''; fp = sys.argv[7].replace(':', '').lower() if len(sys.argv) > 7 else ''
|
||||||
|
pw = open(pwf).read().strip()
|
||||||
|
s = socket.create_connection((h, p), 10)
|
||||||
|
def rx(n, c=None):
|
||||||
|
c = c or s; b = b''
|
||||||
|
while len(b) < n:
|
||||||
|
d = c.recv(n - len(b))
|
||||||
|
if not d: raise SystemExit('EOF')
|
||||||
|
b += d
|
||||||
|
return b
|
||||||
|
ver = rx(12); s.sendall(b'RFB 003.008\n')
|
||||||
|
n = rx(1)[0]
|
||||||
|
if n == 0: raise SystemExit('server refused: ' + rx(struct.unpack('>I', rx(4))[0]).decode())
|
||||||
|
types = list(rx(n)); print('security types:', types, 'None offered:', 1 in types)
|
||||||
|
assert 19 in types, 'no VeNCrypt'
|
||||||
|
s.sendall(b'\x13'); sv = rx(2); s.sendall(b'\x00\x02'); assert rx(1) == b'\x00'
|
||||||
|
m = rx(1)[0]; subs = [struct.unpack('>I', rx(4))[0] for _ in range(m)]; print('vencrypt subtypes:', subs)
|
||||||
|
st = 262 if 262 in subs else 259; s.sendall(struct.pack('>I', st)); assert rx(1) == b'\x01'
|
||||||
|
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT); ctx.check_hostname = False; ctx.verify_mode = ssl.CERT_NONE
|
||||||
|
t = ctx.wrap_socket(s); cert = t.getpeercert(binary_form=True)
|
||||||
|
cfp = hashlib.sha256(cert).hexdigest() if cert else '-'; print('tls', t.version(), t.cipher()[0], 'cert sha256', cfp[:16], 'pinned-match' if fp and cfp == fp else '')
|
||||||
|
if fp: assert cfp == fp, 'certificate fingerprint mismatch'
|
||||||
|
s = t
|
||||||
|
s.sendall(struct.pack('>II', len(user), len(pw)) + user.encode() + pw.encode())
|
||||||
|
r = struct.unpack('>I', rx(4))[0]
|
||||||
|
if r != 0:
|
||||||
|
try: reason = rx(struct.unpack('>I', rx(4))[0]).decode()
|
||||||
|
except SystemExit: reason = ''
|
||||||
|
print('AUTH FAIL', reason); sys.exit(3)
|
||||||
|
print('AUTH OK subtype', st)
|
||||||
|
s.sendall(b'\x01'); w, hh = struct.unpack('>HH', rx(4)); rx(16); name = rx(struct.unpack('>I', rx(4))[0]).decode(); print('desktop', name, w, 'x', hh)
|
||||||
|
s.sendall(struct.pack('>BxxxBBBBHHHBBBxxx', 0, 32, 24, 0, 1, 255, 255, 255, 16, 8, 0)); s.sendall(struct.pack('>BxHi', 2, 1, 0))
|
||||||
|
def grab(path):
|
||||||
|
s.sendall(struct.pack('>BBHHHH', 3, 0, 0, 0, w, hh)); img = bytearray(w * hh * 3); got = 0
|
||||||
|
while got < w * hh:
|
||||||
|
mt = rx(1)[0]
|
||||||
|
if mt == 2: continue
|
||||||
|
if mt == 1: rx(5); continue
|
||||||
|
if mt != 0: raise SystemExit('msg %d' % mt)
|
||||||
|
rx(1); nr = struct.unpack('>H', rx(2))[0]
|
||||||
|
for _ in range(nr):
|
||||||
|
x, y, rw, rh, enc = struct.unpack('>HHHHi', rx(12))
|
||||||
|
if enc != 0: continue
|
||||||
|
px = rx(rw * rh * 4)
|
||||||
|
for j in range(rh):
|
||||||
|
for i in range(rw):
|
||||||
|
v = px[(j*rw+i)*4:(j*rw+i)*4+4]; o = ((y+j)*w + x+i)*3; img[o:o+3] = bytes((v[2], v[1], v[0]))
|
||||||
|
got += rw * rh
|
||||||
|
open(path, 'wb').write(b'P6 %d %d 255\n' % (w, hh) + img); print('saved', path)
|
||||||
|
grab(out)
|
||||||
|
if text:
|
||||||
|
s.sendall(struct.pack('>BBHH', 5, 0, 64, 64)); time.sleep(0.2) # pointer to the centre (virtual pointer)
|
||||||
|
for ch in text:
|
||||||
|
k = ord(ch); s.sendall(struct.pack('>BBxxI', 4, 1, k)); s.sendall(struct.pack('>BBxxI', 4, 0, k)); time.sleep(0.05)
|
||||||
|
time.sleep(1.5); grab(out.replace('.ppm', '-typed.ppm'))
|
||||||
19
b14/README.md
Normal file
19
b14/README.md
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# B14 — aurora-ui: 128x128 modem status screen (Cage + SDL2/Wayland)
|
||||||
|
|
||||||
|
```
|
||||||
|
DRM/KMS card0 (SPI-1, ST7735S) ← Cage (wlroots 0.20, Pixman) ← aurora-ui (SDL2 2.32.10, video driver wayland,
|
||||||
|
GL renderer = Mesa llvmpipe via EGL/wl_shm, no GPU)
|
||||||
|
```
|
||||||
|
|
||||||
|
- `src/aurora-ui.c` — ~350 lines of C, software-drawn 128x128 ARGB frame (8x16 cp437 font from Linux `lib/fonts/font_8x16.c`, GPL-2.0),
|
||||||
|
uploaded once per second or on change. Worker thread: modem controller state files every 2 s, `mmcli` + `iw` every 5 s (timeout 3 s).
|
||||||
|
Main thread: sysfs/procfs every 1 s (wwan0 counters → throughput, default route, B10 LBC supervisor state + VADC VBAT, USB online,
|
||||||
|
pm8916-thermal). Missing sources show `--`; no SOC is invented (no fuel gauge) — only VBAT.
|
||||||
|
- `src/Makefile` — build on the board: `apk add build-base sdl2-dev && make && make install` (→ /usr/local/bin/aurora-ui).
|
||||||
|
- `config/aurora-ui.conf` → /etc/aurora/aurora-ui.conf: `TZ` for the clock, `LIBGL_ALWAYS_SOFTWARE=1`.
|
||||||
|
- `run/ui-up.sh [--stop-gui]`, `run/ui-stop.sh`, `run/ui-status.sh` → /usr/local/lib/b14/run/. wayvnc: reuse `b13/run/wayvnc-up.sh`
|
||||||
|
(write the socket name to /run/b13/wayland-display first; 172.16.42.1:5900, TLS + password).
|
||||||
|
- `run/aurora-ui.openrc` → /etc/init.d/aurora-ui (not enabled). `run/soak.sh` — read-only 1/min observer.
|
||||||
|
|
||||||
|
Runtime packages (Alpine 3.24): sdl2, wayland-libs-egl (SDL dlopens libwayland-egl; without it SDL2 segfaults in Wayland_CreateWindow),
|
||||||
|
mesa (libEGL/libgallium llvmpipe), cage, seatd. Build only: build-base, sdl2-dev.
|
||||||
3
b14/config/aurora-ui.conf
Normal file
3
b14/config/aurora-ui.conf
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# B14 aurora-ui launcher settings (sourced by ui-up.sh).
|
||||||
|
TZ=MSK-3 # POSIX TZ for the clock (UTC+3); system clock itself stays UTC
|
||||||
|
LIBGL_ALWAYS_SOFTWARE=1 # no GPU/render node: Mesa EGL via zink on lavapipe (mesa-vulkan-swrast)
|
||||||
14
b14/run/aurora-ui.openrc
Normal file
14
b14/run/aurora-ui.openrc
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
# B14: Cage + aurora-ui on the ST7735S (installed as /etc/init.d/aurora-ui; NOT in any runlevel until a separate GO).
|
||||||
|
# Starts early: needs only the display (fbcon/backlight) and NCM for diagnostics; the modem/Wi-Fi keep starting in parallel —
|
||||||
|
# aurora-ui itself shows "MODEM STARTING" until the modem controller reports START OK. Boot never depends on the GUI:
|
||||||
|
# a failing UI just leaves fbcon/getty on tty1. `rc-service aurora-ui stop` returns the console.
|
||||||
|
description="Aurora 128x128 status UI (Cage + SDL2 Wayland)"
|
||||||
|
depend() { need aurora-display; after aurora-ncm aurora-ro; }
|
||||||
|
start() {
|
||||||
|
ebegin "aurora-ui (Cage + SDL2)"
|
||||||
|
( sh /usr/local/lib/b14/run/ui-up.sh --stop-gui >> /run/aurora-ui.service.log 2>&1 ) &
|
||||||
|
eend 0
|
||||||
|
}
|
||||||
|
stop() { ebegin "aurora-ui stop"; sh /usr/local/lib/b14/run/ui-stop.sh >> /run/aurora-ui.service.log 2>&1; eend 0; }
|
||||||
|
status() { sh /usr/local/lib/b14/run/ui-status.sh; }
|
||||||
24
b14/run/soak.sh
Normal file
24
b14/run/soak.sh
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B14 soak observer (read-only): one line per minute for N minutes -> /run/aurora-ui/soak.log
|
||||||
|
N=${1:-15}; O=/run/aurora-ui/soak.log; hz=100
|
||||||
|
dm0=$(dmesg | grep -ciE "error|fail|oops|bug:|warn")
|
||||||
|
cpu() { awk '{print $14+$15}' /proc/$1/stat 2>/dev/null; }
|
||||||
|
U=$(pidof aurora-ui); C=$(pidof cage); u0=$(cpu $U); c0=$(cpu $C); t0=$(cut -d' ' -f1 /proc/uptime)
|
||||||
|
echo "# t ui_rss cage_rss ui_cpu% cage_cpu% modem ping wifi_cl fwd_pkts chg vbat pmic dmesg_new mmc_writes(p27/other) mem_avail" > $O
|
||||||
|
for i in $(seq 1 $N); do
|
||||||
|
sleep 60
|
||||||
|
U2=$(pidof aurora-ui); C2=$(pidof cage); t=$(cut -d' ' -f1 /proc/uptime)
|
||||||
|
u=$(cpu $U2); c=$(cpu $C2)
|
||||||
|
uc=$(awk -v a=$u0 -v b=$u -v d=$(awk -v x=$t0 -v y=$t 'BEGIN{print y-x}') -v hz=$hz 'BEGIN{printf "%.2f",(b-a)/hz/d*100}')
|
||||||
|
cc=$(awk -v a=$c0 -v b=$c -v d=$(awk -v x=$t0 -v y=$t 'BEGIN{print y-x}') -v hz=$hz 'BEGIN{printf "%.2f",(b-a)/hz/d*100}')
|
||||||
|
u0=$u; c0=$c; t0=$t
|
||||||
|
p=$(ping -c1 -W3 77.88.8.8 >/dev/null 2>&1 && echo ok || echo LOSS)
|
||||||
|
cl=$(iw dev wlan0 station dump 2>/dev/null | grep -c ^Station)
|
||||||
|
fw=$(nft list chain inet aurora_router forward 2>/dev/null | awk '/oifname "wwan0"/{for(i=1;i<=NF;i++) if($i=="packets") print $(i+1)}')
|
||||||
|
ch=$(awk '/^state/{print $2"/"$6}' /sys/kernel/debug/pm8916_lbc/state)
|
||||||
|
tz=$(for z in /sys/class/thermal/thermal_zone*; do [ "$(cat $z/type)" = pm8916-thermal ] && cat $z/temp; done)
|
||||||
|
dm=$(( $(dmesg | grep -ciE "error|fail|oops|bug:|warn") - dm0 ))
|
||||||
|
w27=$(awk '{print $5}' /sys/class/block/mmcblk0p27/stat); wo=0; for q in /sys/class/block/mmcblk0p* /sys/class/block/mmcblk0boot0 /sys/class/block/mmcblk0boot1; do [ "$q" = /sys/class/block/mmcblk0p27 ] && continue; wo=$((wo + $(awk '{print $5}' $q/stat))); done
|
||||||
|
echo "$t $(awk '/VmRSS/{print $2}' /proc/$U2/status) $(awk '/VmRSS/{print $2}' /proc/$C2/status) $uc $cc $(cat /run/aurora-modem/state) $p $cl ${fw:--} $ch $tz $dm $w27/$wo $(awk '/MemAvailable/{print $2}' /proc/meminfo) pids=$U2/$C2" >> $O
|
||||||
|
done
|
||||||
|
echo "# SOAK END" >> $O
|
||||||
8
b14/run/ui-status.sh
Normal file
8
b14/run/ui-status.sh
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B14: read-only status of Cage + aurora-ui (+ wayvnc).
|
||||||
|
uipid() { for p in /proc/[0-9]*; do [ "$(readlink $p/exe 2>/dev/null)" = /usr/local/bin/aurora-ui ] && echo ${p#/proc/}; done; } # not pidof: /etc/init.d/aurora-ui has the same comm
|
||||||
|
D=/run/aurora-ui
|
||||||
|
for p in cage aurora-ui wayvnc seatd; do if [ $p = aurora-ui ]; then q=$(uipid); else q=$(pidof $p); fi; [ -n "$q" ] && echo "$p pid=$q rss_kB=$(awk '/VmRSS/{print $2}' /proc/${q%% *}/status)" || echo "$p -"; done
|
||||||
|
echo "socket=$(cat $D/wayland-display 2>/dev/null) vt=$(cat /sys/class/tty/tty0/active)"
|
||||||
|
grep -E "video driver|renderer|first frame" $D/cage.log 2>/dev/null | sed 's/^/ /'
|
||||||
|
tail -3 $D/ui.log 2>/dev/null
|
||||||
10
b14/run/ui-stop.sh
Normal file
10
b14/run/ui-stop.sh
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B14: stop Cage + aurora-ui (and wayvnc if it was attached); fbcon/tty1 comes back when Cage releases the VT.
|
||||||
|
uipid() { for p in /proc/[0-9]*; do [ "$(readlink $p/exe 2>/dev/null)" = /usr/local/bin/aurora-ui ] && echo ${p#/proc/}; done; } # not pidof: /etc/init.d/aurora-ui has the same comm
|
||||||
|
D=/run/aurora-ui; L=$D/ui.log; mkdir -p $D
|
||||||
|
pidof wayvnc >/dev/null && sh /usr/local/lib/b13/run/wayvnc-down.sh >/dev/null 2>&1
|
||||||
|
P=$(cat $D/cage.pid 2>/dev/null)
|
||||||
|
if [ -n "$P" ] && kill -0 $P 2>/dev/null; then kill $P; i=0; while kill -0 $P 2>/dev/null && [ $i -lt 50 ]; do sleep 0.1; i=$((i+1)); done; kill -0 $P 2>/dev/null && kill -9 $P; fi
|
||||||
|
P2=$(uipid); [ -n "$P2" ] && kill $P2
|
||||||
|
rm -f $D/cage.pid $D/wayland-display
|
||||||
|
echo "[$(cut -d' ' -f1 /proc/uptime)] UI STOPPED vt=$(cat /sys/class/tty/tty0/active)" | tee -a $L
|
||||||
32
b14/run/ui-up.sh
Normal file
32
b14/run/ui-up.sh
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B14: Cage + aurora-ui (SDL2, Wayland) on the ST7735S. Usage: ui-up.sh [--stop-gui]
|
||||||
|
uipid() { for p in /proc/[0-9]*; do [ "$(readlink $p/exe 2>/dev/null)" = /usr/local/bin/aurora-ui ] && echo ${p#/proc/}; done; } # not pidof: /etc/init.d/aurora-ui has the same comm
|
||||||
|
# Refuses if Xorg / Cage / Sway already hold the panel, unless --stop-gui (then aurora-x / b13 cage / b13 sway are stopped cleanly).
|
||||||
|
# One instance only; state in /run/aurora-ui. Equivalent to `cage -- /usr/local/bin/aurora-ui` with the Pixman/seatd environment.
|
||||||
|
D=/run/aurora-ui; mkdir -p $D; L=$D/ui.log
|
||||||
|
now() { cut -d' ' -f1 /proc/uptime; }
|
||||||
|
log() { echo "[$(now)] $*" | tee -a $L; }
|
||||||
|
[ -f /etc/aurora/aurora-ui.conf ] && . /etc/aurora/aurora-ui.conf
|
||||||
|
export TZ LIBGL_ALWAYS_SOFTWARE SDL_VIDEODRIVER=wayland
|
||||||
|
export XDG_RUNTIME_DIR=/run/user/0; mkdir -p -m 0700 $XDG_RUNTIME_DIR
|
||||||
|
export WLR_RENDERER=pixman WLR_BACKENDS=drm,libinput WLR_DRM_DEVICES=/dev/dri/card0 WLR_LIBINPUT_NO_DEVICES=1 LIBSEAT_BACKEND=seatd
|
||||||
|
[ -f $D/cage.pid ] && kill -0 "$(cat $D/cage.pid)" 2>/dev/null && { log "aurora-ui already running (cage $(cat $D/cage.pid))"; exit 0; }
|
||||||
|
busy=$(for p in Xorg cage sway; do pidof $p >/dev/null && echo $p; done | tr '\n' ' ')
|
||||||
|
if [ -n "$busy" ]; then
|
||||||
|
[ "$1" = --stop-gui ] || { log "FAIL: display held by: $busy(use --stop-gui)"; exit 1; }
|
||||||
|
pidof wayvnc >/dev/null && sh /usr/local/lib/b13/run/wayvnc-down.sh >/dev/null 2>&1
|
||||||
|
pidof Xorg >/dev/null && { log "stopping X11"; /usr/local/bin/aurora-x stop >> $L 2>&1; }
|
||||||
|
pidof sway >/dev/null && sh /usr/local/lib/b13/run/sway-down.sh >> $L 2>&1
|
||||||
|
pidof cage >/dev/null && sh /usr/local/lib/b13/run/cage-down.sh >> $L 2>&1
|
||||||
|
sleep 1; for p in Xorg cage sway; do pidof $p >/dev/null && { log "FAIL: $p still running"; exit 1; }; done
|
||||||
|
fi
|
||||||
|
[ -x /usr/local/bin/aurora-ui ] || { log "FAIL: /usr/local/bin/aurora-ui missing"; exit 1; }
|
||||||
|
pidof seatd >/dev/null || { seatd -g video > $D/seatd.log 2>&1 & i=0; while [ ! -S /run/seatd.sock ] && [ $i -lt 50 ]; do sleep 0.1; i=$((i+1)); done; }
|
||||||
|
t0=$(now)
|
||||||
|
setsid cage -d -- /usr/local/bin/aurora-ui > $D/cage.log 2>&1 < /dev/null &
|
||||||
|
echo $! > $D/cage.pid
|
||||||
|
i=0; while ! grep -q "aurora-ui: first frame" $D/cage.log 2>/dev/null && [ $i -lt 300 ]; do kill -0 $(cat $D/cage.pid) 2>/dev/null || break; sleep 0.1; i=$((i+1)); done
|
||||||
|
if grep -q "aurora-ui: first frame" $D/cage.log; then
|
||||||
|
for w in $XDG_RUNTIME_DIR/wayland-*; do case $w in *.lock) ;; *) [ -S $w ] && basename $w > $D/wayland-display;; esac; done
|
||||||
|
log "UI UP cage=$(cat $D/cage.pid) aurora-ui=$(uipid) socket=$(cat $D/wayland-display) start=$(awk -v a=$t0 -v b=$(now) 'BEGIN{printf "%.2f", b-a}')s $(grep -E 'video driver|renderer|first frame' $D/cage.log | sed 's/aurora-ui: //' | tr '\n' ';')"
|
||||||
|
else log "FAIL: aurora-ui did not draw (see $D/cage.log)"; tail -15 $D/cage.log; exit 1; fi
|
||||||
8
b14/src/Makefile
Normal file
8
b14/src/Makefile
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
# B14 aurora-ui — build natively on the board (Alpine aarch64, gcc + sdl2-dev).
|
||||||
|
CFLAGS ?= -O2 -Wall -Wextra
|
||||||
|
aurora-ui: aurora-ui.c font8x16.h
|
||||||
|
$(CC) $(CFLAGS) -o $@ aurora-ui.c $$(pkg-config --cflags --libs sdl2) -lpthread
|
||||||
|
install: aurora-ui
|
||||||
|
install -m 0755 aurora-ui /usr/local/bin/aurora-ui
|
||||||
|
clean:
|
||||||
|
rm -f aurora-ui
|
||||||
379
b14/src/aurora-ui.c
Normal file
379
b14/src/aurora-ui.c
Normal file
|
|
@ -0,0 +1,379 @@
|
||||||
|
/*
|
||||||
|
* aurora-ui — B14 128x128 modem status screen (SDL2 Wayland client under Cage).
|
||||||
|
*
|
||||||
|
* Rendering: one 128x128 ARGB buffer drawn in software (8x16 cp437 bitmap font), uploaded to a streaming
|
||||||
|
* texture once per second or when data changes. Max ~2 FPS, no animations.
|
||||||
|
*
|
||||||
|
* Data (all optional; a missing source shows "--" / "ERR", never crashes):
|
||||||
|
* main thread, 1 s : /sys/class/net/wwan0/statistics/{rx,tx}_bytes (throughput; bam-dmux keeps them at 0 -> wlan0 counters),
|
||||||
|
* /proc/net/route (default),
|
||||||
|
* /sys/kernel/debug/pm8916_lbc/state (B10 supervisor: state + VADC vbat),
|
||||||
|
* /sys/class/power_supply/pm8916-lbc-chgr/online, thermal zone "pm8916-thermal", clock
|
||||||
|
* worker, 2 s : /run/aurora-modem/state, lifecycle.log (START OK / FAIL), ipcfg (IPv4)
|
||||||
|
* worker, 5 s : `timeout 3 mmcli -m any --output-keyvalue` (operator, RAT, signal, state) — only while ModemManager runs,
|
||||||
|
* `timeout 3 iw dev wlan0 info` + `station dump` (AP up, client count)
|
||||||
|
* No SOC: the board has no fuel gauge, so only VBAT is shown.
|
||||||
|
*/
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include "font8x16.h"
|
||||||
|
|
||||||
|
#define W 128
|
||||||
|
#define H 128
|
||||||
|
|
||||||
|
/* palette: 4 main colours + dim grey */
|
||||||
|
#define C_BG 0xff000000u
|
||||||
|
#define C_TEXT 0xffe8e8e8u
|
||||||
|
#define C_OK 0xff40d040u
|
||||||
|
#define C_WARN 0xffffc020u
|
||||||
|
#define C_BAD 0xffff4040u
|
||||||
|
#define C_DIM 0xff606060u
|
||||||
|
|
||||||
|
static uint32_t fb[W * H];
|
||||||
|
static volatile sig_atomic_t quit;
|
||||||
|
|
||||||
|
/* ---------- drawing ---------- */
|
||||||
|
static void fill(int x, int y, int w, int h, uint32_t c)
|
||||||
|
{
|
||||||
|
for (int j = y; j < y + h; j++)
|
||||||
|
for (int i = x; i < x + w; i++)
|
||||||
|
if (i >= 0 && i < W && j >= 0 && j < H) fb[j * W + i] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void glyph(int x, int y, unsigned char ch, uint32_t c)
|
||||||
|
{
|
||||||
|
const unsigned char *g = &font8x16[ch * 16];
|
||||||
|
for (int r = 0; r < 16; r++)
|
||||||
|
for (int b = 0; b < 8; b++)
|
||||||
|
if (g[r] & (0x80 >> b)) fill(x + b, y + r, 1, 1, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void text(int x, int y, uint32_t c, const char *s)
|
||||||
|
{
|
||||||
|
for (; *s && x < W; s++, x += 8) glyph(x, y, (unsigned char)*s, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* right-aligned to column 16 */
|
||||||
|
static void textr(int y, uint32_t c, const char *s)
|
||||||
|
{
|
||||||
|
text(W - 8 * (int)strlen(s), y, c, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bars(int x, int y, int pct, uint32_t c)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
int h = 3 + i * 3, on = pct >= 0 && pct > i * 20;
|
||||||
|
fill(x + i * 6, y + 14 - h, 4, h, on ? c : C_DIM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- small file helpers ---------- */
|
||||||
|
static int readfile(const char *p, char *buf, size_t n)
|
||||||
|
{
|
||||||
|
FILE *f = fopen(p, "r");
|
||||||
|
if (!f) return -1;
|
||||||
|
size_t k = fread(buf, 1, n - 1, f);
|
||||||
|
fclose(f);
|
||||||
|
buf[k] = 0;
|
||||||
|
return (int)k;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long long readll(const char *p)
|
||||||
|
{
|
||||||
|
char b[64];
|
||||||
|
return readfile(p, b, sizeof b) > 0 ? atoll(b) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pid_alive(const char *pidfile)
|
||||||
|
{
|
||||||
|
char b[32], p[64];
|
||||||
|
if (readfile(pidfile, b, sizeof b) <= 0) return 0;
|
||||||
|
snprintf(p, sizeof p, "/proc/%d", atoi(b));
|
||||||
|
return access(p, F_OK) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- shared state ---------- */
|
||||||
|
struct state {
|
||||||
|
/* worker */
|
||||||
|
char mstate[24]; /* controller state, e.g. BEARER_CONNECTED */
|
||||||
|
int mstart; /* 0 starting, 1 START OK, -1 FAIL */
|
||||||
|
char ip[20];
|
||||||
|
char oper[16], rat[8];
|
||||||
|
int sig; /* % or -1 */
|
||||||
|
int mm_ok; /* mmcli answered */
|
||||||
|
int ap; /* 1 AP, 0 down, -1 unknown */
|
||||||
|
int clients;
|
||||||
|
/* main */
|
||||||
|
double rxr, txr; /* B/s */
|
||||||
|
int wwan_ok, defroute;
|
||||||
|
char chg[12]; /* CHARGING/HOLD/FAULT/... */
|
||||||
|
int vbat_mv, usb, tempc;
|
||||||
|
};
|
||||||
|
static struct state st = { .sig = -1, .ap = -1, .clients = -1, .vbat_mv = -1, .tempc = -1000 };
|
||||||
|
static pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
static int dirty = 1;
|
||||||
|
|
||||||
|
static void kv(const char *line, const char *key, char *out, size_t n)
|
||||||
|
{
|
||||||
|
const char *p = strstr(line, key);
|
||||||
|
if (!p) return;
|
||||||
|
p = strchr(p, ':');
|
||||||
|
if (!p) return;
|
||||||
|
p++;
|
||||||
|
while (*p == ' ') p++;
|
||||||
|
size_t k = strcspn(p, "\n");
|
||||||
|
if (k >= n) k = n - 1;
|
||||||
|
memcpy(out, p, k);
|
||||||
|
out[k] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *worker(void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
int tick = 0;
|
||||||
|
while (!quit) {
|
||||||
|
struct state t;
|
||||||
|
pthread_mutex_lock(&mu); t = st; pthread_mutex_unlock(&mu);
|
||||||
|
|
||||||
|
char b[4096];
|
||||||
|
if (readfile("/run/aurora-modem/state", b, sizeof b) > 0) { b[strcspn(b, "\n")] = 0; snprintf(t.mstate, sizeof t.mstate, "%s", b); }
|
||||||
|
else snprintf(t.mstate, sizeof t.mstate, "--");
|
||||||
|
t.mstart = 0;
|
||||||
|
FILE *f = fopen("/run/aurora-modem/lifecycle.log", "r");
|
||||||
|
if (f) {
|
||||||
|
char l[512];
|
||||||
|
while (fgets(l, sizeof l, f)) {
|
||||||
|
if (strstr(l, "=== START OK")) t.mstart = 1;
|
||||||
|
else if (strstr(l, "FAIL in") || strstr(l, "rollback")) t.mstart = -1;
|
||||||
|
else if (strstr(l, "=== START (")) t.mstart = 0;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
t.ip[0] = 0;
|
||||||
|
if (readfile("/run/aurora-modem/ipcfg", b, sizeof b) > 0) {
|
||||||
|
char *a = strstr(b, "\nA=");
|
||||||
|
if (a) { a += 3; size_t k = strcspn(a, "\n"); if (k < sizeof t.ip) { memcpy(t.ip, a, k); t.ip[k] = 0; } }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tick % 5 == 0) {
|
||||||
|
/* LTE details from ModemManager, only if it runs (avoid spawning mmcli into a stopped stack) */
|
||||||
|
t.mm_ok = 0;
|
||||||
|
if (pid_alive("/run/aurora-modem/mm.pid") && (f = popen("timeout 3 mmcli -m any --output-keyvalue 2>/dev/null", "r"))) {
|
||||||
|
char l[512], v[64];
|
||||||
|
t.sig = -1; t.oper[0] = 0; t.rat[0] = 0;
|
||||||
|
while (fgets(l, sizeof l, f)) {
|
||||||
|
v[0] = 0;
|
||||||
|
if (strstr(l, "modem.3gpp.operator-name ")) { kv(l, "operator-name", v, sizeof v); snprintf(t.oper, sizeof t.oper, "%s", strcmp(v, "--") ? v : ""); t.mm_ok = 1; }
|
||||||
|
else if (strstr(l, "access-technologies.value[1]")) { kv(l, "]", v, sizeof v); snprintf(t.rat, sizeof t.rat, "%s", v); }
|
||||||
|
else if (strstr(l, "signal-quality.value")) { kv(l, "value", v, sizeof v); t.sig = atoi(v); }
|
||||||
|
}
|
||||||
|
pclose(f);
|
||||||
|
for (char *p = t.oper; *p; p++) if (*p >= 'a' && *p <= 'z') *p -= 32;
|
||||||
|
for (char *p = t.rat; *p; p++) if (*p >= 'a' && *p <= 'z') *p -= 32;
|
||||||
|
}
|
||||||
|
/* Wi-Fi AP + stations (one short iw call pair, every 5 s) */
|
||||||
|
t.ap = -1; t.clients = -1;
|
||||||
|
if ((f = popen("timeout 3 iw dev wlan0 info 2>/dev/null; echo ---; timeout 3 iw dev wlan0 station dump 2>/dev/null", "r"))) {
|
||||||
|
char l[256]; int sect = 0, n = 0, ap = 0, any = 0;
|
||||||
|
while (fgets(l, sizeof l, f)) {
|
||||||
|
if (!strncmp(l, "---", 3)) { sect = 1; continue; }
|
||||||
|
if (!sect) { any = 1; if (strstr(l, "type AP")) ap = 1; }
|
||||||
|
else if (!strncmp(l, "Station ", 8)) n++;
|
||||||
|
}
|
||||||
|
pclose(f);
|
||||||
|
if (any) { t.ap = ap; t.clients = ap ? n : 0; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&mu);
|
||||||
|
if (memcmp(&t, &st, sizeof t)) {
|
||||||
|
/* keep the main-thread fields current */
|
||||||
|
t.rxr = st.rxr; t.txr = st.txr; t.wwan_ok = st.wwan_ok; t.defroute = st.defroute;
|
||||||
|
memcpy(t.chg, st.chg, sizeof t.chg); t.vbat_mv = st.vbat_mv; t.usb = st.usb; t.tempc = st.tempc;
|
||||||
|
st = t; dirty = 1;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mu);
|
||||||
|
for (int i = 0; i < 20 && !quit; i++) usleep(100000);
|
||||||
|
tick += 2;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- fast metrics (main thread, 1 s) ---------- */
|
||||||
|
static long long prx = -1, ptx = -1;
|
||||||
|
static double pt;
|
||||||
|
|
||||||
|
static void fast(void)
|
||||||
|
{
|
||||||
|
char b[512];
|
||||||
|
struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
double now = ts.tv_sec + ts.tv_nsec / 1e9;
|
||||||
|
long long rx = readll("/sys/class/net/wwan0/statistics/rx_bytes"), tx = readll("/sys/class/net/wwan0/statistics/tx_bytes");
|
||||||
|
/* the bam-dmux wwan0 driver keeps its netdev counters at 0 -> fall back to the Wi-Fi LAN side (traffic to/from clients):
|
||||||
|
download = wlan0 tx, upload = wlan0 rx */
|
||||||
|
if (rx == 0 && tx == 0) {
|
||||||
|
long long lrx = readll("/sys/class/net/wlan0/statistics/rx_bytes"), ltx = readll("/sys/class/net/wlan0/statistics/tx_bytes");
|
||||||
|
if (lrx >= 0 && ltx >= 0) { rx = ltx; tx = lrx; }
|
||||||
|
}
|
||||||
|
struct state t; pthread_mutex_lock(&mu); t = st; pthread_mutex_unlock(&mu);
|
||||||
|
t.wwan_ok = rx >= 0;
|
||||||
|
if (rx >= 0 && prx >= 0 && now > pt) { t.rxr = (rx - prx) / (now - pt); t.txr = (tx - ptx) / (now - pt); }
|
||||||
|
else { t.rxr = t.txr = -1; }
|
||||||
|
prx = rx; ptx = tx; pt = now;
|
||||||
|
|
||||||
|
t.defroute = 0;
|
||||||
|
FILE *f = fopen("/proc/net/route", "r");
|
||||||
|
if (f) { char l[256], ifn[32]; unsigned d; while (fgets(l, sizeof l, f)) if (sscanf(l, "%31s %x", ifn, &d) == 2 && d == 0) t.defroute = 1; fclose(f); }
|
||||||
|
|
||||||
|
t.chg[0] = 0; t.vbat_mv = -1;
|
||||||
|
if (readfile("/sys/kernel/debug/pm8916_lbc/state", b, sizeof b) > 0) {
|
||||||
|
char s[16]; long uv;
|
||||||
|
char *p = strstr(b, "state ");
|
||||||
|
if (p && sscanf(p, "state %15s", s) == 1) snprintf(t.chg, sizeof t.chg, "%s", s);
|
||||||
|
if ((p = strstr(b, "vbat_uv ")) && sscanf(p, "vbat_uv %ld", &uv) == 1) t.vbat_mv = (int)(uv / 1000);
|
||||||
|
}
|
||||||
|
t.usb = (int)readll("/sys/class/power_supply/pm8916-lbc-chgr/online");
|
||||||
|
|
||||||
|
t.tempc = -1000;
|
||||||
|
DIR *d = opendir("/sys/class/thermal");
|
||||||
|
if (d) {
|
||||||
|
struct dirent *e; char p[300];
|
||||||
|
while ((e = readdir(d))) {
|
||||||
|
if (strncmp(e->d_name, "thermal_zone", 12)) continue;
|
||||||
|
snprintf(p, sizeof p, "/sys/class/thermal/%s/type", e->d_name);
|
||||||
|
if (readfile(p, b, sizeof b) > 0 && !strncmp(b, "pm8916-thermal", 14)) {
|
||||||
|
snprintf(p, sizeof p, "/sys/class/thermal/%s/temp", e->d_name);
|
||||||
|
long long v = readll(p); if (v > -100000) t.tempc = (int)(v / 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(d);
|
||||||
|
}
|
||||||
|
pthread_mutex_lock(&mu);
|
||||||
|
st.rxr = t.rxr; st.txr = t.txr; st.wwan_ok = t.wwan_ok; st.defroute = t.defroute;
|
||||||
|
memcpy(st.chg, t.chg, sizeof st.chg); st.vbat_mv = t.vbat_mv; st.usb = t.usb; st.tempc = t.tempc;
|
||||||
|
pthread_mutex_unlock(&mu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rate(char *o, size_t n, double r)
|
||||||
|
{
|
||||||
|
if (r < 0) snprintf(o, n, "--");
|
||||||
|
else if (r < 1000) snprintf(o, n, "%dB", (int)r);
|
||||||
|
else if (r < 1e6) snprintf(o, n, "%.*fK", r < 1e4 ? 1 : 0, r / 1e3);
|
||||||
|
else snprintf(o, n, "%.1fM", r / 1e6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- screen ---------- */
|
||||||
|
static void render(void)
|
||||||
|
{
|
||||||
|
struct state t; pthread_mutex_lock(&mu); t = st; pthread_mutex_unlock(&mu);
|
||||||
|
char s[40], a[16], b[16];
|
||||||
|
fill(0, 0, W, H, C_BG);
|
||||||
|
|
||||||
|
/* row 0-1: LTE */
|
||||||
|
int online = t.mstart == 1 && !strcmp(t.mstate, "BEARER_CONNECTED");
|
||||||
|
if (t.mstart == 0 && strcmp(t.mstate, "BEARER_CONNECTED")) {
|
||||||
|
text(0, 0, C_WARN, "MODEM STARTING");
|
||||||
|
snprintf(s, sizeof s, "%.16s", t.mstate); text(0, 16, C_DIM, s);
|
||||||
|
} else if (t.mstart < 0) {
|
||||||
|
text(0, 0, C_BAD, "MODEM FAIL");
|
||||||
|
snprintf(s, sizeof s, "%.16s", t.mstate); text(0, 16, C_DIM, s);
|
||||||
|
} else {
|
||||||
|
snprintf(s, sizeof s, "%.11s", t.oper[0] ? t.oper : "LTE --"); text(0, 0, t.mm_ok ? C_TEXT : C_DIM, s);
|
||||||
|
textr(0, online ? C_OK : C_WARN, t.rat[0] ? t.rat : "--");
|
||||||
|
bars(0, 16, t.mm_ok ? t.sig : -1, online ? C_OK : C_WARN);
|
||||||
|
if (t.mm_ok && t.sig >= 0) { snprintf(s, sizeof s, "%d%%", t.sig); text(36, 16, C_TEXT, s); }
|
||||||
|
else text(36, 16, C_DIM, "--");
|
||||||
|
}
|
||||||
|
/* row 2: IPv4 */
|
||||||
|
text(0, 32, t.ip[0] ? C_TEXT : C_DIM, t.ip[0] ? t.ip : "IP --");
|
||||||
|
|
||||||
|
/* row 3: Wi-Fi */
|
||||||
|
if (t.ap < 0) text(0, 48, C_DIM, "WiFi --");
|
||||||
|
else if (!t.ap) text(0, 48, C_BAD, "WiFi DOWN");
|
||||||
|
else { snprintf(s, sizeof s, "WiFi %d cl", t.clients); text(0, 48, C_OK, s); }
|
||||||
|
|
||||||
|
/* row 4: throughput (cp437 0x19 down, 0x18 up) */
|
||||||
|
rate(a, sizeof a, t.rxr); rate(b, sizeof b, t.txr);
|
||||||
|
snprintf(s, sizeof s, "\x19%-6s \x18%s", a, b); text(0, 64, t.wwan_ok ? C_TEXT : C_DIM, s);
|
||||||
|
|
||||||
|
/* row 5: battery (VADC VBAT from the B10 supervisor; no SOC) */
|
||||||
|
if (t.vbat_mv > 0) snprintf(s, sizeof s, "BAT %d.%02dV", t.vbat_mv / 1000, (t.vbat_mv % 1000) / 10);
|
||||||
|
else snprintf(s, sizeof s, "BAT --");
|
||||||
|
text(0, 80, t.vbat_mv > 0 ? C_TEXT : C_DIM, s);
|
||||||
|
const char *cs = t.chg[0] ? t.chg : (t.usb == 1 ? "USB" : "--");
|
||||||
|
uint32_t cc = !strcmp(cs, "FAULT") ? C_BAD : (!strcmp(cs, "CHARGING") ? C_WARN : C_OK);
|
||||||
|
if (!strcmp(cs, "CHARGING")) cs = "CHG";
|
||||||
|
snprintf(s, sizeof s, "%.5s", cs); textr(80, cc, s);
|
||||||
|
|
||||||
|
/* row 6: PMIC temperature + router (default route) */
|
||||||
|
if (t.tempc > -1000) { snprintf(s, sizeof s, "PMIC %d\xf8""C", t.tempc); text(0, 96, t.tempc >= 60 ? C_BAD : C_TEXT, s); }
|
||||||
|
else text(0, 96, C_DIM, "PMIC --");
|
||||||
|
textr(96, t.defroute ? C_OK : C_DIM, t.defroute ? "NAT" : "---");
|
||||||
|
|
||||||
|
/* row 7: clock + overall */
|
||||||
|
time_t now = time(NULL); struct tm tm; localtime_r(&now, &tm);
|
||||||
|
if (tm.tm_year + 1900 >= 2026) { snprintf(s, sizeof s, "%02d%c%02d", tm.tm_hour, (now & 1) ? ':' : ' ', tm.tm_min); text(0, 112, C_TEXT, s); }
|
||||||
|
else text(0, 112, C_DIM, "--:--");
|
||||||
|
textr(112, online ? C_OK : (t.mstart < 0 ? C_BAD : C_WARN), online ? "ONLINE" : (t.mstart < 0 ? "FAIL" : "WAIT"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_sig(int s) { (void)s; quit = 1; }
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(stderr, NULL, _IONBF, 0);
|
||||||
|
struct timespec t0; clock_gettime(CLOCK_MONOTONIC, &t0);
|
||||||
|
signal(SIGTERM, on_sig); signal(SIGINT, on_sig); signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO)) { fprintf(stderr, "aurora-ui: SDL_Init: %s\n", SDL_GetError()); return 1; }
|
||||||
|
const char *drv = SDL_GetCurrentVideoDriver();
|
||||||
|
printf("aurora-ui: SDL %d.%d.%d video driver %s\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL, drv ? drv : "?");
|
||||||
|
if (!drv || strcmp(drv, "wayland")) { fprintf(stderr, "aurora-ui: refusing to run on video driver '%s' (Wayland required)\n", drv ? drv : "?"); SDL_Quit(); return 2; }
|
||||||
|
|
||||||
|
SDL_Window *win = SDL_CreateWindow("aurora-ui", 0, 0, W, H, SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_BORDERLESS);
|
||||||
|
if (!win) { fprintf(stderr, "aurora-ui: window: %s\n", SDL_GetError()); SDL_Quit(); return 1; }
|
||||||
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
|
SDL_Renderer *r = SDL_CreateRenderer(win, -1, 0);
|
||||||
|
if (!r) { fprintf(stderr, "aurora-ui: renderer: %s\n", SDL_GetError()); SDL_Quit(); return 1; }
|
||||||
|
SDL_RendererInfo ri; SDL_GetRendererInfo(r, &ri);
|
||||||
|
SDL_Texture *tex = SDL_CreateTexture(r, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, W, H);
|
||||||
|
int ww, wh; SDL_GetWindowSize(win, &ww, &wh);
|
||||||
|
printf("aurora-ui: renderer %s, window %dx%d\n", ri.name, ww, wh);
|
||||||
|
|
||||||
|
pthread_t th; pthread_create(&th, NULL, worker, NULL);
|
||||||
|
Uint32 last = 0; int first = 1;
|
||||||
|
while (!quit) {
|
||||||
|
SDL_Event e;
|
||||||
|
if (SDL_WaitEventTimeout(&e, 250)) {
|
||||||
|
if (e.type == SDL_QUIT) quit = 1;
|
||||||
|
if (e.type == SDL_WINDOWEVENT) dirty = 1;
|
||||||
|
}
|
||||||
|
Uint32 now = SDL_GetTicks();
|
||||||
|
if (now - last >= 1000) { last = now; fast(); dirty = 1; }
|
||||||
|
if (dirty) {
|
||||||
|
dirty = 0;
|
||||||
|
render();
|
||||||
|
SDL_UpdateTexture(tex, NULL, fb, W * 4);
|
||||||
|
SDL_RenderClear(r);
|
||||||
|
SDL_RenderCopy(r, tex, NULL, NULL);
|
||||||
|
SDL_RenderPresent(r);
|
||||||
|
if (first) {
|
||||||
|
struct timespec t1; clock_gettime(CLOCK_MONOTONIC, &t1);
|
||||||
|
printf("aurora-ui: first frame after %.3f s\n", (t1.tv_sec - t0.tv_sec) + (t1.tv_nsec - t0.tv_nsec) / 1e9);
|
||||||
|
first = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pthread_join(th, NULL);
|
||||||
|
SDL_DestroyTexture(tex); SDL_DestroyRenderer(r); SDL_DestroyWindow(win); SDL_Quit();
|
||||||
|
printf("aurora-ui: exit\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
259
b14/src/font8x16.h
Normal file
259
b14/src/font8x16.h
Normal file
|
|
@ -0,0 +1,259 @@
|
||||||
|
/* 8x16 cp437 bitmap font extracted from Linux lib/fonts/font_8x16.c (GPL-2.0), 256 glyphs x 16 rows, MSB = left pixel. */
|
||||||
|
static const unsigned char font8x16[4096] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
|
||||||
|
0x00, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x1c, 0x36, 0x32, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
|
||||||
|
0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
|
||||||
|
0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x18, 0x70, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x70, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x38, 0x6c, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x0c, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x36, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
|
||||||
|
0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x60, 0xe0, 0x62, 0x66, 0x6c, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00,
|
||||||
|
0x00, 0x60, 0xe0, 0x62, 0x66, 0x6c, 0x18, 0x30, 0x66, 0xce, 0x9a, 0x3f, 0x06, 0x06, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
|
||||||
|
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
|
||||||
|
0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
|
||||||
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||||
|
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x6c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x3c, 0x66, 0x0c, 0x18, 0x32, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
};
|
||||||
19
b14/src/sdlprobe.c
Normal file
19
b14/src/sdlprobe.c
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* B14: SDL2 probe — which video drivers are compiled in, which one initialises, which renderer we get. */
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
int main(void) {
|
||||||
|
setvbuf(stdout, NULL, _IONBF, 0);
|
||||||
|
SDL_version v; SDL_GetVersion(&v); printf("SDL %d.%d.%d\n", v.major, v.minor, v.patch);
|
||||||
|
printf("compiled video drivers:"); for (int i = 0; i < SDL_GetNumVideoDrivers(); i++) printf(" %s", SDL_GetVideoDriver(i)); printf("\n");
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO)) { printf("SDL_Init failed: %s\n", SDL_GetError()); return 1; }
|
||||||
|
printf("current video driver: %s\n", SDL_GetCurrentVideoDriver());
|
||||||
|
SDL_DisplayMode m; if (!SDL_GetCurrentDisplayMode(0, &m)) printf("display 0: %dx%d@%d\n", m.w, m.h, m.refresh_rate);
|
||||||
|
SDL_Window *w = SDL_CreateWindow("probe", 0, 0, 128, 128, SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_BORDERLESS);
|
||||||
|
if (!w) { printf("window: %s\n", SDL_GetError()); return 1; }
|
||||||
|
printf("render drivers:"); for (int i = 0; i < SDL_GetNumRenderDrivers(); i++) { SDL_RendererInfo ri; SDL_GetRenderDriverInfo(i, &ri); printf(" %s", ri.name); } printf("\n");
|
||||||
|
SDL_Renderer *r = SDL_CreateRenderer(w, -1, 0);
|
||||||
|
if (!r) { printf("renderer: %s\n", SDL_GetError()); } else { SDL_RendererInfo ri; SDL_GetRendererInfo(r, &ri); printf("renderer: %s flags=0x%x\n", ri.name, ri.flags); }
|
||||||
|
int ww, wh; SDL_GetWindowSize(w, &ww, &wh); printf("window %dx%d\n", ww, wh);
|
||||||
|
if (r) { SDL_SetRenderDrawColor(r, 0, 0, 255, 255); SDL_RenderClear(r); SDL_RenderPresent(r); SDL_Delay(1500); }
|
||||||
|
SDL_Quit(); return 0;
|
||||||
|
}
|
||||||
12
b15/B15-rollback.sh
Normal file
12
b15/B15-rollback.sh
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# B15 rollback - restore the B12R cache (e85d862e: Alpine primary root + router, kernel b12 without WireGuard). Needs 9008 via HW EDL.
|
||||||
|
# boot/aboot/userdata untouched (aurora-vpn just logs "kernel has no WireGuard" under b12). Deeper: b12/b12r/B12R-rollback.sh (B12Q).
|
||||||
|
cd ~/doc/modem/jz08-aurora || exit 1
|
||||||
|
L=firehose/007050e100000000_394a2e47cf830150_fhprg_peek.bin ; O=logs/b15/rollback ; mkdir -p $O
|
||||||
|
B=b12/b12r/cache/cache-extlinux-b12r.img
|
||||||
|
[ "$(sha256sum $B | cut -d' ' -f1)" = e85d862e463aa4affd7ec1cea9b1f2c7f765bb08e2a6bdce4af9539278f80d33 ] || { echo "STOP: rollback image hash"; exit 1; }
|
||||||
|
lsusb | grep -q 05c6:9008 || { echo "STOP: no 9008"; exit 1; }
|
||||||
|
edl --loader=$L printgpt > $O/00-printgpt.log 2>&1
|
||||||
|
edl --loader=$L w cache $B > $O/cache-w.log 2>&1
|
||||||
|
edl --loader=$L r cache $O/cache-rb.bin > /dev/null 2>&1 ; cmp $B $O/cache-rb.bin && echo CACHE_RESTORED_B12R
|
||||||
|
sha256sum $B $O/cache-rb.bin
|
||||||
52
b15/B15-write.sh
Normal file
52
b15/B15-write.sh
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# B15 — the ONLY write: cache := B15 candidate (= B12Q initramfs + kernel 7.2.7-aurora-b15: b12 + WireGuard + IP_MULTIPLE_TABLES policy routing).
|
||||||
|
# Run on 480s ONLY after explicit GO (operator chose to flash without a RAM test). Derived 1:1 from b12/b12r/B12R-write.sh; changed: image/hashes,
|
||||||
|
# rollback refs, log dir. The pre-write readback of the live cache (must be B12R e85d862e) is kept as backup.
|
||||||
|
# Entry: HW EDL (battery on, D+->GND, plug USB, release). Never `edl reset`. Stops at first failed gate.
|
||||||
|
cd ~/doc/modem/jz08-aurora || exit 1
|
||||||
|
L=firehose/007050e100000000_394a2e47cf830150_fhprg_peek.bin
|
||||||
|
O=logs/b15/W ; A3=logs/b5a/A3 ; P=logs/b5a/A4pre ; mkdir -p $O
|
||||||
|
NEW=b15/cache/cache-extlinux-b15.img ; NEW_SHA=212e0ca903911dad19fca00c013610cb6d5a773821c36410d8c277e34139856f
|
||||||
|
OLD_SHA=e85d862e463aa4affd7ec1cea9b1f2c7f765bb08e2a6bdce4af9539278f80d33 # current cache = B12R extlinux
|
||||||
|
BOOT_SHA=e9579f33c7304cd47f487f2b61cd9226dc04fd3a63775d62b4b95fc15bd3ebff
|
||||||
|
ABOOT_SHA=15208dbb4feafccd72d2b06db5714cd746c216701f0ef8822c58bb47105d37c4 # aboot = lk1st-b9l (B9L-PERSIST)
|
||||||
|
die(){ echo "STOP: $*"; exit 1; }
|
||||||
|
sha(){ sha256sum "$1" | cut -d" " -f1; }
|
||||||
|
E(){ edl --loader=$L "$@"; }
|
||||||
|
echo "== G0 inputs"
|
||||||
|
[ "$(sha $L)" = 53f193500c03248f0d671ab57bfe9ca8a42967e97f28403294b4b3f854075aca ] || die loader
|
||||||
|
[ "$(sha $NEW)" = $NEW_SHA ] && [ $(stat -c %s $NEW) = 134217728 ] || die candidate
|
||||||
|
[ "$(sha b12/b12r/cache/cache-extlinux-b12r.img)" = $OLD_SHA ] || die rollback-image
|
||||||
|
[ "$(sha logs/b12/b12r/W/11-cache-readback.bin)" = $OLD_SHA ] || die b12r-readback-backup
|
||||||
|
lsusb | grep -q 05c6:9008 || die "no 9008"
|
||||||
|
echo "== G1 identity + geometry + baseline"
|
||||||
|
E printgpt > $O/00-printgpt.log 2>&1 || die printgpt
|
||||||
|
grep -aq "Serial: *0x<SAHARA_SERIAL>" $O/00-printgpt.log || grep -aq "Mode detected: firehose" $O/00-printgpt.log || die serial
|
||||||
|
grep -a "^cache:" $O/00-printgpt.log | grep -q "Offset 0x000000004118c000, Length 0x0000000008000000" || die cache-geometry
|
||||||
|
E rs 0 34 $O/pre-gptp.bin >/dev/null 2>&1; cmp $O/pre-gptp.bin $A3/gpt-primary-34.bin || die gpt-changed
|
||||||
|
E r boot $O/pre-boot.bin >/dev/null 2>&1; [ "$(sha $O/pre-boot.bin)" = $BOOT_SHA ] || die boot-not-emmc1
|
||||||
|
E r aboot $O/pre-aboot.bin >/dev/null 2>&1; [ "$(sha $O/pre-aboot.bin)" = $ABOOT_SHA ] || die aboot-not-b9l
|
||||||
|
E r cache $O/pre-cache.bin >/dev/null 2>&1; [ "$(sha $O/pre-cache.bin)" = $OLD_SHA ] || die cache-not-backup
|
||||||
|
echo "== W cache := candidate (LBA 2133088, 262144 sectors)"
|
||||||
|
E w cache $NEW > $O/10-cache-write.log 2>&1; echo "rc=$?"; grep -a "Wrote" $O/10-cache-write.log
|
||||||
|
E r cache $O/11-cache-readback.bin > $O/11-cache-readback.log 2>&1 || die readback-rc
|
||||||
|
sha256sum $NEW $O/11-cache-readback.bin
|
||||||
|
cmp $NEW $O/11-cache-readback.bin || die "CACHE READBACK MISMATCH — do NOT reboot; run b15/B15-rollback.sh"
|
||||||
|
echo CACHE_MATCH
|
||||||
|
echo "== V everything else unchanged"
|
||||||
|
E rs 0 34 $O/post-gptp.bin >/dev/null 2>&1; cmp $O/post-gptp.bin $A3/gpt-primary-34.bin || die gptp
|
||||||
|
E rs 7634911 33 $O/post-gptb.bin >/dev/null 2>&1; cmp $O/post-gptb.bin $A3/gpt-backup-33.bin || die gptb
|
||||||
|
E rs 305184 1024 $O/post-tzbak.bin >/dev/null 2>&1; cmp $O/post-tzbak.bin $A3/tzbak-305184.bin || die tzbak
|
||||||
|
E r boot $O/post-boot.bin >/dev/null 2>&1; [ "$(sha $O/post-boot.bin)" = $BOOT_SHA ] || die boot
|
||||||
|
E r aboot $O/post-aboot.bin >/dev/null 2>&1; [ "$(sha $O/post-aboot.bin)" = $ABOOT_SHA ] || die aboot
|
||||||
|
for p in sbl1 rpm tz hyp recovery modemst1 modemst2 fsg fsc persist; do
|
||||||
|
E r $p $O/post-$p.bin >/dev/null 2>&1; cmp $O/post-$p.bin $A3/$p.bin || die "$p changed"; echo "$p == A3"
|
||||||
|
done
|
||||||
|
for p in modem system; do
|
||||||
|
E r $p $O/post-$p.bin >/dev/null 2>&1; cmp $O/post-$p.bin $P/$p.bin || die "$p changed"; echo "$p == A4pre"; rm -f $O/post-$p.bin
|
||||||
|
done
|
||||||
|
E rs 2428000 8 $O/post-userdata-sb.bin >/dev/null 2>&1
|
||||||
|
[ "$(dd if=$O/post-userdata-sb.bin bs=1 skip=1080 count=2 2>/dev/null | od -An -tx1 | tr -d ' \n')" = 53ef ] && [ "$(dd if=$O/post-userdata-sb.bin bs=1 skip=1144 count=16 2>/dev/null | tr -d '\000')" = aurora-alpine ] || die "userdata superblock is not ext4 aurora-alpine"
|
||||||
|
echo "userdata = ext4 aurora-alpine (superblock)"
|
||||||
|
(cd $O && sha256sum *.bin > SHA256SUMS)
|
||||||
|
echo "B15_CACHE_WRITE_VERIFIED — power off fully (USB, then battery) before first boot"
|
||||||
15
b15/b15-boot.sh
Normal file
15
b15/b15-boot.sh
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# 480s: B15 RAM test. Waits for lk1st fastboot (RESET held at power-on), `fastboot boot` the b15 image (WireGuard kernel), then waits
|
||||||
|
# for NCM + router. Nothing flashed. After it prints READY, bring the tunnel up by hand: aurora-vpn up.
|
||||||
|
cd ~/doc/modem/jz08-aurora; O=logs/b15/ram${1:-1}; mkdir -p $O; IMG=b15/out/aurora-b15.img
|
||||||
|
A=$O/host-actions.txt; act() { echo "$(date -u +%H:%M:%S) $*" | tee -a $A; }
|
||||||
|
tn() { { sleep 1; sed "s/\$/\r/" "$1"; sleep $2; } | ncat 172.16.42.1 23 | tr -d "\000\r"; }
|
||||||
|
grep " aurora-b15.img\$" b15/out/SHA256SUMS | sed "s| | b15/out/|" | sha256sum -c || exit 1
|
||||||
|
act "B15 ram: waiting for fastboot <EMMC_SERIAL> (RESET held at power-on)"
|
||||||
|
i=0; until fastboot devices 2>/dev/null | grep -q <EMMC_SERIAL>; do i=$((i+1)); [ $i -ge 900 ] && { act ABORT; exit 1; }; sleep 2; done
|
||||||
|
act "fastboot present"; { fastboot boot $IMG 2>&1; echo rc=$?; } | tee -a $A
|
||||||
|
i=0; until ping -c1 -W1 172.16.42.1 >/dev/null 2>&1; do i=$((i+1)); [ $i -ge 240 ] && { act "ABORT NCM"; exit 1; }; sleep 1; done; act "NCM up"
|
||||||
|
printf 'uname -r; grep -c WIREGUARD=y /proc/config.gz 2>/dev/null; ls -d /sys/module/wireguard 2>/dev/null; grep -E "ROUTER UP OK" /run/aurora-router/router.log | tail -1 | cut -c1-70\n' > $O/.w
|
||||||
|
i=0; until tn $O/.w 3 | grep -q "ROUTER UP OK"; do i=$((i+1)); [ $i -ge 60 ] && break; sleep 6; done
|
||||||
|
tn $O/.w 3 | grep -aE "aurora|ROUTER|/sys/module" | tee -a $A
|
||||||
|
act "READY — run: ssh q@480s \"cd doc/modem/jz08-aurora/b12; ./tn.sh 12 'aurora-vpn up'\""
|
||||||
11
b15/build-b15.sh
Normal file
11
b15/build-b15.sh
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# B15 RAM image: kernel 7.2.7-aurora-b15 (= b12 + WireGuard + IP_MULTIPLE_TABLES policy routing, tree src-b10b5) + prod DTB e47762d1
|
||||||
|
# + B9C cmdline + B12Q initramfs (stage0 -> Alpine on p27) unchanged. fastboot boot only; nothing flashed.
|
||||||
|
set -e; cd "$(dirname "$0")"; O=out; KB=/home/q/aurora-kbuild/out-b15; Q=../b12/b12q/out; mkdir -p $O
|
||||||
|
echo "9ade7cffb1f3f19e86acc8869565a88b960abba543385a2fddcebd27bd529e79 $Q/initramfs-b12q.cpio.gz" | sha256sum -c
|
||||||
|
echo "e47762d1dcd0af6e2acb711fa47ecc13769cd6bcb81259ce50635e8b18b6514a $Q/aurora-b10b3.dtb" | sha256sum -c
|
||||||
|
for s in WIREGUARD=y IP_MULTIPLE_TABLES=y NF_TABLES=y CHARGER_PM8916_LBC=y 'LOCALVERSION="-aurora-b15"'; do grep -q "^CONFIG_$s\$" $KB/.config || { echo "STOP $s"; exit 1; }; done
|
||||||
|
cp $KB/arch/arm64/boot/Image.gz $O/Image-b15.gz; cp $KB/.config $O/config-b15; cp $Q/aurora-b10b3.dtb $Q/initramfs-b12q.cpio.gz $Q/cmdline.txt $O/
|
||||||
|
cat $O/Image-b15.gz $O/aurora-b10b3.dtb > $O/Image.gz-dtb
|
||||||
|
python3 ../b6p/mkbootimg.py $O/Image.gz-dtb $O/initramfs-b12q.cpio.gz $O/cmdline.txt $O/aurora-b15.img
|
||||||
|
(cd $O && sha256sum Image-b15.gz config-b15 aurora-b10b3.dtb Image.gz-dtb initramfs-b12q.cpio.gz cmdline.txt aurora-b15.img > SHA256SUMS; grep -E "aurora-b15.img|Image-b15" SHA256SUMS)
|
||||||
6
b15/cache/extlinux-b15.conf
vendored
Normal file
6
b15/cache/extlinux-b15.conf
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
default b15
|
||||||
|
label b15
|
||||||
|
linux /Image.gz-dtb
|
||||||
|
fdt /aurora-b10b3.dtb
|
||||||
|
initrd /initramfs-b12q.cpio.gz
|
||||||
|
append earlycon console=tty0 console=ttyMSM0,115200n8 ignore_loglevel loglevel=8 rdinit=/init fbcon=font:6x8 consoleblank=0
|
||||||
27
b15/cache/mkfs-cache-b15.sh
vendored
Normal file
27
b15/cache/mkfs-cache-b15.sh
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# B15 cache CANDIDATE (= B12Q initramfs + kernel 7.2.7-aurora-b15: b12 + WireGuard + policy routing) (NOT for writing without a separate GO): exact recipe of b10/b10b3/cache-v4/mkfs-cache-b10b5.sh (c3732515);
|
||||||
|
# differs only in the initrd (B9C initramfs + B12P overlay: aurora-alpine autostart, modem safety gate, e2fsck bundle), file names,
|
||||||
|
# extlinux label, fs label and UUIDs. Kernel/DTB/append = B10 production unchanged. Runs on 480s (mke2fs 1.47.2). Offline only.
|
||||||
|
# The image contains the AP PSK (in the initramfs) - never publish it.
|
||||||
|
set -e
|
||||||
|
cd ~/doc/modem/jz08-aurora/b15/cache
|
||||||
|
OUT=${1:-cache-extlinux-b15.img}; F=../out
|
||||||
|
echo "0fef41b262917c8ae308fa222da0017e2b3cb3ec5da1ca8ba18d0318476761a3 $F/cmdline.txt" | sha256sum -c
|
||||||
|
echo "8ba2c2274d89ec7622c6dc3831f312c086aabce1784f497edc39fe4eec87c857 $F/Image.gz-dtb" | sha256sum -c
|
||||||
|
echo "e47762d1dcd0af6e2acb711fa47ecc13769cd6bcb81259ce50635e8b18b6514a $F/aurora-b10b3.dtb" | sha256sum -c
|
||||||
|
echo "9ade7cffb1f3f19e86acc8869565a88b960abba543385a2fddcebd27bd529e79 $F/initramfs-b12q.cpio.gz" | sha256sum -c
|
||||||
|
ST=$(mktemp -d); mkdir -p $ST/extlinux
|
||||||
|
cp $F/Image.gz-dtb $F/aurora-b10b3.dtb $F/initramfs-b12q.cpio.gz $ST/
|
||||||
|
printf "default b15\nlabel b15\n\tlinux /Image.gz-dtb\n\tfdt /aurora-b10b3.dtb\n\tinitrd /initramfs-b12q.cpio.gz\n\tappend %s\n" "$(cat $F/cmdline.txt)" > $ST/extlinux/extlinux.conf
|
||||||
|
cp $ST/extlinux/extlinux.conf extlinux-b15.conf
|
||||||
|
chmod 0644 $ST/*.* $ST/extlinux/extlinux.conf; chmod 0755 $ST $ST/extlinux
|
||||||
|
find $ST -exec touch -h -d @1790726400 {} +
|
||||||
|
rm -f $OUT; truncate -s 134217728 $OUT
|
||||||
|
E2FSPROGS_FAKE_TIME=1790726400 /sbin/mke2fs -F -q -t ext2 -O none,filetype,sparse_super \
|
||||||
|
-b 4096 -I 128 -N 64 -m 0 -L aurora-b15 -U 4a5a3038-b6f0-4000-8000-00000b151500 \
|
||||||
|
-E root_owner=0:0,hash_seed=4a5a3038-b6f0-4000-8000-00000b151501 -d $ST $OUT 32768
|
||||||
|
rm -rf $ST
|
||||||
|
for f in / /lost+found /extlinux /extlinux/extlinux.conf /Image.gz-dtb /aurora-b10b3.dtb /initramfs-b12q.cpio.gz; do for t in atime ctime mtime; do echo "sif $f $t @1790726400"; done; done > /tmp/b15-sif.$$
|
||||||
|
/sbin/debugfs -w -f /tmp/b15-sif.$$ $OUT >/dev/null 2>&1; rm -f /tmp/b15-sif.$$
|
||||||
|
/sbin/e2fsck -fn $OUT >/dev/null 2>&1 && echo "e2fsck -fn clean"
|
||||||
|
stat -c "%n %s" $OUT; sha256sum $OUT
|
||||||
95
b15/run/aurora-router
Normal file
95
b15/run/aurora-router
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Aurora router (B12R, runtime state only in /run): aurora-router up | down | status
|
||||||
|
# up: wlan0 192.168.77.1/24, default route via wwan0 (only if none), nftables table inet aurora_router (NAT LAN->wwan0, default-deny forward,
|
||||||
|
# no LTE->LAN, Wi-Fi blocked from the USB mgmt subnet and from every board address except 192.168.77.1 DHCP/DNS/ping), ip_forward=1,
|
||||||
|
# dnsmasq bound to wlan0 only (upstream = bearer DNS).
|
||||||
|
# down: undo exactly that. Needs kernel nf_tables (7.2.7-aurora-b12).
|
||||||
|
. /etc/aurora/router.conf
|
||||||
|
S=/run/aurora-router; LOG=$S/router.log; mkdir -p $S
|
||||||
|
now() { cut -d' ' -f1 /proc/uptime; }
|
||||||
|
log() { m="[$(now)] $*"; echo "$m"; echo "$m" >> $LOG; echo "<5>[aurora-router] $*" > /dev/kmsg 2>/dev/null; }
|
||||||
|
fail() { log "FAIL: $*"; exit 1; }
|
||||||
|
dpid() { [ -f $S/dnsmasq.pid ] && kill -0 "$(cat $S/dnsmasq.pid)" 2>/dev/null && cat $S/dnsmasq.pid; }
|
||||||
|
case "$1" in
|
||||||
|
up)
|
||||||
|
log "=== ROUTER UP"
|
||||||
|
nft list tables >/dev/null 2>&1 || fail "kernel has no nf_tables ($(uname -r))"
|
||||||
|
[ -e /sys/class/net/$LAN_IF ] || fail "$LAN_IF absent"; [ -e /sys/class/net/$WAN_IF ] || fail "$WAN_IF absent"
|
||||||
|
DNS=$(sed -n 's/^DNS=//p' /run/aurora-modem/ipcfg 2>/dev/null | tr ',' ' '); [ -n "$DNS" ] || DNS=$FALLBACK_DNS
|
||||||
|
[ -f $S/ip_forward.saved ] || cat /proc/sys/net/ipv4/ip_forward > $S/ip_forward.saved
|
||||||
|
ip -4 addr show dev $LAN_IF | grep -q "inet $LAN_ADDR/" || ip addr add $LAN_ADDR/$LAN_PFX dev $LAN_IF || fail "addr $LAN_IF"
|
||||||
|
if ! ip route | grep -q "^default"; then ip route add default dev $WAN_IF && echo $WAN_IF > $S/default.added || fail "default route"; fi
|
||||||
|
cat > $S/ruleset.nft <<N
|
||||||
|
table inet aurora_router
|
||||||
|
delete table inet aurora_router
|
||||||
|
table inet aurora_router {
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority filter; policy accept;
|
||||||
|
ct state established,related accept
|
||||||
|
iifname "lo" accept
|
||||||
|
iifname "$MGMT_IF" accept
|
||||||
|
iifname "$LAN_IF" jump lan_in
|
||||||
|
iifname "$WAN_IF" jump wan_in
|
||||||
|
}
|
||||||
|
chain lan_in {
|
||||||
|
udp sport 68 udp dport 67 accept comment "DHCP (incl. broadcast)"
|
||||||
|
ip daddr != $LAN_ADDR counter drop comment "Wi-Fi may not touch mgmt/WAN addresses of the board"
|
||||||
|
udp dport 53 accept
|
||||||
|
tcp dport 22 accept comment "B17: SSH (dropbear) from Wi-Fi to the board LAN address only"
|
||||||
|
tcp dport 53 accept
|
||||||
|
icmp type echo-request limit rate 20/second accept
|
||||||
|
meta l4proto ipv6-icmp accept
|
||||||
|
counter drop
|
||||||
|
}
|
||||||
|
chain wan_in {
|
||||||
|
icmp type { echo-reply, destination-unreachable, time-exceeded } accept
|
||||||
|
counter drop comment "no unsolicited inbound from LTE"
|
||||||
|
}
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority filter; policy drop;
|
||||||
|
ct state invalid counter drop
|
||||||
|
iifname "$LAN_IF" oifname "$WAN_IF" ip saddr $LAN_NET counter accept
|
||||||
|
iifname "$WAN_IF" oifname "$LAN_IF" ct state established,related counter accept
|
||||||
|
iifname "$LAN_IF" oifname "$MGMT_IF" counter drop comment "Wi-Fi -> USB mgmt blocked"
|
||||||
|
iifname "$MGMT_IF" oifname "$LAN_IF" counter drop
|
||||||
|
counter drop comment "default deny (incl. LTE -> LAN)"
|
||||||
|
}
|
||||||
|
chain postrouting {
|
||||||
|
type nat hook postrouting priority srcnat; policy accept;
|
||||||
|
oifname "$WAN_IF" ip saddr $LAN_NET counter masquerade
|
||||||
|
}
|
||||||
|
}
|
||||||
|
N
|
||||||
|
# B15: aurora-vpn owns the firewall while up (fail-closed LAN -> tunnel); a late router up (AP enabled after VPN) must not
|
||||||
|
# re-add aurora_router, whose forward chain drops LAN -> wg0/singtun0 (both forward hooks must accept).
|
||||||
|
if nft list table inet aurora_vpn >/dev/null 2>&1; then log "aurora_vpn table present: keep VPN firewall, skip aurora_router ruleset"
|
||||||
|
else nft -f $S/ruleset.nft || fail "nft ruleset"; fi
|
||||||
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||||
|
if [ -z "$(dpid)" ]; then
|
||||||
|
{ echo "interface=$LAN_IF"; echo "except-interface=lo"; echo "bind-interfaces"; echo "no-resolv"; echo "no-hosts"
|
||||||
|
for d in $DNS; do echo "server=$d"; done
|
||||||
|
echo "dhcp-range=$DHCP_RANGE"; echo "dhcp-option=option:router,$LAN_ADDR"; echo "dhcp-option=option:dns-server,$LAN_ADDR"
|
||||||
|
echo "dhcp-leasefile=$S/dnsmasq.leases"; echo "dhcp-authoritative"; echo "cache-size=300"; echo "domain-needed"; echo "bogus-priv"
|
||||||
|
echo "pid-file=$S/dnsmasq.pid"; echo "log-facility=$S/dnsmasq.log"; echo "log-dhcp"; echo "user=root"; } > $S/dnsmasq.conf
|
||||||
|
dnsmasq --conf-file=$S/dnsmasq.conf || fail "dnsmasq"; sleep 1
|
||||||
|
fi
|
||||||
|
[ -n "$(dpid)" ] || fail "dnsmasq not running"
|
||||||
|
log "=== ROUTER UP OK lan $LAN_IF $LAN_ADDR/$LAN_PFX dhcp $DHCP_RANGE dns [$DNS] wan $WAN_IF default=[$(ip route | grep "^default")] fwd=$(cat /proc/sys/net/ipv4/ip_forward) dnsmasq=$(dpid)";;
|
||||||
|
down)
|
||||||
|
log "=== ROUTER DOWN"
|
||||||
|
p=$(dpid); [ -n "$p" ] && { kill $p; sleep 1; }; rm -f $S/dnsmasq.pid
|
||||||
|
nft list table inet aurora_router >/dev/null 2>&1 && nft delete table inet aurora_router
|
||||||
|
[ -f $S/ip_forward.saved ] && { cat $S/ip_forward.saved > /proc/sys/net/ipv4/ip_forward; rm -f $S/ip_forward.saved; }
|
||||||
|
ip addr del $LAN_ADDR/$LAN_PFX dev $LAN_IF 2>/dev/null
|
||||||
|
[ -f $S/default.added ] && { ip route del default dev "$(cat $S/default.added)" 2>/dev/null; rm -f $S/default.added; }
|
||||||
|
log "=== ROUTER DOWN OK fwd=$(cat /proc/sys/net/ipv4/ip_forward) tables=[$(nft list tables 2>/dev/null | tr '\n' ' ')] default=[$(ip route | grep "^default")]";;
|
||||||
|
status)
|
||||||
|
echo "kernel $(uname -r) ip_forward=$(cat /proc/sys/net/ipv4/ip_forward) dnsmasq=$(dpid)"
|
||||||
|
ip -4 addr show dev $LAN_IF | grep inet; ip route | grep "^default"
|
||||||
|
echo "-- leases"; cat $S/dnsmasq.leases 2>/dev/null
|
||||||
|
echo "-- stations"; iw dev $LAN_IF station dump 2>/dev/null | grep -E "^Station|signal:|connected time"
|
||||||
|
echo "-- conntrack $(cat /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null)"
|
||||||
|
nft list table inet aurora_router 2>&1 | grep -E "counter|chain"
|
||||||
|
tail -3 $LOG 2>/dev/null;;
|
||||||
|
*) echo "usage: $0 up|down|status"; exit 2;;
|
||||||
|
esac
|
||||||
130
b15/run/aurora-vpn
Normal file
130
b15/run/aurora-vpn
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# aurora-vpn (B15): full-tunnel VPN for the Wi-Fi LAN. Two modes (/etc/aurora/vpn.conf VPN_MODE):
|
||||||
|
# vless = sing-box VLESS-over-WS-over-TLS via CDN, TUN singtun0 (config /etc/sing-box/config.json)
|
||||||
|
# wg = kernel WireGuard wg0 (config /etc/wireguard/wg0.conf)
|
||||||
|
# LAN clients are policy-routed into the tunnel; the board itself, USB NCM management and the tunnel's own
|
||||||
|
# outbound (to the VPN server/CDN) stay DIRECT on wwan0 (source-based rule -> no loop).
|
||||||
|
# Fail-closed: while up, LAN may leave ONLY via the tunnel; if it is down, LAN has no internet (never LTE).
|
||||||
|
# aurora-vpn up | down | status. Needs kernel 7.2.7-aurora-b15 (TUN; WireGuard for wg mode).
|
||||||
|
TBL=51820; RULE_PRI=100; S=/run/aurora-vpn; mkdir -p $S; LOG=$S/vpn.log
|
||||||
|
[ -f /etc/aurora/router.conf ] && . /etc/aurora/router.conf
|
||||||
|
[ -f /etc/aurora/vpn.conf ] && . /etc/aurora/vpn.conf
|
||||||
|
VPN_MODE=${VPN_MODE:-wg}; LAN_IF=${LAN_IF:-wlan0}; LAN_NET=${LAN_NET:-192.168.77.0/24}; LAN_ADDR=${LAN_ADDR:-192.168.77.1}
|
||||||
|
WAN_IF=${WAN_IF:-wwan0}; MGMT_IF=${MGMT_IF:-usb0}; TUN_IF=${TUN_IF:-singtun0}; TUN_MTU=${TUN_MTU:-1400}
|
||||||
|
SB=/etc/sing-box/config.json; WGC=/etc/wireguard/wg0.conf
|
||||||
|
now() { cut -d' ' -f1 /proc/uptime; }
|
||||||
|
log() { m="[$(now)] $*"; echo "$m"; echo "$m" >> $LOG; echo "<5>[aurora-vpn] $*" > /dev/kmsg 2>/dev/null; }
|
||||||
|
fail() { log "FAIL: $*"; exit 1; }
|
||||||
|
tif() { [ "$VPN_MODE" = wg ] && echo wg0 || echo "$TUN_IF"; }
|
||||||
|
|
||||||
|
firewall() {
|
||||||
|
T=$(tif); MSS=$(( ${1:-$TUN_MTU} - 40 ))
|
||||||
|
nft list table inet aurora_router >/dev/null 2>&1 && nft delete table inet aurora_router
|
||||||
|
nft -f - <<NFT || fail "nft"
|
||||||
|
table inet aurora_vpn {
|
||||||
|
chain input {
|
||||||
|
type filter hook input priority filter; policy accept;
|
||||||
|
ct state established,related accept
|
||||||
|
iifname "lo" accept
|
||||||
|
iifname "$MGMT_IF" accept
|
||||||
|
iifname "$LAN_IF" jump lan_in
|
||||||
|
iifname { "$WAN_IF", "$T" } jump wan_in
|
||||||
|
}
|
||||||
|
chain lan_in {
|
||||||
|
udp sport 68 udp dport 67 accept
|
||||||
|
ip daddr != $LAN_ADDR counter drop
|
||||||
|
udp dport 53 accept
|
||||||
|
tcp dport 22 accept comment "B17: SSH (dropbear) from Wi-Fi to the board LAN address only"
|
||||||
|
tcp dport 53 accept
|
||||||
|
icmp type echo-request limit rate 20/second accept
|
||||||
|
counter drop
|
||||||
|
}
|
||||||
|
chain wan_in {
|
||||||
|
icmp type { echo-reply, destination-unreachable, time-exceeded } accept
|
||||||
|
ct state established,related accept
|
||||||
|
counter drop
|
||||||
|
}
|
||||||
|
chain forward {
|
||||||
|
type filter hook forward priority filter; policy drop;
|
||||||
|
ct state invalid counter drop
|
||||||
|
iifname "$LAN_IF" oifname "$T" ip saddr $LAN_NET tcp flags syn tcp option maxseg size set $MSS
|
||||||
|
iifname "$LAN_IF" oifname "$T" ip saddr $LAN_NET counter accept
|
||||||
|
iifname "$T" oifname "$LAN_IF" ct state established,related counter accept
|
||||||
|
iifname "$LAN_IF" oifname "$WAN_IF" counter drop comment "fail-closed: no LTE leak"
|
||||||
|
iifname "$LAN_IF" oifname "$MGMT_IF" counter drop
|
||||||
|
counter drop
|
||||||
|
}
|
||||||
|
chain postrouting {
|
||||||
|
type nat hook postrouting priority srcnat; policy accept;
|
||||||
|
oifname "$T" ip saddr $LAN_NET counter masquerade
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NFT
|
||||||
|
}
|
||||||
|
route_lan() {
|
||||||
|
T=$(tif)
|
||||||
|
ip route replace default dev "$T" table $TBL
|
||||||
|
ip rule show | grep -q "lookup $TBL" || ip rule add from "$LAN_NET" lookup $TBL priority $RULE_PRI
|
||||||
|
ip rule show | grep -q "from $LAN_NET to $LAN_NET lookup main" || ip rule add from "$LAN_NET" to "$LAN_NET" lookup main priority $((RULE_PRI-1))
|
||||||
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||||
|
}
|
||||||
|
unroute() {
|
||||||
|
while ip rule del from "$LAN_NET" lookup $TBL 2>/dev/null; do :; done
|
||||||
|
while ip rule del from "$LAN_NET" to "$LAN_NET" lookup main 2>/dev/null; do :; done
|
||||||
|
ip route flush table $TBL 2>/dev/null
|
||||||
|
}
|
||||||
|
case "$1" in
|
||||||
|
up)
|
||||||
|
log "=== VPN UP ($VPN_MODE)"
|
||||||
|
if [ "$VPN_MODE" = vless ]; then
|
||||||
|
[ -f $SB ] || fail "$SB missing"
|
||||||
|
command -v sing-box >/dev/null || fail "sing-box not installed"
|
||||||
|
pidof sing-box >/dev/null && { log "sing-box already running"; } || {
|
||||||
|
sing-box check -c $SB 2>>$LOG || fail "sing-box config invalid"
|
||||||
|
setsid sh -c "trap '' HUP; exec sing-box run -c $SB" >> $S/sing-box.log 2>&1 < /dev/null &
|
||||||
|
echo $! > $S/sing-box.pid
|
||||||
|
}
|
||||||
|
i=0; while [ ! -e /sys/class/net/$TUN_IF ] && [ $i -lt 100 ]; do sleep 0.1; i=$((i+1)); done
|
||||||
|
[ -e /sys/class/net/$TUN_IF ] || { tail -8 $S/sing-box.log; fail "$TUN_IF did not appear"; }
|
||||||
|
ip link set $TUN_IF mtu $TUN_MTU 2>/dev/null
|
||||||
|
else
|
||||||
|
ip link add dev wg0 type wireguard 2>/dev/null || ip link show wg0 >/dev/null 2>&1 || fail "no WireGuard"
|
||||||
|
[ -f $WGC ] || fail "$WGC missing"
|
||||||
|
A=$(sed -n 's/^Address[ ]*=[ ]*//p' $WGC | head -1); M=$(sed -n 's/^MTU[ ]*=[ ]*//p' $WGC | head -1); EP=$(sed -n 's/^Endpoint[ ]*=[ ]*//p' $WGC | head -1 | sed 's/:[0-9]*$//')
|
||||||
|
wg-quick strip wg0 2>/dev/null | wg setconf wg0 /dev/stdin || { ip link del wg0; fail "wg setconf"; }
|
||||||
|
ip addr flush dev wg0; ip addr add "$A" dev wg0; ip link set wg0 mtu "${M:-$TUN_MTU}" up
|
||||||
|
# loopback endpoint = local relay (free-turn-client on 127.0.0.1): its own uplink is board traffic -> main -> wwan0
|
||||||
|
case "$EP" in 127.*) log "endpoint $EP is local relay: no direct route";;
|
||||||
|
*) GW=$(ip route show default dev $WAN_IF | awk '{print $3; exit}'); ip route replace "$EP/32" dev $WAN_IF ${GW:+via $GW}; echo "$EP" > $S/endpoint;; esac
|
||||||
|
fi
|
||||||
|
route_lan; firewall $M
|
||||||
|
log "=== VPN UP OK mode=$VPN_MODE tun=$(tif) LAN $LAN_NET -> $(tif) (table $TBL); fail-closed on"
|
||||||
|
;;
|
||||||
|
down)
|
||||||
|
log "=== VPN DOWN"
|
||||||
|
[ "$VPN_MODE" = vless ] && { pidof sing-box >/dev/null && kill $(pidof sing-box); sleep 1; pidof sing-box >/dev/null && kill -9 $(pidof sing-box); rm -f $S/sing-box.pid; }
|
||||||
|
[ "$VPN_MODE" = wg ] && ip link del wg0 2>/dev/null
|
||||||
|
unroute
|
||||||
|
[ -f $S/endpoint ] && { ip route del "$(cat $S/endpoint)/32" dev $WAN_IF 2>/dev/null; rm -f $S/endpoint; }
|
||||||
|
nft list table inet aurora_vpn >/dev/null 2>&1 && nft delete table inet aurora_vpn
|
||||||
|
/usr/sbin/aurora-router up >/dev/null 2>&1 || log "note: run 'aurora-router up' to restore LAN->LTE"
|
||||||
|
log "=== VPN DOWN OK (router restored: $(nft list tables 2>/dev/null | tr '\n' ' '))"
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
T=$(tif); echo "kernel $(uname -r) mode $VPN_MODE"
|
||||||
|
if [ -e /sys/class/net/$T ]; then
|
||||||
|
echo "$T UP mtu=$(cat /sys/class/net/$T/mtu)"
|
||||||
|
if [ "$VPN_MODE" = vless ]; then
|
||||||
|
echo "sing-box pid=$(pidof sing-box) rss_kB=$(awk '/VmRSS/{print $2}' /proc/$(pidof sing-box 2>/dev/null)/status 2>/dev/null)"
|
||||||
|
tail -3 $S/sing-box.log 2>/dev/null | sed 's/^/ /'
|
||||||
|
else
|
||||||
|
HS=$(wg show wg0 latest-handshakes 2>/dev/null | awk '{print $2}' | head -1)
|
||||||
|
echo "handshake_age=$([ -n "$HS" ] && [ "$HS" != 0 ] && echo $(( $(date +%s)-HS ))s || echo never) transfer=$(wg show wg0 transfer 2>/dev/null | awk '{print $2"/"$3}')"
|
||||||
|
fi
|
||||||
|
echo "rules:"; ip rule show | grep -E "lookup $TBL|$LAN_NET"
|
||||||
|
echo "table $TBL:"; ip route show table $TBL
|
||||||
|
else echo "$T DOWN"; fi
|
||||||
|
nft list table inet aurora_vpn 2>/dev/null | grep -E "oifname|masquerade|drop" | sed 's/^[ \t]*//' | head
|
||||||
|
;;
|
||||||
|
*) echo "usage: $0 up|down|status"; exit 2;;
|
||||||
|
esac
|
||||||
16
b15/run/aurora-vpn-diag
Normal file
16
b15/run/aurora-vpn-diag
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# aurora-vpn-diag (B15): read-only VPN/leak diagnostics, no secrets (no keys, no endpoint port).
|
||||||
|
. /etc/aurora/router.conf 2>/dev/null; LAN_NET=${LAN_NET:-192.168.77.0/24}; WAN_IF=${WAN_IF:-wwan0}; WG=wg0; TBL=51820
|
||||||
|
echo "== kernel"; uname -r
|
||||||
|
echo "== $WAN_IF"; ip -4 -o addr show $WAN_IF | awk '{print $4}'; ip route show default
|
||||||
|
echo "== $WG"; if ip link show $WG >/dev/null 2>&1; then ip -4 -o addr show $WG | awk '{print $2,$4,"mtu",$0}' | sed 's/.*mtu/mtu/;s/\\\\/ /'; wg show $WG | grep -vE "private|listening"; else echo DOWN; fi
|
||||||
|
echo "== handshake"; hs=$(wg show $WG latest-handshakes 2>/dev/null | awk '{print $2}' | head -1); [ -n "$hs" ] && [ "$hs" != 0 ] && echo "age $(( $(date +%s) - hs )) s" || echo "none"
|
||||||
|
echo "== rules"; ip rule show | grep -E "lookup $TBL|$LAN_NET" || echo none
|
||||||
|
echo "== table $TBL"; ip route show table $TBL || echo empty
|
||||||
|
echo "== endpoint path (must be $WAN_IF, not $WG):"; ep=$(cat /run/aurora-vpn/endpoint 2>/dev/null); [ -n "$ep" ] && ip route get "$ep" | head -1 || echo "no endpoint recorded"
|
||||||
|
echo "== nft forward/nat counters"; nft list table inet aurora_vpn 2>/dev/null | grep -E "oifname|masquerade|drop" | sed 's/^[ \t]*//'
|
||||||
|
echo "== wg transfer"; wg show $WG transfer 2>/dev/null | sed 's/\\t/ /g' || echo none
|
||||||
|
echo "== LEAK TEST (LAN source route): a LAN client packet must exit via $WG, NOT $WAN_IF"
|
||||||
|
echo " ip route get 1.1.1.1 from ${LAN_NET%/*}.100:"; ip route get 1.1.1.1 from "$(echo $LAN_NET | sed 's#0/24#100#')" 2>/dev/null | head -1
|
||||||
|
verdict=$(ip route get 1.1.1.1 from "$(echo $LAN_NET | sed 's#0/24#100#')" 2>/dev/null | grep -oE "dev [a-z0-9]+" | awk '{print $2}' | head -1)
|
||||||
|
if ip link show $WG >/dev/null 2>&1; then [ "$verdict" = "$WG" ] && echo " LEAK-GUARD: OK (LAN -> $WG)" || echo " LEAK-GUARD: WARN (LAN -> ${verdict:-?})"; else echo " LEAK-GUARD: VPN down -> LAN forward dropped (fail-closed)"; fi
|
||||||
7
b15/run/aurora-vpn.openrc
Normal file
7
b15/run/aurora-vpn.openrc
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
# B15: full-tunnel WireGuard for the Wi-Fi LAN (installed as /etc/init.d/aurora-vpn; default runlevel since 2026-10-05 (free-turn wg mode)).
|
||||||
|
description="Aurora WireGuard full tunnel (Wi-Fi LAN -> wg0)"
|
||||||
|
depend() { need aurora-router; use free-turn; after aurora-modem aurora-wifi free-turn; }
|
||||||
|
start() { ebegin "aurora-vpn up"; /usr/local/bin/aurora-vpn up >> /run/aurora-vpn.service.log 2>&1; eend $?; }
|
||||||
|
stop() { ebegin "aurora-vpn down"; /usr/local/bin/aurora-vpn down >> /run/aurora-vpn.service.log 2>&1; eend $?; }
|
||||||
|
status() { /usr/local/bin/aurora-vpn status; }
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue