mirror of
https://github.com/archr-linux/Arch-R.git
synced 2026-07-12 18:19:42 -07:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9b55f926c0 | |||
| b36a333523 | |||
| c8e7fe99e9 | |||
| 06dc2d16f3 | |||
| 8650d940e2 | |||
| 70342ca457 | |||
| b6eff2e748 | |||
| 9c30a92cab | |||
| cbc39b8802 | |||
| 87719600d2 | |||
| baaeb69a19 | |||
| a1efd4fc01 | |||
| e4294ab47b | |||
| 70765e96bd | |||
| 2ccf5383ac | |||
| 476b05cd9a | |||
| a9029b419f |
+34
@@ -3,6 +3,20 @@ output/
|
||||
|
||||
# Kernel and bootloader source (cloned during build)
|
||||
kernel/src/
|
||||
|
||||
# Kernel module build artifacts (compiled .ko/.o are not source)
|
||||
kernel/drivers/**/*.o
|
||||
kernel/drivers/**/*.ko
|
||||
kernel/drivers/**/*.mod
|
||||
kernel/drivers/**/*.mod.c
|
||||
kernel/drivers/**/*.mod.o
|
||||
kernel/drivers/**/*.cmd
|
||||
kernel/drivers/**/Module.symvers
|
||||
kernel/drivers/**/modules.order
|
||||
kernel/drivers/**/.module-common.o
|
||||
|
||||
# Compiled DTBs in source tree (use output/boot/dtbs/ instead)
|
||||
kernel/dts/*.dtb
|
||||
bootloader/src/
|
||||
|
||||
# Build cache
|
||||
@@ -71,3 +85,23 @@ restore-mesa26-gbm.sh
|
||||
|
||||
# Website (separate project)
|
||||
website/
|
||||
|
||||
# Environment secrets
|
||||
.env
|
||||
|
||||
# Bootloader source trees (cloned/downloaded during build)
|
||||
bootloader/rkbin/
|
||||
bootloader/u-boot-mainline/
|
||||
bootloader/u-boot-rk3326-clone/
|
||||
|
||||
# Pre-built U-Boot backups (working binaries, not part of build pipeline)
|
||||
bootloader/u-boot-clone-working/
|
||||
|
||||
# Extracted DTBs (debugging artifacts)
|
||||
bootloader/u-boot-r36s-working/extracted_dtb_*.dtb
|
||||
|
||||
# Clone U-Boot build output
|
||||
bootloader/u-boot-clone-build/
|
||||
|
||||
# Others
|
||||
feedback/
|
||||
+610
File diff suppressed because it is too large
Load Diff
@@ -8,22 +8,32 @@
|
||||
>
|
||||
> Leve como uma pluma.
|
||||
|
||||
Arch R is a custom Linux distribution built from scratch for the R36S handheld gaming console (RK3326 SoC, Mali-G31 GPU, 640x480 MIPI DSI display). It supports all R36S variants and clones with 18 different display panels.
|
||||
Arch R is a custom Linux distribution built from scratch for the R36S handheld gaming console (RK3326 SoC, Mali-G31 GPU, 640x480 MIPI DSI display). It supports all R36S variants and clones — 16 board profiles and 20 display panels.
|
||||
|
||||
## Features
|
||||
|
||||
- **Kernel 6.6.89** (Rockchip BSP) — custom DTS with joypad, panel init sequences, audio, USB OTG
|
||||
- **Kernel 6.12.61** (Mainline LTS) — board auto-detection via SARADC, 16 board DTBs, panel overlays
|
||||
- **Mesa 26 Panfrost** — open-source GPU driver, GLES 1.0/2.0/3.1, no proprietary blobs
|
||||
- **EmulationStation** (fcamod fork) — 78fps stable, GLES 1.0 native rendering
|
||||
- **RetroArch 1.22.2** — KMS/DRM + EGL, 18+ cores pre-installed
|
||||
- **19-second boot** — U-Boot logo → kernel → systemd → EmulationStation
|
||||
- **Full audio** — ALSA, speaker + headphone auto-switch, volume hotkeys
|
||||
- **Battery monitoring** — LED warning, capacity/voltage/temp reporting
|
||||
- **Multi-panel support** — 18 panel DTBOs (6 original R36S + 12 clones)
|
||||
- **19-second boot** — initramfs splash at 0.7s, systemd to EmulationStation
|
||||
- **Full audio** — ALSA, speaker + headphone auto-switch, volume/brightness hotkeys
|
||||
- **Battery monitoring** — capacity/voltage reporting, LED warning
|
||||
- **Multi-panel support** — 20 panel overlays (7 original + 13 clone variants)
|
||||
- **Two images** — Original R36S and Clone boards, both auto-detect hardware
|
||||
|
||||
## Quick Start — Flash a Pre-built Image
|
||||
## Quick Start
|
||||
|
||||
Download the latest image from [Releases](../../releases), then:
|
||||
Download the latest images from [Releases](../../releases):
|
||||
|
||||
- **`ArchR-R36S-*.img.xz`** — for genuine R36S, OGA, OGS, RG351V/M, Chi, R33S
|
||||
- **`ArchR-R36S-clone-*.img.xz`** — for K36 clones, RGB20S, RGB10X, XU-Mini-M, R36Max
|
||||
|
||||
### Using Arch R Flasher (recommended)
|
||||
|
||||
Download the [Arch R Flasher](https://github.com/archr-linux/archr-flasher) app, select your console type and display panel, and flash directly. The Flasher handles image download, panel overlay selection, and SD card writing.
|
||||
|
||||
### Manual Flash
|
||||
|
||||
```bash
|
||||
xz -d ArchR-R36S-*.img.xz
|
||||
@@ -31,7 +41,16 @@ sudo dd if=ArchR-R36S-*.img of=/dev/sdX bs=4M status=progress
|
||||
sync
|
||||
```
|
||||
|
||||
Insert the SD card into your R36S and power on. First boot creates a ROMS partition automatically.
|
||||
After flashing, mount the BOOT partition and copy your panel overlay:
|
||||
|
||||
```bash
|
||||
sudo mount /dev/sdX1 /mnt
|
||||
sudo cp /mnt/overlays/panel4-v22.dtbo /mnt/overlays/mipi-panel.dtbo
|
||||
sudo umount /mnt
|
||||
sync
|
||||
```
|
||||
|
||||
Insert the SD card and power on. The correct board DTB is selected automatically.
|
||||
|
||||
## Building from Source
|
||||
|
||||
@@ -40,7 +59,6 @@ Insert the SD card into your R36S and power on. First boot creates a ROMS partit
|
||||
- **OS:** Ubuntu 22.04+ (or any Linux with QEMU user-static support)
|
||||
- **Disk:** 30GB+ free space
|
||||
- **RAM:** 4GB+ recommended
|
||||
- **Time:** ~3-4 hours (first build), ~1 hour (incremental)
|
||||
|
||||
### Install Dependencies
|
||||
|
||||
@@ -66,21 +84,22 @@ sudo apt install -y \
|
||||
### Build Everything
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules https://github.com/user/Arch-R.git
|
||||
git clone --recurse-submodules https://github.com/archr-linux/Arch-R.git
|
||||
cd Arch-R
|
||||
|
||||
# Full build (kernel + rootfs + mesa + ES + retroarch + panels + image)
|
||||
# Full build: kernel + rootfs + mesa + ES + retroarch + panels + both images
|
||||
sudo ./build-all.sh
|
||||
```
|
||||
|
||||
The flashable image will be at `output/images/ArchR-R36S-YYYYMMDD.img.xz` (~860MB compressed).
|
||||
Output: `output/images/ArchR-R36S-YYYYMMDD.img.xz` and `ArchR-R36S-clone-YYYYMMDD.img.xz`
|
||||
|
||||
### Build Individual Components
|
||||
|
||||
```bash
|
||||
sudo ./build-all.sh --kernel # Kernel only (~10 min)
|
||||
sudo ./build-all.sh --rootfs # Rootfs + Mesa + ES + RetroArch (~3 hours)
|
||||
sudo ./build-all.sh --image # Image assembly only (~2 min)
|
||||
sudo ./build-all.sh --kernel # Kernel + initramfs (~10 min, cross-compile)
|
||||
sudo ./build-all.sh --rootfs # Rootfs + Mesa + ES + RetroArch (~3 hours, QEMU chroot)
|
||||
sudo ./build-all.sh --uboot # U-Boot (~2 min)
|
||||
sudo ./build-all.sh --image # Image assembly only (~2 min per variant)
|
||||
sudo ./build-all.sh --clean # Remove all build artifacts
|
||||
```
|
||||
|
||||
@@ -88,53 +107,63 @@ sudo ./build-all.sh --clean # Remove all build artifacts
|
||||
|
||||
```
|
||||
build-all.sh
|
||||
├── build-kernel.sh # Cross-compile kernel 6.6.89 (~10 min)
|
||||
├── build-rootfs.sh # Arch Linux ARM rootfs in QEMU chroot (~45 min)
|
||||
├── build-mesa.sh # Mesa 26 with Panfrost + GLES 1.0 (~30 min)
|
||||
├── build-emulationstation.sh # ES-fcamod with 21 patches (~20 min)
|
||||
├── build-retroarch.sh # RetroArch + cores (~40 min)
|
||||
├── generate-panel-dtbos.sh # 18 panel DTBO overlays (~10 sec)
|
||||
└── build-image.sh # Assemble SD card image (~2 min)
|
||||
├── build-initramfs.sh # Boot splash (SVG rendering, ~648KB)
|
||||
├── build-kernel.sh # Cross-compile kernel 6.12.61 (~10 min)
|
||||
├── build-rootfs.sh # Arch Linux ARM in QEMU chroot (~45 min)
|
||||
├── build-mesa.sh # Mesa 26 Panfrost + GLES 1.0 (~30 min)
|
||||
├── build-emulationstation.sh # ES-fcamod with patches (~20 min)
|
||||
├── build-retroarch.sh # RetroArch + cores (~40 min)
|
||||
├── generate-panel-dtbos.sh # 20 panel overlays (~10 sec)
|
||||
├── build-uboot.sh # BSP U-Boot for original boards
|
||||
├── build-uboot-clone.sh # Mainline U-Boot for clone boards
|
||||
└── build-image.sh # SD card image (×2 variants)
|
||||
```
|
||||
|
||||
All builds happen inside a QEMU aarch64 chroot — no cross-compilation issues.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
Arch-R/
|
||||
├── build-all.sh # Master build orchestrator
|
||||
├── build-kernel.sh # Kernel compilation
|
||||
├── build-rootfs.sh # Root filesystem (Arch Linux ARM + services)
|
||||
├── build-mesa.sh # Mesa 26 GPU driver
|
||||
├── build-emulationstation.sh # EmulationStation frontend
|
||||
├── build-retroarch.sh # RetroArch + cores
|
||||
├── build-image.sh # SD card image assembly
|
||||
├── build-all.sh # Master build orchestrator
|
||||
├── build-kernel.sh # Kernel 6.12.61 cross-compilation
|
||||
├── build-initramfs.sh # Initramfs with boot splash
|
||||
├── build-rootfs.sh # Root filesystem (Arch Linux ARM)
|
||||
├── build-mesa.sh # Mesa 26 GPU driver
|
||||
├── build-emulationstation.sh # EmulationStation frontend
|
||||
├── build-retroarch.sh # RetroArch + cores
|
||||
├── build-uboot.sh # BSP U-Boot (original boards)
|
||||
├── build-uboot-clone.sh # Mainline U-Boot (clone boards)
|
||||
├── build-image.sh # SD card image assembly
|
||||
├── config/
|
||||
│ ├── archr-6.6-r36s.config # Kernel config fragment (393 options)
|
||||
│ ├── boot.ini # U-Boot fallback boot script
|
||||
│ ├── es_systems.cfg # EmulationStation system definitions
|
||||
│ ├── retroarch.cfg # RetroArch base configuration
|
||||
│ ├── asound.conf # ALSA audio configuration
|
||||
│ └── autoconfig/ # RetroArch controller autoconfig
|
||||
│ ├── linux-archr-base.config # Kernel config (mainline 6.12)
|
||||
│ ├── a_boot.ini # Boot script — original variant
|
||||
│ ├── b_boot.ini # Boot script — clone variant
|
||||
│ ├── es_systems.cfg # EmulationStation systems
|
||||
│ ├── retroarch.cfg # RetroArch base config
|
||||
│ ├── asound.conf # ALSA audio config
|
||||
│ ├── gptokeyb/ # Gamepad-to-keyboard mappings
|
||||
│ ├── udev/ # udev rules (automount, USB gadget)
|
||||
│ └── autoconfig/ # RetroArch controller autoconfig
|
||||
├── kernel/
|
||||
│ └── dts/
|
||||
│ ├── rk3326-gameconsole-r36s.dts # Custom R36S device tree
|
||||
│ └── R36S-DTB/ # Reference panel DTBs
|
||||
│ ├── dts/archr/ # Board device trees (16 boards)
|
||||
│ └── drivers/ # Out-of-tree joypad driver
|
||||
├── patches/ # Kernel patches (mainline + device)
|
||||
├── scripts/
|
||||
│ ├── emulationstation.sh # ES launch wrapper
|
||||
│ ├── retroarch-launch.sh # RetroArch launch wrapper
|
||||
│ ├── archr-hotkeys.py # Volume/brightness hotkey daemon
|
||||
│ ├── first-boot.sh # First boot setup (ROMS partition)
|
||||
│ ├── generate-panel-dtbos.sh # Panel overlay generator
|
||||
│ ├── pmic-poweroff # PMIC shutdown handler
|
||||
│ └── vlc-stub.c # VLC stub library for ES build
|
||||
│ ├── emulationstation.sh # ES launch wrapper
|
||||
│ ├── retroarch-launch.sh # RetroArch launch wrapper
|
||||
│ ├── archr-hotkeys.py # Volume/brightness hotkey daemon
|
||||
│ ├── archr-init.c # Initramfs splash (static binary)
|
||||
│ ├── archr-gptokeyb.c # Gamepad-to-keyboard mapper
|
||||
│ ├── panel-detect.py # Panel detection
|
||||
│ ├── generate-panel-dtbos.sh # Panel overlay generator
|
||||
│ ├── pmic-poweroff # PMIC shutdown handler
|
||||
│ └── opt-system/ # ES Tools menu scripts
|
||||
├── bootloader/
|
||||
│ └── u-boot-r36s-working/ # Pre-built U-Boot binaries
|
||||
│ └── u-boot-rk3326/ # U-Boot source (submodule)
|
||||
├── prebuilt/
|
||||
│ └── cores/ # Pre-built RetroArch cores (FBNeo, MAME, N64, PSP)
|
||||
├── ArchR.png # Boot logo source
|
||||
└── ROADMAP.md # Development diary
|
||||
│ └── cores/ # Pre-built RetroArch cores
|
||||
├── ArchR.png # Boot logo
|
||||
├── ROADMAP.md # Development diary
|
||||
└── FLASHER.md # Flasher app specification
|
||||
```
|
||||
|
||||
## Hardware
|
||||
@@ -144,29 +173,101 @@ Arch-R/
|
||||
| SoC | Rockchip RK3326 (4x Cortex-A35 @ 1.5GHz) |
|
||||
| GPU | Mali-G31 Bifrost (Mesa Panfrost, 600MHz) |
|
||||
| RAM | 1GB DDR3L (786MHz) |
|
||||
| Display | 640x480 MIPI DSI (18 panel variants) |
|
||||
| Display | 640x480 MIPI DSI (20 panel variants) |
|
||||
| Audio | RK817 codec, speaker + headphone jack |
|
||||
| Storage | MicroSD (boot + rootfs + ROMS) |
|
||||
| Storage | MicroSD (BOOT + rootfs + ROMS) |
|
||||
| Controls | D-pad, ABXY, L1/L2/R1/R2, dual analog sticks |
|
||||
| Battery | 3200mAh Li-Po (RK817 charger) |
|
||||
| USB | OTG with host mode (VBUS power on GPIO0_B7) |
|
||||
| USB | OTG with host/gadget mode switching |
|
||||
|
||||
## Supported Panels
|
||||
## Architecture
|
||||
|
||||
Arch R supports 18 display panels via DTBO overlays:
|
||||
Arch R separates **board configuration** from **panel configuration**:
|
||||
|
||||
**Original R36S:** Panel 0, Panel 1 (V10), Panel 2 (V12), Panel 3 (V20), Panel 4 (V22, default), Panel 5 (V22 Q8)
|
||||
- **Board DTB** = hardware profile (GPIOs, PMIC, joypad, audio codec). One per board variant. Selected automatically by U-Boot via SARADC ADC reading.
|
||||
- **Panel overlay** = display init sequence and timings. One per panel type. Applied on top of the board DTB at boot time.
|
||||
|
||||
**Clones:** Clone Panel 1-10 (ST7703, NV3051D variants), R36 Max, RX6S
|
||||
This means the same image works on all boards of a variant — only the panel overlay needs to match your specific display.
|
||||
|
||||
### Supported Boards
|
||||
|
||||
| Board | DTB | Image |
|
||||
|-------|-----|-------|
|
||||
| R36S (original) | rk3326-gameconsole-r36s | Original |
|
||||
| Odroid Go Advance | rk3326-odroid-go2 | Original |
|
||||
| Odroid Go Advance v1.1 | rk3326-odroid-go2-v11 | Original |
|
||||
| Odroid Go Super | rk3326-odroid-go3 | Original |
|
||||
| Anbernic RG351V | rk3326-anbernic-rg351v | Original |
|
||||
| Anbernic RG351M | rk3326-anbernic-rg351m | Original |
|
||||
| GameForce Chi | rk3326-gameforce-chi | Original |
|
||||
| R33S | rk3326-gameconsole-r33s | Original |
|
||||
| MagicX XU10 | rk3326-magicx-xu10 | Original |
|
||||
| K36 / R36S clone | rk3326-gameconsole-r36max | Clone |
|
||||
| EE clone | rk3326-gameconsole-eeclone | Clone |
|
||||
| Powkiddy RGB10 | rk3326-powkiddy-rgb10 | Clone |
|
||||
| Powkiddy RGB10X | rk3326-powkiddy-rgb10x | Clone |
|
||||
| Powkiddy RGB20S | rk3326-powkiddy-rgb20s | Clone |
|
||||
| MagicX XU-Mini-M | rk3326-magicx-xu-mini-m | Clone |
|
||||
| BatLexp G350 | rk3326-batlexp-g350 | Clone |
|
||||
|
||||
### Supported Panels
|
||||
|
||||
#### Original R36S (7 panels)
|
||||
|
||||
| Panel | Overlay file | Controller | Notes |
|
||||
|-------|-------------|------------|-------|
|
||||
| Panel 0 | panel0.dtbo | ST7703 | Early R36S units |
|
||||
| Panel 1 | panel1.dtbo | ST7703 | V10 board |
|
||||
| Panel 2 | panel2.dtbo | ST7703 | V12 board |
|
||||
| Panel 3 | panel3.dtbo | ST7703 | V20 board |
|
||||
| Panel 4 | panel4.dtbo | ST7703 | V22 board |
|
||||
| Panel 4-V22 | panel4-v22.dtbo | ST7703 | Most common (~60%) |
|
||||
| Panel 5 | panel5.dtbo | ST7703 | V22 Q8 variant |
|
||||
|
||||
R46H (1024x768): `r46h.dtbo`
|
||||
|
||||
#### Clone R36S (13 panels)
|
||||
|
||||
| Panel | Overlay file | Controller | Notes |
|
||||
|-------|-------------|------------|-------|
|
||||
| Clone 1 | clone_panel_1.dtbo | ST7703 | |
|
||||
| Clone 2 | clone_panel_2.dtbo | ST7703 | |
|
||||
| Clone 3 | clone_panel_3.dtbo | NV3051D | |
|
||||
| Clone 4 | clone_panel_4.dtbo | NV3051D | |
|
||||
| Clone 5 | clone_panel_5.dtbo | ST7703 | |
|
||||
| Clone 6 | clone_panel_6.dtbo | NV3051D | |
|
||||
| Clone 7 | clone_panel_7.dtbo | JD9365DA | |
|
||||
| Clone 8 | clone_panel_8.dtbo | ST7703 | G80CA — most common |
|
||||
| Clone 9 | clone_panel_9.dtbo | NV3051D | |
|
||||
| Clone 10 | clone_panel_10.dtbo | ST7703 | |
|
||||
| R36 Max | r36_max.dtbo | ST7703 | 720x720 |
|
||||
| RX6S | rx6s.dtbo | NV3051D | |
|
||||
|
||||
### Manual Panel Selection
|
||||
|
||||
Mount the BOOT partition and copy the correct overlay as `mipi-panel.dtbo`:
|
||||
|
||||
```bash
|
||||
sudo mount /dev/sdX1 /mnt
|
||||
|
||||
# Example: set Panel 4-V22 (most common original R36S panel)
|
||||
sudo cp /mnt/overlays/panel4-v22.dtbo /mnt/overlays/mipi-panel.dtbo
|
||||
|
||||
# Example: set Clone 8 (most common clone panel)
|
||||
sudo cp /mnt/overlays/clone_panel_8.dtbo /mnt/overlays/mipi-panel.dtbo
|
||||
|
||||
sudo umount /mnt
|
||||
sync
|
||||
```
|
||||
|
||||
## Boot Flow
|
||||
|
||||
```
|
||||
Power On
|
||||
→ U-Boot (idbloader → trust → uboot.img)
|
||||
→ logo.bmp displayed on screen
|
||||
→ extlinux/extlinux.conf loaded (primary)
|
||||
→ Kernel 6.6.89 + rk3326-gameconsole-r36s.dtb
|
||||
→ U-Boot loads (idbloader → trust → uboot.img)
|
||||
→ boot.ini: read SARADC hwrev → select board DTB
|
||||
→ boot.ini: apply overlays/mipi-panel.dtbo (panel init sequence)
|
||||
→ Kernel 6.12.61 + initramfs splash (0.7s)
|
||||
→ systemd → archr-boot-setup (GPU + governors)
|
||||
→ emulationstation.service → EmulationStation UI
|
||||
≈ 19 seconds total
|
||||
|
||||
+824
-153
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+1
-1
Submodule bootloader/u-boot-rk3326 updated: 5606e804ff...2492a3e467
+38
-4
@@ -44,6 +44,7 @@ usage() {
|
||||
echo "Options:"
|
||||
echo " --kernel Build kernel only"
|
||||
echo " --rootfs Build rootfs only"
|
||||
echo " --uboot Build U-Boot only"
|
||||
echo " --image Build image only"
|
||||
echo " --all Build everything (default)"
|
||||
echo " --clean Clean all build artifacts"
|
||||
@@ -53,6 +54,7 @@ usage() {
|
||||
|
||||
BUILD_KERNEL=false
|
||||
BUILD_ROOTFS=false
|
||||
BUILD_UBOOT=false
|
||||
BUILD_IMAGE=false
|
||||
CLEAN=false
|
||||
|
||||
@@ -60,14 +62,16 @@ CLEAN=false
|
||||
if [ $# -eq 0 ]; then
|
||||
BUILD_KERNEL=true
|
||||
BUILD_ROOTFS=true
|
||||
BUILD_UBOOT=true
|
||||
BUILD_IMAGE=true
|
||||
else
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--kernel) BUILD_KERNEL=true; shift ;;
|
||||
--rootfs) BUILD_ROOTFS=true; shift ;;
|
||||
--uboot) BUILD_UBOOT=true; shift ;;
|
||||
--image) BUILD_IMAGE=true; shift ;;
|
||||
--all) BUILD_KERNEL=true; BUILD_ROOTFS=true; BUILD_IMAGE=true; shift ;;
|
||||
--all) BUILD_KERNEL=true; BUILD_ROOTFS=true; BUILD_UBOOT=true; BUILD_IMAGE=true; shift ;;
|
||||
--clean) CLEAN=true; shift ;;
|
||||
--help) usage; exit 0 ;;
|
||||
*) error "Unknown option: $1" ;;
|
||||
@@ -125,6 +129,14 @@ log "✓ Prerequisites OK"
|
||||
START_TIME=$(date +%s)
|
||||
|
||||
if [ "$BUILD_KERNEL" = true ]; then
|
||||
# Initramfs must be built BEFORE kernel — kernel embeds it at compile time
|
||||
log ""
|
||||
log "═══════════════════════════════════════════════════════════════"
|
||||
log " BUILDING INITRAMFS"
|
||||
log "═══════════════════════════════════════════════════════════════"
|
||||
chmod +x "$SCRIPT_DIR/build-initramfs.sh"
|
||||
"$SCRIPT_DIR/build-initramfs.sh"
|
||||
|
||||
log ""
|
||||
log "═══════════════════════════════════════════════════════════════"
|
||||
log " BUILDING KERNEL"
|
||||
@@ -180,13 +192,35 @@ log "═════════════════════════
|
||||
chmod +x "$SCRIPT_DIR/scripts/generate-panel-dtbos.sh"
|
||||
"$SCRIPT_DIR/scripts/generate-panel-dtbos.sh"
|
||||
|
||||
# Build U-Boot BSP (requires aarch64 cross-compiler)
|
||||
if [ "$BUILD_UBOOT" = true ] && [ -f "$SCRIPT_DIR/build-uboot.sh" ]; then
|
||||
if command -v aarch64-linux-gnu-gcc &>/dev/null; then
|
||||
log ""
|
||||
log "═══════════════════════════════════════════════════════════════"
|
||||
log " BUILDING U-BOOT"
|
||||
log "═══════════════════════════════════════════════════════════════"
|
||||
chmod +x "$SCRIPT_DIR/build-uboot.sh"
|
||||
"$SCRIPT_DIR/build-uboot.sh"
|
||||
else
|
||||
warn "Skipping U-Boot build: aarch64-linux-gnu-gcc not found"
|
||||
warn "Install: sudo apt install gcc-aarch64-linux-gnu"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$BUILD_IMAGE" = true ]; then
|
||||
chmod +x "$SCRIPT_DIR/build-image.sh"
|
||||
|
||||
log ""
|
||||
log "═══════════════════════════════════════════════════════════════"
|
||||
log " BUILDING IMAGE"
|
||||
log " BUILDING IMAGE (original)"
|
||||
log "═══════════════════════════════════════════════════════════════"
|
||||
chmod +x "$SCRIPT_DIR/build-image.sh"
|
||||
"$SCRIPT_DIR/build-image.sh"
|
||||
"$SCRIPT_DIR/build-image.sh" --variant original
|
||||
|
||||
log ""
|
||||
log "═══════════════════════════════════════════════════════════════"
|
||||
log " BUILDING IMAGE (clone)"
|
||||
log "═══════════════════════════════════════════════════════════════"
|
||||
"$SCRIPT_DIR/build-image.sh" --variant clone
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
+154
-162
@@ -3,7 +3,18 @@
|
||||
#==============================================================================
|
||||
# Arch R - SD Card Image Builder
|
||||
#==============================================================================
|
||||
# Creates a flashable SD card image for R36S
|
||||
# Creates a flashable SD card image for Arch R.
|
||||
#
|
||||
# BOOT partition layout:
|
||||
# /KERNEL ← kernel Image
|
||||
# /boot.ini ← boot script (BSP reads directly, hwrev→DTB)
|
||||
# /dtbs/rk3326-*.dtb ← ALL board DTBs (selected by boot.ini hwrev mapping)
|
||||
# /overlays/*.dtbo ← all available panel overlays (no default — Flasher selects)
|
||||
#
|
||||
# Usage:
|
||||
# sudo ./build-image.sh --variant original # Original R36S, OGA, OGS, RG351, etc.
|
||||
# sudo ./build-image.sh --variant clone # K36 clones, RGB20S, RGB10X, etc.
|
||||
# sudo ./build-image.sh # defaults to original
|
||||
#==============================================================================
|
||||
|
||||
set -e
|
||||
@@ -20,18 +31,52 @@ log() { echo -e "${GREEN}[$(date '+%H:%M:%S')]${NC} $1"; }
|
||||
warn() { echo -e "${YELLOW}[$(date '+%H:%M:%S')] WARNING:${NC} $1"; }
|
||||
error() { echo -e "${RED}[$(date '+%H:%M:%S')] ERROR:${NC} $1"; exit 1; }
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Parse arguments
|
||||
#------------------------------------------------------------------------------
|
||||
VARIANT="original"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--variant)
|
||||
VARIANT="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
error "Unknown option: $1\nUsage: $0 --variant original|clone"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$VARIANT" != "original" ] && [ "$VARIANT" != "clone" ]; then
|
||||
error "Invalid variant: $VARIANT (must be 'original' or 'clone')"
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Variant-specific configuration
|
||||
#------------------------------------------------------------------------------
|
||||
if [ "$VARIANT" = "original" ]; then
|
||||
IMAGE_SUFFIX="R36S"
|
||||
BOOT_INI="$SCRIPT_DIR/config/a_boot.ini"
|
||||
else
|
||||
IMAGE_SUFFIX="R36S-clone"
|
||||
BOOT_INI="$SCRIPT_DIR/config/b_boot.ini"
|
||||
fi
|
||||
|
||||
# U-Boot binaries (same BSP build for both variants)
|
||||
UBOOT_BIN_DIR="$SCRIPT_DIR/bootloader/u-boot-rk3326/sd_fuse"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Configuration
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
OUTPUT_DIR="$SCRIPT_DIR/output"
|
||||
ROOTFS_DIR="$OUTPUT_DIR/rootfs"
|
||||
BOOT_OUTPUT="$OUTPUT_DIR/boot"
|
||||
PANELS_DIR="$OUTPUT_DIR/panels"
|
||||
IMAGE_DIR="$OUTPUT_DIR/images"
|
||||
IMAGE_NAME="ArchR-R36S-$(date +%Y%m%d).img"
|
||||
IMAGE_NAME="ArchR-${IMAGE_SUFFIX}-$(date +%Y%m%d).img"
|
||||
|
||||
# CRITICAL: Always clean up loop devices and mounts on exit (success OR failure).
|
||||
# Without this trap, a build error leaves loop devices and mounts dangling —
|
||||
# loop device holds the image file, mounts prevent cleanup.
|
||||
# Cleanup on exit
|
||||
LOOP_DEV=""
|
||||
cleanup_image() {
|
||||
echo "[IMAGE] Cleaning up mounts and loop devices..."
|
||||
@@ -44,14 +89,11 @@ trap cleanup_image EXIT
|
||||
IMAGE_FILE="$IMAGE_DIR/$IMAGE_NAME"
|
||||
|
||||
# Partition sizes (in MB)
|
||||
BOOT_SIZE=128 # Boot partition (FAT32)
|
||||
ROOTFS_SIZE=6144 # Root filesystem (ext4) - 6GB for full Arch + gaming stack
|
||||
# ROMS partition will use remaining space on actual SD card
|
||||
BOOT_SIZE=128
|
||||
ROOTFS_SIZE=6144
|
||||
IMAGE_SIZE=$((BOOT_SIZE + ROOTFS_SIZE + 32))
|
||||
|
||||
# Total image size
|
||||
IMAGE_SIZE=$((BOOT_SIZE + ROOTFS_SIZE + 32)) # +32MB for partition table
|
||||
|
||||
log "=== Arch R Image Builder ==="
|
||||
log "=== Arch R Image Builder (variant: $VARIANT) ==="
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Root check
|
||||
@@ -67,31 +109,54 @@ log ""
|
||||
log "Step 1: Checking prerequisites..."
|
||||
|
||||
if [ ! -d "$ROOTFS_DIR" ]; then
|
||||
error "Rootfs not found at: $ROOTFS_DIR"
|
||||
error "Run build-rootfs.sh first!"
|
||||
error "Rootfs not found at: $ROOTFS_DIR\nRun build-rootfs.sh first!"
|
||||
fi
|
||||
|
||||
if [ ! -f "$ROOTFS_DIR/boot/Image" ]; then
|
||||
warn "Kernel Image not found in rootfs. Make sure kernel is installed."
|
||||
# Kernel
|
||||
if [ ! -f "$BOOT_OUTPUT/KERNEL" ]; then
|
||||
error "Kernel not found at: $BOOT_OUTPUT/KERNEL\nRun build-kernel.sh first!"
|
||||
fi
|
||||
KERNEL_BYTES=$(stat -c%s "$BOOT_OUTPUT/KERNEL")
|
||||
log " KERNEL: $(($KERNEL_BYTES / 1024 / 1024))MB"
|
||||
|
||||
# Board DTBs
|
||||
if [ ! -d "$BOOT_OUTPUT/dtbs" ]; then
|
||||
error "DTBs not found at: $BOOT_OUTPUT/dtbs/\nRun build-kernel.sh first!"
|
||||
fi
|
||||
DTB_COUNT=$(ls "$BOOT_OUTPUT/dtbs"/rk3326-*.dtb 2>/dev/null | wc -l)
|
||||
log " Board DTBs: $DTB_COUNT files"
|
||||
|
||||
# Kernel modules in rootfs
|
||||
if [ ! -d "$ROOTFS_DIR/lib/modules" ] || [ -z "$(ls "$ROOTFS_DIR/lib/modules/" 2>/dev/null)" ]; then
|
||||
warn "Kernel modules not found in rootfs! Run build-rootfs.sh after build-kernel.sh."
|
||||
else
|
||||
# Validate kernel Image size (kernel 6.6 trimmed is ~18MB, stale 4.4 was ~5MB)
|
||||
IMAGE_BYTES=$(stat -c%s "$ROOTFS_DIR/boot/Image")
|
||||
if [ "$IMAGE_BYTES" -lt 10000000 ]; then
|
||||
warn "Kernel Image is only $(($IMAGE_BYTES / 1024 / 1024))MB — expected ~18MB for kernel 6.6!"
|
||||
warn "This may be a stale kernel 4.4 build. Run build-kernel.sh first."
|
||||
error "Aborting: kernel Image too small (likely wrong version)"
|
||||
fi
|
||||
log " Kernel Image: $(($IMAGE_BYTES / 1024 / 1024))MB (OK)"
|
||||
log " Kernel modules: OK"
|
||||
fi
|
||||
|
||||
# Check required tools
|
||||
# Panel overlays (generate if missing)
|
||||
if [ ! -d "$PANELS_DIR" ] || [ -z "$(ls "$PANELS_DIR"/*.dtbo 2>/dev/null)" ]; then
|
||||
log " Panel overlays not found — generating..."
|
||||
if [ -x "$SCRIPT_DIR/scripts/generate-panel-dtbos.sh" ]; then
|
||||
"$SCRIPT_DIR/scripts/generate-panel-dtbos.sh"
|
||||
else
|
||||
warn "Panel overlays not found and generate-panel-dtbos.sh not executable!"
|
||||
fi
|
||||
fi
|
||||
|
||||
# U-Boot
|
||||
if [ ! -d "$UBOOT_BIN_DIR" ] || [ ! -f "$UBOOT_BIN_DIR/idbloader.img" ]; then
|
||||
error "U-Boot binaries not found at: $UBOOT_BIN_DIR"
|
||||
fi
|
||||
log " U-Boot: $UBOOT_BIN_DIR"
|
||||
|
||||
# Tools
|
||||
for tool in parted mkfs.vfat mkfs.ext4 losetup; do
|
||||
if ! command -v $tool &> /dev/null; then
|
||||
error "Required tool not found: $tool"
|
||||
fi
|
||||
done
|
||||
|
||||
log " ✓ Prerequisites OK"
|
||||
log " Prerequisites OK"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 2: Create Image File
|
||||
@@ -100,97 +165,54 @@ log ""
|
||||
log "Step 2: Creating image file..."
|
||||
|
||||
mkdir -p "$IMAGE_DIR"
|
||||
rm -f "$IMAGE_DIR"/ArchR-${IMAGE_SUFFIX}-*.img "$IMAGE_DIR"/ArchR-${IMAGE_SUFFIX}-*.img.xz
|
||||
|
||||
# Remove old images (current date and any previous builds)
|
||||
rm -f "$IMAGE_DIR"/ArchR-R36S-*.img "$IMAGE_DIR"/ArchR-R36S-*.img.xz
|
||||
|
||||
# Create sparse image file
|
||||
dd if=/dev/zero of="$IMAGE_FILE" bs=1M count=0 seek=$IMAGE_SIZE 2>/dev/null
|
||||
log " ✓ Created ${IMAGE_SIZE}MB image"
|
||||
log " Created ${IMAGE_SIZE}MB image: $IMAGE_NAME"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 2.5: Install U-Boot Bootloader
|
||||
# Step 3: Install U-Boot Bootloader
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 2.5: Installing U-Boot bootloader..."
|
||||
log "Step 3: Installing U-Boot bootloader..."
|
||||
|
||||
# Search for U-Boot binaries — prefer R36S-u-boot-builder (known working)
|
||||
UBOOT_DIR=""
|
||||
for dir in "$SCRIPT_DIR/bootloader/u-boot-r36s-working" \
|
||||
"$OUTPUT_DIR/bootloader" \
|
||||
"$SCRIPT_DIR/bootloader/u-boot-rk3326/sd_fuse" \
|
||||
"$SCRIPT_DIR/bootloader/sd_fuse"; do
|
||||
if [ -f "$dir/idbloader.img" ] && [ -f "$dir/uboot.img" ] && [ -f "$dir/trust.img" ]; then
|
||||
UBOOT_DIR="$dir"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$UBOOT_DIR" ]; then
|
||||
dd if="$UBOOT_DIR/idbloader.img" of="$IMAGE_FILE" bs=512 seek=64 conv=sync,noerror,notrunc 2>/dev/null
|
||||
dd if="$UBOOT_DIR/uboot.img" of="$IMAGE_FILE" bs=512 seek=16384 conv=sync,noerror,notrunc 2>/dev/null
|
||||
dd if="$UBOOT_DIR/trust.img" of="$IMAGE_FILE" bs=512 seek=24576 conv=sync,noerror,notrunc 2>/dev/null
|
||||
log " ✓ U-Boot installed from $UBOOT_DIR"
|
||||
else
|
||||
warn "U-Boot files not found!"
|
||||
warn "Run build-uboot.sh first for bootable image!"
|
||||
fi
|
||||
dd if="$UBOOT_BIN_DIR/idbloader.img" of="$IMAGE_FILE" bs=512 seek=64 conv=sync,noerror,notrunc 2>/dev/null
|
||||
dd if="$UBOOT_BIN_DIR/uboot.img" of="$IMAGE_FILE" bs=512 seek=16384 conv=sync,noerror,notrunc 2>/dev/null
|
||||
dd if="$UBOOT_BIN_DIR/trust.img" of="$IMAGE_FILE" bs=512 seek=24576 conv=sync,noerror,notrunc 2>/dev/null
|
||||
log " U-Boot installed"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 3: Create Partitions
|
||||
# Step 4: Create and Format Partitions
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 3: Creating partitions..."
|
||||
log "Step 4: Creating partitions..."
|
||||
|
||||
# Create partition table
|
||||
parted -s "$IMAGE_FILE" mklabel msdos
|
||||
|
||||
# Calculate partition boundaries
|
||||
BOOT_START=16 # Start at 16MB for U-Boot space
|
||||
BOOT_START=16
|
||||
BOOT_END=$((BOOT_START + BOOT_SIZE))
|
||||
ROOTFS_START=$BOOT_END
|
||||
ROOTFS_END=$((ROOTFS_START + ROOTFS_SIZE))
|
||||
|
||||
# Create partitions
|
||||
parted -s "$IMAGE_FILE" mkpart primary fat32 ${BOOT_START}MiB ${BOOT_END}MiB
|
||||
parted -s "$IMAGE_FILE" mkpart primary ext4 ${ROOTFS_START}MiB ${ROOTFS_END}MiB
|
||||
parted -s "$IMAGE_FILE" set 1 boot on
|
||||
|
||||
log " ✓ Partitions created"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 4: Setup Loop Devices
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 4: Setting up loop devices..."
|
||||
|
||||
LOOP_DEV=$(losetup -fP --show "$IMAGE_FILE")
|
||||
BOOT_PART="${LOOP_DEV}p1"
|
||||
ROOT_PART="${LOOP_DEV}p2"
|
||||
|
||||
# Wait for partitions to appear
|
||||
sleep 1
|
||||
|
||||
log " Loop device: $LOOP_DEV"
|
||||
log " Boot: $BOOT_PART"
|
||||
log " Root: $ROOT_PART"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 5: Format Partitions
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 5: Formatting partitions..."
|
||||
|
||||
mkfs.vfat -F 32 -n BOOT "$BOOT_PART"
|
||||
mkfs.ext4 -L ROOTFS -O ^metadata_csum "$ROOT_PART"
|
||||
mkfs.ext4 -L STORAGE -O ^metadata_csum "$ROOT_PART"
|
||||
|
||||
log " ✓ Partitions formatted"
|
||||
log " Partitions: BOOT (${BOOT_SIZE}MB FAT32) + STORAGE (${ROOTFS_SIZE}MB ext4)"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 6: Mount and Copy Files
|
||||
# Step 5: Mount and Copy Files
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 6: Copying files..."
|
||||
log "Step 5: Copying files..."
|
||||
|
||||
MOUNT_ROOT="$OUTPUT_DIR/mnt_root"
|
||||
MOUNT_BOOT="$OUTPUT_DIR/mnt_boot"
|
||||
@@ -199,128 +221,98 @@ mkdir -p "$MOUNT_ROOT" "$MOUNT_BOOT"
|
||||
mount "$ROOT_PART" "$MOUNT_ROOT"
|
||||
mount "$BOOT_PART" "$MOUNT_BOOT"
|
||||
|
||||
# Copy rootfs (excluding /boot)
|
||||
# --- Rootfs (excluding /boot) ---
|
||||
log " Copying rootfs..."
|
||||
rsync -aHxS --exclude='/boot' "$ROOTFS_DIR/" "$MOUNT_ROOT/"
|
||||
|
||||
# Copy boot files
|
||||
log " Copying boot files..."
|
||||
if [ -d "$ROOTFS_DIR/boot" ]; then
|
||||
cp "$ROOTFS_DIR/boot/Image" "$MOUNT_BOOT/"
|
||||
# Only copy the R36S DTB — extra DTBs (r35s, rg351mp-linux) are not needed
|
||||
cp "$ROOTFS_DIR/boot/rk3326-gameconsole-r36s.dtb" "$MOUNT_BOOT/" 2>/dev/null || true
|
||||
fi
|
||||
# --- Variant marker ---
|
||||
mkdir -p "$MOUNT_ROOT/etc/archr"
|
||||
echo "$VARIANT" > "$MOUNT_ROOT/etc/archr/variant"
|
||||
|
||||
# Copy U-Boot DTB (required for U-Boot display initialization)
|
||||
# Default: Panel 4 V22 — most common R36S panel
|
||||
UBOOT_DTB="$SCRIPT_DIR/kernel/dts/R36S-DTB/R36S/Panel 4 - V22/rg351mp-kernel.dtb"
|
||||
if [ ! -f "$UBOOT_DTB" ]; then
|
||||
# Fallback to Panel 0 if Panel 4 V22 not available
|
||||
UBOOT_DTB="$SCRIPT_DIR/kernel/dts/R36S-DTB/R36S/Panel 0/rg351mp-kernel.dtb"
|
||||
fi
|
||||
if [ -f "$UBOOT_DTB" ]; then
|
||||
cp "$UBOOT_DTB" "$MOUNT_BOOT/rg351mp-kernel.dtb"
|
||||
log " ✓ U-Boot DTB installed ($(basename "$(dirname "$UBOOT_DTB")")/rg351mp-kernel.dtb)"
|
||||
else
|
||||
warn "U-Boot DTB not found! U-Boot may not initialize display."
|
||||
fi
|
||||
# --- First-boot flag ---
|
||||
rm -f "$MOUNT_ROOT/var/lib/archr/.first-boot-done"
|
||||
|
||||
# boot.ini (fallback — extlinux.conf is primary boot method)
|
||||
if [ -f "$SCRIPT_DIR/config/boot.ini" ]; then
|
||||
cp "$SCRIPT_DIR/config/boot.ini" "$MOUNT_BOOT/boot.ini"
|
||||
log " ✓ boot.ini installed (fallback boot method)"
|
||||
else
|
||||
error "boot.ini not found at config/boot.ini!"
|
||||
fi
|
||||
# --- BOOT partition: KERNEL ---
|
||||
cp "$BOOT_OUTPUT/KERNEL" "$MOUNT_BOOT/KERNEL"
|
||||
log " KERNEL installed"
|
||||
|
||||
# --- BOOT partition: Board DTBs (ALL rk3326-*.dtb) ---
|
||||
mkdir -p "$MOUNT_BOOT/dtbs"
|
||||
cp "$BOOT_OUTPUT/dtbs"/rk3326-*.dtb "$MOUNT_BOOT/dtbs/"
|
||||
dtb_count=$(ls "$MOUNT_BOOT/dtbs"/rk3326-*.dtb | wc -l)
|
||||
log " DTBs: $dtb_count board DTBs in /dtbs/"
|
||||
|
||||
# --- BOOT partition: Panel overlays ---
|
||||
mkdir -p "$MOUNT_BOOT/overlays"
|
||||
overlay_count=0
|
||||
|
||||
# Panel DTBO overlays (ScreenFiles/)
|
||||
PANELS_DIR="$OUTPUT_DIR/panels/ScreenFiles"
|
||||
if [ -d "$PANELS_DIR" ]; then
|
||||
cp -r "$PANELS_DIR" "$MOUNT_BOOT/"
|
||||
panel_count=$(find "$MOUNT_BOOT/ScreenFiles" -name "*.dtbo" | wc -l)
|
||||
log " ✓ Panel DTBOs installed (${panel_count} panels)"
|
||||
for dtbo in "$PANELS_DIR"/*.dtbo; do
|
||||
[ -f "$dtbo" ] || continue
|
||||
cp "$dtbo" "$MOUNT_BOOT/overlays/"
|
||||
overlay_count=$((overlay_count + 1))
|
||||
done
|
||||
|
||||
log " Panel overlays: $overlay_count shipped (no default — Flasher selects panel)"
|
||||
else
|
||||
warn "Panel DTBOs not found! Run scripts/generate-panel-dtbos.sh first"
|
||||
warn "No panel overlays found — display may not work without mipi-panel.dtbo!"
|
||||
fi
|
||||
|
||||
# U-Boot logo (BMP format — U-Boot displays logo.bmp natively during boot)
|
||||
log " Converting boot logo..."
|
||||
LOGO_SRC="$SCRIPT_DIR/ArchR.png"
|
||||
# --- BOOT partition: boot.ini (BSP U-Boot reads directly) ---
|
||||
cp "$BOOT_INI" "$MOUNT_BOOT/boot.ini"
|
||||
log " boot.ini installed"
|
||||
|
||||
if [ -f "$LOGO_SRC" ]; then
|
||||
if command -v convert &>/dev/null; then
|
||||
convert "$LOGO_SRC" -resize 640x480! -alpha remove -type TrueColor BMP3:"$MOUNT_BOOT/logo.bmp"
|
||||
log " ✓ logo.bmp created ($(du -h "$MOUNT_BOOT/logo.bmp" | cut -f1))"
|
||||
elif command -v ffmpeg &>/dev/null; then
|
||||
ffmpeg -y -loglevel error -i "$LOGO_SRC" -vf "scale=640:480" -pix_fmt bgr24 "$MOUNT_BOOT/logo.bmp"
|
||||
log " ✓ logo.bmp created via ffmpeg"
|
||||
else
|
||||
warn "Neither imagemagick nor ffmpeg found — logo.bmp skipped"
|
||||
warn "Install with: sudo apt install imagemagick"
|
||||
fi
|
||||
else
|
||||
warn "ArchR.png not found — logo.bmp skipped (U-Boot will show no logo)"
|
||||
fi
|
||||
# --- Initramfs is embedded in kernel (no separate file needed) ---
|
||||
|
||||
# Create extlinux.conf (primary boot method — U-Boot loads this first)
|
||||
mkdir -p "$MOUNT_BOOT/extlinux"
|
||||
cat > "$MOUNT_BOOT/extlinux/extlinux.conf" << 'EXTLINUX_EOF'
|
||||
LABEL ArchR
|
||||
LINUX /Image
|
||||
FDT /rk3326-gameconsole-r36s.dtb
|
||||
APPEND root=/dev/mmcblk1p2 rootwait rw console=ttyFIQ0 loglevel=0 quiet vt.global_cursor_default=0 consoleblank=0 printk.devkmsg=off fsck.mode=skip
|
||||
EXTLINUX_EOF
|
||||
log " ✓ extlinux.conf installed (primary boot method)"
|
||||
|
||||
# Create fstab (overrides rootfs fstab with correct entries)
|
||||
# --- Rootfs: fstab ---
|
||||
cat > "$MOUNT_ROOT/etc/fstab" << 'FSTAB_EOF'
|
||||
# Arch R fstab — optimized for fast boot
|
||||
# fsck disabled (fsck.mode=skip in cmdline + pass=0 here)
|
||||
LABEL=BOOT /boot vfat defaults,noatime 0 0
|
||||
LABEL=ROOTFS / ext4 defaults,noatime 0 0
|
||||
LABEL=STORAGE / ext4 defaults,noatime 0 0
|
||||
LABEL=ROMS /roms vfat defaults,utf8,noatime,uid=1001,gid=1001,nofail,x-systemd.device-timeout=10s 0 0
|
||||
tmpfs /tmp tmpfs defaults,nosuid,nodev,size=128M 0 0
|
||||
tmpfs /var/log tmpfs defaults,nosuid,nodev,noexec,size=16M 0 0
|
||||
FSTAB_EOF
|
||||
log " ✓ Files copied"
|
||||
|
||||
log " fstab installed"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 7: Cleanup
|
||||
# Step 6: Sync and Unmount
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 7: Syncing filesystem..."
|
||||
|
||||
log "Step 6: Syncing filesystem..."
|
||||
sync
|
||||
|
||||
# Mounts and loop device cleaned up by EXIT trap (cleanup_image)
|
||||
log " ✓ Sync complete"
|
||||
log " Sync complete"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 8: Compress (optional)
|
||||
# Step 7: Compress
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 8: Compressing image..."
|
||||
log "Step 7: Compressing image..."
|
||||
|
||||
if command -v xz &> /dev/null; then
|
||||
rm -f "${IMAGE_FILE}.xz"
|
||||
xz -9 -k "$IMAGE_FILE"
|
||||
COMPRESSED="${IMAGE_FILE}.xz"
|
||||
COMPRESSED_SIZE=$(du -h "$COMPRESSED" | cut -f1)
|
||||
log " ✓ Compressed: $COMPRESSED ($COMPRESSED_SIZE)"
|
||||
log " Compressed: $COMPRESSED ($COMPRESSED_SIZE)"
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Summary
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "=== Image Build Complete ==="
|
||||
log "=== Image Build Complete ($VARIANT) ==="
|
||||
log ""
|
||||
|
||||
IMAGE_SIZE_ACTUAL=$(du -h "$IMAGE_FILE" | cut -f1)
|
||||
log "Image: $IMAGE_FILE"
|
||||
log "Size: $IMAGE_SIZE_ACTUAL"
|
||||
log "Image: $IMAGE_FILE ($IMAGE_SIZE_ACTUAL)"
|
||||
log "Variant: $VARIANT"
|
||||
log "DTBs: $dtb_count board DTBs"
|
||||
log "Overlays: $overlay_count panel overlays"
|
||||
log ""
|
||||
log "To flash to SD card:"
|
||||
log " sudo dd if=$IMAGE_FILE of=/dev/sdX bs=4M status=progress"
|
||||
log ""
|
||||
log "✓ Arch R image ready!"
|
||||
log "Arch R image ready!"
|
||||
|
||||
Executable
+102
@@ -0,0 +1,102 @@
|
||||
#!/bin/bash
|
||||
|
||||
#==============================================================================
|
||||
# Arch R - Initramfs Builder
|
||||
#==============================================================================
|
||||
# Generates the initramfs directory for kernel embedding (CONFIG_INITRAMFS_SOURCE).
|
||||
# Must run BEFORE build-kernel.sh — the kernel embeds this at compile time.
|
||||
#
|
||||
# Pipeline:
|
||||
# 1. Compile archr-init.c + SVG splash library (static aarch64 binary)
|
||||
# 2. Create initramfs directory tree (init + dev + proc + newroot)
|
||||
#
|
||||
# Logo is rendered from SVG paths at runtime (no ImageMagick needed).
|
||||
#
|
||||
# Output: $OUTPUT_DIR/initramfs/ (directory tree, not cpio)
|
||||
#==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
log() { echo -e "${GREEN}[$(date '+%H:%M:%S')]${NC} $1"; }
|
||||
warn() { echo -e "${YELLOW}[$(date '+%H:%M:%S')] WARNING:${NC} $1"; }
|
||||
error() { echo -e "${RED}[$(date '+%H:%M:%S')] ERROR:${NC} $1"; exit 1; }
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Configuration
|
||||
#------------------------------------------------------------------------------
|
||||
OUTPUT_DIR="$SCRIPT_DIR/output"
|
||||
INITRAMFS_DIR="$OUTPUT_DIR/initramfs"
|
||||
SPLASH_DIR="$SCRIPT_DIR/scripts/splash"
|
||||
|
||||
log "================================================================"
|
||||
log " Arch R - Initramfs Builder (SVG splash)"
|
||||
log "================================================================"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Prerequisites
|
||||
#------------------------------------------------------------------------------
|
||||
if ! command -v aarch64-linux-gnu-gcc &>/dev/null; then
|
||||
error "Cross-compiler not found. Install: sudo apt install gcc-aarch64-linux-gnu"
|
||||
fi
|
||||
|
||||
# Verify splash library files exist
|
||||
for f in fbsplash.c svg_parser.c svg_renderer.c archr-logo.h; do
|
||||
if [ ! -f "$SPLASH_DIR/$f" ]; then
|
||||
error "Missing splash file: $SPLASH_DIR/$f"
|
||||
fi
|
||||
done
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 1: Compile archr-init (static aarch64 binary with SVG splash)
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 1: Compiling archr-init (SVG splash)..."
|
||||
|
||||
TMPDIR=$(mktemp -d)
|
||||
|
||||
aarch64-linux-gnu-gcc -static -O2 \
|
||||
-I"$SPLASH_DIR" \
|
||||
-o "$TMPDIR/archr-init" \
|
||||
"$SCRIPT_DIR/scripts/archr-init.c" \
|
||||
"$SPLASH_DIR/fbsplash.c" \
|
||||
"$SPLASH_DIR/svg_parser.c" \
|
||||
"$SPLASH_DIR/svg_renderer.c" \
|
||||
-lm
|
||||
|
||||
log " archr-init compiled ($(du -h "$TMPDIR/archr-init" | cut -f1))"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 2: Create initramfs directory tree
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 2: Creating initramfs directory..."
|
||||
|
||||
rm -rf "$INITRAMFS_DIR"
|
||||
mkdir -p "$INITRAMFS_DIR"/{dev,proc,newroot}
|
||||
|
||||
cp "$TMPDIR/archr-init" "$INITRAMFS_DIR/init"
|
||||
chmod 755 "$INITRAMFS_DIR/init"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Cleanup
|
||||
#------------------------------------------------------------------------------
|
||||
rm -rf "$TMPDIR"
|
||||
|
||||
INIT_SIZE=$(du -h "$INITRAMFS_DIR/init" | cut -f1)
|
||||
log ""
|
||||
log "================================================================"
|
||||
log " Initramfs Ready"
|
||||
log "================================================================"
|
||||
log ""
|
||||
log " Directory: $INITRAMFS_DIR"
|
||||
log " /init: $INIT_SIZE (static aarch64 + SVG splash)"
|
||||
log ""
|
||||
log " Kernel will embed this via CONFIG_INITRAMFS_SOURCE"
|
||||
+217
-109
@@ -1,9 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
#==============================================================================
|
||||
# Arch R - Kernel 6.6 Build Script for R36S
|
||||
# Arch R - Kernel Build Script
|
||||
#==============================================================================
|
||||
# Builds Linux kernel 6.6.89 (Rockchip BSP) with R36S DTS + systemd support
|
||||
# Builds mainline Linux 6.12.x with Arch R patches for RK3326 R36S
|
||||
# Applies: device patches, 6.12-LTS patches, mainline patches
|
||||
# Builds: kernel Image + ALL DTBs + modules + out-of-tree joypad driver
|
||||
#==============================================================================
|
||||
|
||||
set -e
|
||||
@@ -14,7 +16,6 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m'
|
||||
|
||||
log() { echo -e "${GREEN}[$(date '+%H:%M:%S')]${NC} $1"; }
|
||||
@@ -22,20 +23,18 @@ warn() { echo -e "${YELLOW}[$(date '+%H:%M:%S')] WARNING:${NC} $1"; }
|
||||
error() { echo -e "${RED}[$(date '+%H:%M:%S')] ERROR:${NC} $1"; exit 1; }
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Configuration - Kernel 6.6 Rockchip BSP
|
||||
# Configuration
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
KERNEL_VERSION="6.6.89"
|
||||
KERNEL_BRANCH="develop-6.6"
|
||||
KERNEL_REPO="https://github.com/rockchip-linux/kernel.git"
|
||||
DEFCONFIG="rockchip_linux_defconfig"
|
||||
CONFIG_FRAGMENT="$SCRIPT_DIR/config/archr-6.6-r36s.config"
|
||||
|
||||
# DTS target
|
||||
R36S_DTB="rk3326-gameconsole-r36s"
|
||||
KERNEL_VERSION="6.12.61"
|
||||
KERNEL_URL="https://www.kernel.org/pub/linux/kernel/v6.x/linux-${KERNEL_VERSION}.tar.xz"
|
||||
|
||||
# Paths
|
||||
KERNEL_SRC="${KERNEL_SRC:-/home/dgateles/Documentos/Projetos/kernel}"
|
||||
KERNEL_SRC="$SCRIPT_DIR/kernel/src/linux-${KERNEL_VERSION}"
|
||||
PATCHES_DIR="$SCRIPT_DIR/patches/linux"
|
||||
DTS_DIR="$SCRIPT_DIR/kernel/dts/archr"
|
||||
JOYPAD_DIR="$SCRIPT_DIR/kernel/drivers/archr-joypad"
|
||||
CONFIG_BASE="$SCRIPT_DIR/config/linux-archr-base.config"
|
||||
|
||||
# Output
|
||||
OUTPUT_DIR="$SCRIPT_DIR/output"
|
||||
@@ -49,13 +48,17 @@ export CROSS_COMPILE=aarch64-linux-gnu-
|
||||
# Build parallelism
|
||||
JOBS=$(nproc)
|
||||
|
||||
# DTS target directory inside kernel
|
||||
KERNEL_DTS_DIR="$KERNEL_SRC/arch/arm64/boot/dts/rockchip"
|
||||
|
||||
log "================================================================"
|
||||
log " Arch R - Kernel $KERNEL_VERSION (Rockchip BSP for R36S)"
|
||||
log " Arch R - Kernel $KERNEL_VERSION (Mainline + Arch R patches)"
|
||||
log "================================================================"
|
||||
log ""
|
||||
log "Source: $KERNEL_SRC"
|
||||
log "Branch: $KERNEL_BRANCH"
|
||||
log "DTB: $R36S_DTB"
|
||||
log "Patches: $PATCHES_DIR"
|
||||
log "DTS: $DTS_DIR"
|
||||
log "Config: $CONFIG_BASE"
|
||||
log "Jobs: $JOBS"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
@@ -65,11 +68,13 @@ log ""
|
||||
log "Step 1: Checking kernel source..."
|
||||
|
||||
if [ ! -d "$KERNEL_SRC" ]; then
|
||||
log " Cloning kernel 6.6 (rockchip-linux/kernel)..."
|
||||
log " Branch: $KERNEL_BRANCH"
|
||||
git clone --depth 1 --branch "$KERNEL_BRANCH" \
|
||||
"$KERNEL_REPO" "$KERNEL_SRC"
|
||||
log " Kernel cloned"
|
||||
TARBALL="$SCRIPT_DIR/kernel/src/linux-${KERNEL_VERSION}.tar.xz"
|
||||
if [ ! -f "$TARBALL" ]; then
|
||||
log " Downloading kernel $KERNEL_VERSION..."
|
||||
wget -c "$KERNEL_URL" -O "$TARBALL"
|
||||
fi
|
||||
log " Extracting..."
|
||||
tar -xf "$TARBALL" -C "$SCRIPT_DIR/kernel/src/"
|
||||
fi
|
||||
|
||||
if [ ! -f "$KERNEL_SRC/Makefile" ]; then
|
||||
@@ -79,68 +84,130 @@ fi
|
||||
ACTUAL_VERSION=$(make -C "$KERNEL_SRC" -s kernelversion 2>/dev/null)
|
||||
log " Kernel: $ACTUAL_VERSION"
|
||||
|
||||
# Copy R36S DTS from Arch-R repo into kernel source tree
|
||||
DTS_SRC="$SCRIPT_DIR/kernel/dts/rk3326-gameconsole-r36s.dts"
|
||||
DTS_DEST="$KERNEL_SRC/arch/arm64/boot/dts/rockchip/rk3326-gameconsole-r36s.dts"
|
||||
if [ -f "$DTS_SRC" ]; then
|
||||
cp "$DTS_SRC" "$DTS_DEST"
|
||||
log " DTS: copied from repo"
|
||||
else
|
||||
if [ -f "$DTS_DEST" ]; then
|
||||
warn "DTS not in Arch-R repo — using existing kernel source copy"
|
||||
else
|
||||
error "DTS not found! Expected at: $DTS_SRC"
|
||||
fi
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 2: Configure Kernel
|
||||
# Step 2: Apply Patches (idempotent — skip already applied)
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 2: Configuring kernel..."
|
||||
log "Step 2: Applying patches..."
|
||||
|
||||
# Apply base defconfig
|
||||
make -C "$KERNEL_SRC" ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE $DEFCONFIG
|
||||
log " Base: $DEFCONFIG"
|
||||
PATCH_MARKER="$KERNEL_SRC/.archr-patches-applied"
|
||||
|
||||
# Merge R36S-specific config fragment
|
||||
# IMPORTANT: merge_config.sh writes output to .config in the CURRENT directory,
|
||||
# NOT to the base config path. Must run from kernel source dir.
|
||||
if [ -f "$CONFIG_FRAGMENT" ]; then
|
||||
pushd "$KERNEL_SRC" > /dev/null
|
||||
MERGE_LOG=$(scripts/kconfig/merge_config.sh \
|
||||
-m .config "$CONFIG_FRAGMENT" 2>&1) || true
|
||||
echo "$MERGE_LOG" | grep -E "(^#|Value)" | tail -20 || true
|
||||
popd > /dev/null
|
||||
make -C "$KERNEL_SRC" ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE olddefconfig
|
||||
# Verify critical GPU config was applied
|
||||
if grep -q "CONFIG_DRM_PANFROST=y" "$KERNEL_SRC/.config"; then
|
||||
log " Panfrost GPU: ENABLED (built-in)"
|
||||
elif grep -q "CONFIG_DRM_PANFROST=m" "$KERNEL_SRC/.config"; then
|
||||
log " Panfrost GPU: ENABLED (module)"
|
||||
else
|
||||
warn " Panfrost GPU: NOT ENABLED — check config fragment!"
|
||||
fi
|
||||
if grep -q "CONFIG_MALI_MIDGARD=y" "$KERNEL_SRC/.config"; then
|
||||
warn " Mali Midgard: STILL ENABLED (conflict with Panfrost!)"
|
||||
else
|
||||
log " Mali Midgard: disabled (good)"
|
||||
fi
|
||||
log " Merged: $(basename "$CONFIG_FRAGMENT")"
|
||||
if [ -f "$PATCH_MARKER" ]; then
|
||||
log " Patches already applied (marker exists). Skipping."
|
||||
else
|
||||
warn "Config fragment not found: $CONFIG_FRAGMENT"
|
||||
PATCH_COUNT=0
|
||||
|
||||
# Order: mainline first (GPIO API, input-polldev), then 6.12-LTS, then device-specific
|
||||
for PATCH_SUBDIR in mainline 6.12-lts device; do
|
||||
PDIR="$PATCHES_DIR/$PATCH_SUBDIR"
|
||||
if [ ! -d "$PDIR" ]; then
|
||||
warn " Patch dir not found: $PDIR"
|
||||
continue
|
||||
fi
|
||||
for PATCH in $(ls "$PDIR"/*.patch 2>/dev/null | sort); do
|
||||
PNAME=$(basename "$PATCH")
|
||||
log " Applying [$PATCH_SUBDIR] $PNAME..."
|
||||
if ! patch -d "$KERNEL_SRC" -p1 --forward --batch < "$PATCH" 2>&1 | tail -3; then
|
||||
warn " Patch may have failed or already applied: $PNAME"
|
||||
fi
|
||||
PATCH_COUNT=$((PATCH_COUNT + 1))
|
||||
done
|
||||
done
|
||||
|
||||
touch "$PATCH_MARKER"
|
||||
log " Applied $PATCH_COUNT patches"
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 3: Copy DTS files
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 3: Copying DTS files..."
|
||||
|
||||
if [ ! -d "$DTS_DIR" ]; then
|
||||
error "DTS directory not found: $DTS_DIR"
|
||||
fi
|
||||
|
||||
DTS_COUNT=0
|
||||
for DTS_FILE in "$DTS_DIR"/*.dts "$DTS_DIR"/*.dtsi; do
|
||||
[ -f "$DTS_FILE" ] || continue
|
||||
DEST="$KERNEL_DTS_DIR/$(basename "$DTS_FILE")"
|
||||
cp "$DTS_FILE" "$DEST"
|
||||
DTS_COUNT=$((DTS_COUNT + 1))
|
||||
done
|
||||
|
||||
# Add DTS entries to Makefile (for each .dts, ensure dtb- line exists)
|
||||
ROCKCHIP_MAKEFILE="$KERNEL_DTS_DIR/Makefile"
|
||||
for DTS_FILE in "$DTS_DIR"/*.dts; do
|
||||
[ -f "$DTS_FILE" ] || continue
|
||||
DTB_NAME=$(basename "$DTS_FILE" .dts)
|
||||
if ! grep -q "${DTB_NAME}.dtb" "$ROCKCHIP_MAKEFILE"; then
|
||||
# Add before the first empty line or at the end of the dtb list
|
||||
echo "dtb-\$(CONFIG_ARCH_ROCKCHIP) += ${DTB_NAME}.dtb" >> "$ROCKCHIP_MAKEFILE"
|
||||
log " Added to Makefile: ${DTB_NAME}.dtb"
|
||||
fi
|
||||
done
|
||||
|
||||
log " Copied $DTS_COUNT DTS files"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 4: Configure Kernel
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 4: Configuring kernel..."
|
||||
|
||||
if [ ! -f "$CONFIG_BASE" ]; then
|
||||
error "Config base not found: $CONFIG_BASE"
|
||||
fi
|
||||
|
||||
# Copy Arch R base config
|
||||
cp "$CONFIG_BASE" "$KERNEL_SRC/.config"
|
||||
|
||||
# Replace placeholder for initramfs
|
||||
INITRAMFS_DIR="$OUTPUT_DIR/initramfs"
|
||||
if [ -d "$INITRAMFS_DIR" ] && [ -x "$INITRAMFS_DIR/init" ]; then
|
||||
log " Embedding initramfs from: $INITRAMFS_DIR"
|
||||
sed -i "s|@INITRAMFS_SOURCE@|${INITRAMFS_DIR}|" "$KERNEL_SRC/.config"
|
||||
else
|
||||
warn " Initramfs not found at $INITRAMFS_DIR"
|
||||
warn " Run build-initramfs.sh first! Disabling embedded initramfs."
|
||||
sed -i 's|CONFIG_INITRAMFS_SOURCE=.*|CONFIG_INITRAMFS_SOURCE=""|' "$KERNEL_SRC/.config"
|
||||
fi
|
||||
|
||||
# Finalize config
|
||||
make -C "$KERNEL_SRC" ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE olddefconfig
|
||||
|
||||
# Verify critical settings
|
||||
log " Verifying config..."
|
||||
check_config() {
|
||||
local key="$1" expected="$2" desc="$3"
|
||||
local val=$(grep "^${key}=" "$KERNEL_SRC/.config" 2>/dev/null | head -1)
|
||||
if [ -z "$val" ]; then
|
||||
val=$(grep "^# ${key} is not set" "$KERNEL_SRC/.config" 2>/dev/null | head -1)
|
||||
fi
|
||||
if echo "$val" | grep -q "$expected"; then
|
||||
log " $desc: OK"
|
||||
else
|
||||
warn " $desc: UNEXPECTED ($val)"
|
||||
fi
|
||||
}
|
||||
|
||||
check_config "CONFIG_DRM_PANFROST" "=m" "Panfrost GPU"
|
||||
check_config "CONFIG_DRM_PANEL_SITRONIX_ST7703" "=y" "ST7703 panel"
|
||||
check_config "CONFIG_FRAMEBUFFER_CONSOLE" "=y" "fbcon"
|
||||
check_config "CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER" "is not set" "No deferred takeover"
|
||||
check_config "CONFIG_EXT4_FS" "=y" "ext4"
|
||||
check_config "CONFIG_DEVTMPFS" "=y" "devtmpfs"
|
||||
|
||||
log " Kernel configured"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 3: Build Kernel Image
|
||||
# Step 5: Build Kernel Image
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 3: Building kernel Image..."
|
||||
log "Step 5: Building kernel Image..."
|
||||
|
||||
make -C "$KERNEL_SRC" -j$JOBS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE Image 2>&1 | \
|
||||
tail -5
|
||||
make -C "$KERNEL_SRC" -j$JOBS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE Image 2>&1 | tail -5
|
||||
|
||||
if [ ! -f "$KERNEL_SRC/arch/arm64/boot/Image" ]; then
|
||||
error "Kernel Image build failed!"
|
||||
@@ -150,68 +217,104 @@ IMAGE_SIZE=$(du -h "$KERNEL_SRC/arch/arm64/boot/Image" | cut -f1)
|
||||
log " Kernel Image built ($IMAGE_SIZE)"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 4: Build Device Tree
|
||||
# Step 6: Build ALL Device Trees
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 4: Building Device Tree ($R36S_DTB)..."
|
||||
log "Step 6: Building Device Trees..."
|
||||
|
||||
make -C "$KERNEL_SRC" -j$JOBS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE \
|
||||
"rockchip/${R36S_DTB}.dtb" 2>&1 | tail -5
|
||||
# Build dtbs target (compiles all DTBs referenced in Makefile)
|
||||
make -C "$KERNEL_SRC" -j$JOBS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE DTC_FLAGS=-@ dtbs 2>&1 | tail -10
|
||||
|
||||
if [ ! -f "$KERNEL_SRC/arch/arm64/boot/dts/rockchip/${R36S_DTB}.dtb" ]; then
|
||||
error "DTB build failed: ${R36S_DTB}.dtb"
|
||||
# Verify R36S DTB was built
|
||||
if [ ! -f "$KERNEL_DTS_DIR/rk3326-gameconsole-r36s.dtb" ]; then
|
||||
error "R36S DTB not built!"
|
||||
fi
|
||||
|
||||
log " DTB built: ${R36S_DTB}.dtb"
|
||||
DTB_COUNT=$(find "$KERNEL_DTS_DIR" -name "rk3326-*.dtb" | wc -l)
|
||||
log " Built $DTB_COUNT RK3326 DTBs"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 5: Build Kernel Modules
|
||||
# Step 7: Build Kernel Modules
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 5: Building kernel modules..."
|
||||
log "Step 7: Building kernel modules..."
|
||||
|
||||
make -C "$KERNEL_SRC" -j$JOBS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE modules 2>&1 | \
|
||||
tail -5
|
||||
make -C "$KERNEL_SRC" -j$JOBS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE modules 2>&1 | tail -5
|
||||
|
||||
log " Kernel modules built"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 6: Install to Output Directory
|
||||
# Step 8: Build Out-of-Tree Drivers
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 6: Installing artifacts..."
|
||||
log "Step 8: Building out-of-tree drivers..."
|
||||
|
||||
if [ -d "$JOYPAD_DIR" ] && [ -f "$JOYPAD_DIR/Makefile" ]; then
|
||||
log " Building archr-joypad..."
|
||||
make -C "$KERNEL_SRC" ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE \
|
||||
M="$JOYPAD_DIR" modules 2>&1 | tail -5
|
||||
if find "$JOYPAD_DIR" -name "*.ko" | grep -q .; then
|
||||
log " archr-joypad: OK"
|
||||
else
|
||||
warn " archr-joypad: no .ko files produced"
|
||||
fi
|
||||
else
|
||||
warn " Joypad driver not found at: $JOYPAD_DIR"
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 9: Install to Output Directory
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 9: Installing artifacts..."
|
||||
|
||||
mkdir -p "$BOOT_DIR"
|
||||
mkdir -p "$MODULES_DIR"
|
||||
|
||||
# Copy kernel image
|
||||
cp "$KERNEL_SRC/arch/arm64/boot/Image" "$BOOT_DIR/"
|
||||
log " Copied: Image"
|
||||
# Copy kernel image as KERNEL (Arch R naming convention)
|
||||
cp "$KERNEL_SRC/arch/arm64/boot/Image" "$BOOT_DIR/KERNEL"
|
||||
log " Copied: KERNEL"
|
||||
|
||||
# Copy R36S DTB
|
||||
cp "$KERNEL_SRC/arch/arm64/boot/dts/rockchip/${R36S_DTB}.dtb" "$BOOT_DIR/"
|
||||
log " Copied: ${R36S_DTB}.dtb"
|
||||
# Copy ALL RK3326 DTBs to dtbs/ subdirectory
|
||||
mkdir -p "$BOOT_DIR/dtbs"
|
||||
for DTB in "$KERNEL_DTS_DIR"/rk3326-*.dtb; do
|
||||
[ -f "$DTB" ] || continue
|
||||
cp "$DTB" "$BOOT_DIR/dtbs/"
|
||||
done
|
||||
log " Copied: $(ls "$BOOT_DIR/dtbs"/rk3326-*.dtb 2>/dev/null | wc -l) DTBs to dtbs/"
|
||||
|
||||
# Install modules (use pipefail to catch errors masked by tail)
|
||||
# Install kernel modules
|
||||
set -o pipefail
|
||||
make -C "$KERNEL_SRC" ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE \
|
||||
INSTALL_MOD_PATH="$MODULES_DIR" \
|
||||
modules_install 2>&1 | tail -5
|
||||
set +o pipefail
|
||||
|
||||
# Remove symlinks (save space)
|
||||
# Install joypad driver module
|
||||
if find "$JOYPAD_DIR" -name "*.ko" | grep -q .; then
|
||||
KREL=$(cat "$KERNEL_SRC/include/config/kernel.release" 2>/dev/null)
|
||||
JOYPAD_DEST="$MODULES_DIR/lib/modules/$KREL/extra/archr-joypad"
|
||||
mkdir -p "$JOYPAD_DEST"
|
||||
cp "$JOYPAD_DIR"/*.ko "$JOYPAD_DEST/"
|
||||
log " Installed joypad modules to: extra/archr-joypad/"
|
||||
# Regenerate modules.dep
|
||||
depmod -b "$MODULES_DIR" "$KREL"
|
||||
fi
|
||||
|
||||
# Remove build/source symlinks (save space on target)
|
||||
rm -f "$MODULES_DIR/lib/modules/"*/source 2>/dev/null || true
|
||||
rm -f "$MODULES_DIR/lib/modules/"*/build 2>/dev/null || true
|
||||
|
||||
# Verify critical module was installed
|
||||
KERNEL_FULL=$(make -C "$KERNEL_SRC" -s kernelversion 2>/dev/null)
|
||||
KREL=$(cat "$KERNEL_SRC/include/config/kernel.release" 2>/dev/null || echo "$KERNEL_FULL")
|
||||
if find "$MODULES_DIR/lib/modules/$KREL" -name 'panfrost.ko*' 2>/dev/null | grep -q .; then
|
||||
log " Panfrost module: INSTALLED"
|
||||
else
|
||||
warn " Panfrost module: NOT FOUND in $MODULES_DIR/lib/modules/$KREL/"
|
||||
warn " Check directory permissions (must be writable by build user)"
|
||||
fi
|
||||
# Verify critical modules
|
||||
KREL=$(cat "$KERNEL_SRC/include/config/kernel.release" 2>/dev/null)
|
||||
for MOD in panfrost; do
|
||||
if find "$MODULES_DIR/lib/modules/$KREL" -name "${MOD}.ko*" 2>/dev/null | grep -q .; then
|
||||
log " Module OK: $MOD"
|
||||
else
|
||||
warn " Module MISSING: $MOD"
|
||||
fi
|
||||
done
|
||||
# Note: rockchipdrm is CONFIG_DRM_ROCKCHIP=y (built-in, not a module) — no .ko to check
|
||||
|
||||
log " Modules installed"
|
||||
|
||||
@@ -224,16 +327,21 @@ log " BUILD COMPLETE"
|
||||
log "================================================================"
|
||||
log ""
|
||||
|
||||
KERNEL_FULL=$(make -C "$KERNEL_SRC" -s kernelversion 2>/dev/null || echo "$KERNEL_VERSION")
|
||||
IMAGE_SIZE=$(du -h "$BOOT_DIR/Image" | cut -f1)
|
||||
DTB_SIZE=$(du -h "$BOOT_DIR/${R36S_DTB}.dtb" | cut -f1)
|
||||
MODULES_SIZE=$(du -sh "$MODULES_DIR" 2>/dev/null | cut -f1 || echo "N/A")
|
||||
KERNEL_FULL=$(make -C "$KERNEL_SRC" -s kernelversion 2>/dev/null)
|
||||
KERNEL_SIZE=$(du -h "$BOOT_DIR/KERNEL" | cut -f1)
|
||||
MODULES_SIZE=$(du -sh "$MODULES_DIR" 2>/dev/null | cut -f1)
|
||||
DTB_COUNT=$(ls "$BOOT_DIR/dtbs"/rk3326-*.dtb 2>/dev/null | wc -l)
|
||||
|
||||
log "Kernel: $KERNEL_FULL"
|
||||
log "Kernel: $KERNEL_FULL (mainline + Arch R patches)"
|
||||
log "KERNEL: $BOOT_DIR/KERNEL ($KERNEL_SIZE)"
|
||||
log "DTBs: $DTB_COUNT files in $BOOT_DIR/dtbs/"
|
||||
log "Modules: $MODULES_DIR/ ($MODULES_SIZE)"
|
||||
log ""
|
||||
log "Artifacts:"
|
||||
log " Image: $BOOT_DIR/Image ($IMAGE_SIZE)"
|
||||
log " DTB: $BOOT_DIR/${R36S_DTB}.dtb ($DTB_SIZE)"
|
||||
log " Modules: $MODULES_DIR/ ($MODULES_SIZE)"
|
||||
log "Key DTBs:"
|
||||
for DTB in rk3326-gameconsole-r36s rk3326-odroid-go2 rk3326-gameconsole-r33s; do
|
||||
if [ -f "$BOOT_DIR/dtbs/${DTB}.dtb" ]; then
|
||||
log " ${DTB}.dtb ($(du -h "$BOOT_DIR/dtbs/${DTB}.dtb" | cut -f1))"
|
||||
fi
|
||||
done
|
||||
log ""
|
||||
log "Kernel 6.6 ready for R36S!"
|
||||
log "Ready for deployment to SD card!"
|
||||
|
||||
+262
-37
@@ -123,15 +123,20 @@ log " ✓ Pacman CheckSpace disabled (QEMU chroot compatibility)"
|
||||
|
||||
# Add multiple fallback mirrors (default mirror often has stale/404 packages)
|
||||
cat > "$ROOTFS_DIR/etc/pacman.d/mirrorlist" << 'MIRRORS_EOF'
|
||||
# Arch Linux ARM mirrors - multiple fallbacks for reliability
|
||||
Server = http://de.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://eu.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://dk.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://de3.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://hu.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://mirror.archlinuxarm.org/$arch/$repo
|
||||
# Arch Linux ARM mirrors - all official, Americas first
|
||||
Server = http://fl.us.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://nj.us.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://ca.us.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://eu.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://de.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://de4.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://dk.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://hu.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://gr.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://de3.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://tw.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://tw2.mirror.archlinuxarm.org/$arch/$repo
|
||||
Server = http://mirror.archlinuxarm.org/$arch/$repo
|
||||
MIRRORS_EOF
|
||||
log " ✓ Multiple ALARM mirrors configured (fallback for 404s)"
|
||||
|
||||
@@ -290,34 +295,33 @@ kernel.sched_latency_ns=1000000
|
||||
kernel.sched_min_granularity_ns=500000
|
||||
SYSCTL_EOF
|
||||
|
||||
# ZRAM swap — via timer, NOT in multi-user.target!
|
||||
# Type=oneshot + WantedBy=multi-user.target means systemd WAITS for mkswap to finish
|
||||
# before reaching multi-user.target. This adds 2.4s to boot critical path.
|
||||
# Fix: use a timer that fires at boot+15s (ES is already running by then).
|
||||
cat > /etc/systemd/system/zram-swap.service << 'ZRAM_EOF'
|
||||
# Memory manager — ZRAM swap with delayed start (15s after boot)
|
||||
# Timer avoids blocking multi-user.target (ES is already running by then)
|
||||
cat > /etc/systemd/system/archr-memory-manager.service << 'MEM_SVC'
|
||||
[Unit]
|
||||
Description=ZRAM Swap
|
||||
Description=Arch R Memory Manager
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/bin/bash -c 'modprobe zram num_devices=1 2>/dev/null; echo lzo > /sys/block/zram0/comp_algorithm; echo 134217728 > /sys/block/zram0/disksize && mkswap /dev/zram0 && swapon -p 100 /dev/zram0'
|
||||
ExecStop=/bin/bash -c 'swapoff /dev/zram0 2>/dev/null; echo 1 > /sys/block/zram0/reset 2>/dev/null'
|
||||
ZRAM_EOF
|
||||
ExecStart=/usr/local/bin/archr-memory-manager setup
|
||||
ExecStop=/usr/local/bin/archr-memory-manager stop
|
||||
ExecReload=/usr/local/bin/archr-memory-manager reload
|
||||
MEM_SVC
|
||||
|
||||
cat > /etc/systemd/system/zram-swap.timer << 'ZRAM_TIMER'
|
||||
cat > /etc/systemd/system/archr-memory-manager.timer << 'MEM_TIMER'
|
||||
[Unit]
|
||||
Description=Delayed ZRAM Swap Setup
|
||||
Description=Delayed Memory Manager Setup
|
||||
|
||||
[Timer]
|
||||
OnBootSec=15s
|
||||
Unit=zram-swap.service
|
||||
Unit=archr-memory-manager.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
ZRAM_TIMER
|
||||
MEM_TIMER
|
||||
|
||||
systemctl enable zram-swap.timer
|
||||
systemctl enable archr-memory-manager.timer
|
||||
|
||||
# Create directories
|
||||
mkdir -p /home/archr/.config/retroarch/cores
|
||||
@@ -353,6 +357,7 @@ fi
|
||||
cat > /etc/systemd/system/firstboot.service << 'FB_EOF'
|
||||
[Unit]
|
||||
Description=Arch R First Boot Setup
|
||||
After=local-fs.target
|
||||
Before=emulationstation.service
|
||||
ConditionPathExists=!/var/lib/archr/.first-boot-done
|
||||
|
||||
@@ -367,6 +372,26 @@ FB_EOF
|
||||
|
||||
systemctl enable firstboot
|
||||
|
||||
# Variant sync: copies variant marker from BOOT → /etc/archr/variant
|
||||
# Only runs if /etc/archr/variant doesn't exist yet (no-panel images flashed by Flasher)
|
||||
cat > /etc/systemd/system/archr-variant-sync.service << 'VARSYNC_EOF'
|
||||
[Unit]
|
||||
Description=Sync variant from BOOT partition
|
||||
After=local-fs.target
|
||||
RequiresMountsFor=/boot
|
||||
ConditionPathExists=!/etc/archr/variant
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/sh -c 'test -f /boot/variant && mkdir -p /etc/archr && cp /boot/variant /etc/archr/variant'
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
VARSYNC_EOF
|
||||
|
||||
systemctl enable archr-variant-sync
|
||||
|
||||
# EmulationStation launch — PRIMARY: systemd service (created by build-emulationstation.sh)
|
||||
# FALLBACK: autologin + .bash_profile (if ES service not installed)
|
||||
# The emulationstation.service Conflicts with getty@tty1, so only one runs.
|
||||
@@ -403,9 +428,12 @@ fi
|
||||
PROFILE_EOF
|
||||
chown archr:archr /home/archr/.bash_profile
|
||||
|
||||
# Disable old custom splash if it exists
|
||||
# Boot splash: handled by initramfs (archr-init with embedded BMP).
|
||||
# Initramfs displays splash at ~0.7s after kernel start, before systemd.
|
||||
# No systemd service needed — splash persists until ES takes DRM master.
|
||||
systemctl disable splash 2>/dev/null || true
|
||||
rm -f /etc/systemd/system/splash.service
|
||||
systemctl disable archr-splash 2>/dev/null || true
|
||||
rm -f /etc/systemd/system/splash.service /etc/systemd/system/archr-splash.service
|
||||
|
||||
# Battery LED warning service
|
||||
cat > /etc/systemd/system/battery-led.service << 'BATT_EOF'
|
||||
@@ -483,7 +511,129 @@ TIMING_EOF
|
||||
|
||||
systemctl enable boot-timing
|
||||
|
||||
# Delete initramfs (not used — extlinux.conf has no INITRD line)
|
||||
# Debug dump: comprehensive system info to /boot/debug.log (readable from PC)
|
||||
cat > /etc/systemd/system/archr-debug-dump.service << 'DEBUG_EOF'
|
||||
[Unit]
|
||||
Description=Arch R Debug Dump
|
||||
After=emulationstation.service
|
||||
After=multi-user.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash -c '\
|
||||
sleep 20; \
|
||||
{ \
|
||||
echo "=== Arch R Debug Dump ($(date)) ==="; \
|
||||
echo ""; \
|
||||
echo "--- Kernel ---"; \
|
||||
uname -a; \
|
||||
echo ""; \
|
||||
echo "--- Input Devices ---"; \
|
||||
for d in /dev/input/event*; do \
|
||||
name=$(cat /sys/class/input/$(basename $d)/device/name 2>/dev/null); \
|
||||
echo " $d: $name"; \
|
||||
done; \
|
||||
echo ""; \
|
||||
echo "--- DRM ---"; \
|
||||
for c in /sys/class/drm/card*/status; do \
|
||||
echo " $c: $(cat $c 2>/dev/null)"; \
|
||||
done; \
|
||||
cat /sys/class/drm/card*/modes 2>/dev/null | head -5; \
|
||||
echo ""; \
|
||||
echo "--- Backlight ---"; \
|
||||
for bl in /sys/class/backlight/*/; do \
|
||||
echo " $(basename $bl): cur=$(cat ${bl}brightness 2>/dev/null) max=$(cat ${bl}max_brightness 2>/dev/null)"; \
|
||||
done; \
|
||||
echo ""; \
|
||||
echo "--- ALSA Controls ---"; \
|
||||
amixer scontrols 2>/dev/null || echo " (no ALSA)"; \
|
||||
echo ""; \
|
||||
echo "--- CPU/GPU ---"; \
|
||||
echo " CPU: $(cat /sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq 2>/dev/null)kHz ($(cat /sys/devices/system/cpu/cpufreq/policy0/scaling_governor 2>/dev/null))"; \
|
||||
echo " GPU: $(cat /sys/devices/platform/ff400000.gpu/devfreq/ff400000.gpu/cur_freq 2>/dev/null)Hz"; \
|
||||
echo " Temp: $(cat /sys/class/thermal/thermal_zone0/temp 2>/dev/null)"; \
|
||||
echo ""; \
|
||||
echo "--- Memory ---"; \
|
||||
free -h; \
|
||||
echo ""; \
|
||||
echo "--- Loaded Modules ---"; \
|
||||
lsmod 2>/dev/null | head -30; \
|
||||
echo ""; \
|
||||
echo "--- Failed Services ---"; \
|
||||
systemctl --failed --no-pager 2>/dev/null; \
|
||||
echo ""; \
|
||||
echo "--- dmesg errors ---"; \
|
||||
dmesg -l err,warn 2>/dev/null | tail -30; \
|
||||
} > /boot/debug.log 2>&1; \
|
||||
chmod 644 /boot/debug.log'
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
DEBUG_EOF
|
||||
|
||||
systemctl enable archr-debug-dump
|
||||
|
||||
# USB auto-mount service (triggered by udev on device insertion)
|
||||
cat > /etc/systemd/system/archr-automount.service << 'AUTOMOUNT_SVC'
|
||||
[Unit]
|
||||
Description=Arch R USB Auto-Mount
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/archr-automount mount
|
||||
AUTOMOUNT_SVC
|
||||
|
||||
# Save config on shutdown (backs up ALSA state, brightness, WiFi to /boot)
|
||||
cat > /etc/systemd/system/archr-save-config.service << 'SAVECONF_SVC'
|
||||
[Unit]
|
||||
Description=Arch R Save Config
|
||||
DefaultDependencies=no
|
||||
Before=shutdown.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/bin/archr-save-config backup
|
||||
|
||||
[Install]
|
||||
WantedBy=shutdown.target
|
||||
SAVECONF_SVC
|
||||
|
||||
systemctl enable archr-save-config
|
||||
|
||||
# Bluetooth auto-pairing agent (runs alongside bluetoothd)
|
||||
cat > /etc/systemd/system/archr-bluetooth-agent.service << 'BTAGENT_SVC'
|
||||
[Unit]
|
||||
Description=Arch R Bluetooth Agent
|
||||
After=bluetooth.service
|
||||
PartOf=bluetooth.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/archr-bluetooth-agent
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=bluetooth.target
|
||||
BTAGENT_SVC
|
||||
|
||||
systemctl enable archr-bluetooth-agent
|
||||
|
||||
# Sleep configuration (suspend disabled by default, user enables via archr-suspend-mode)
|
||||
mkdir -p /etc/systemd/sleep.conf.d
|
||||
cat > /etc/systemd/sleep.conf.d/archr.conf << 'SLEEP_CONF'
|
||||
[Sleep]
|
||||
AllowSuspend=yes
|
||||
SuspendState=mem
|
||||
AllowHibernation=no
|
||||
SLEEP_CONF
|
||||
|
||||
# Modules blacklist for sleep (unloaded before suspend by archr-sleep hook)
|
||||
mkdir -p /etc/archr
|
||||
install -m 644 /tmp/modules.bad /etc/archr/modules.bad 2>/dev/null || true
|
||||
|
||||
# Delete stock ALARM initramfs and kernel (we use our own kernel + initramfs)
|
||||
# Our initramfs.img is built by build-image.sh and placed on BOOT partition
|
||||
rm -f /boot/initramfs-linux.img /boot/Image /boot/Image.gz 2>/dev/null
|
||||
|
||||
# Clean kernel modules: remove media tuners (154 modules, 13MB — useless for gaming)
|
||||
@@ -497,7 +647,7 @@ dd if=/dev/urandom of=/var/lib/systemd/random-seed bs=512 count=1 2>/dev/null
|
||||
chmod 600 /var/lib/systemd/random-seed
|
||||
|
||||
# Sudoers for perfmax/perfnorm/pmic-poweroff (allow archr to run without password)
|
||||
echo "archr ALL=(ALL) NOPASSWD: /usr/local/bin/perfmax, /usr/local/bin/perfnorm, /usr/local/bin/pmic-poweroff, /usr/bin/ln, /usr/bin/dmesg, /usr/bin/chvt, /usr/bin/cp, /usr/bin/chmod, /bin/bash" > /etc/sudoers.d/archr-perf
|
||||
echo "archr ALL=(ALL) NOPASSWD: /usr/local/bin/perfmax, /usr/local/bin/perfnorm, /usr/local/bin/pmic-poweroff, /usr/local/bin/input-merge, /usr/local/bin/archr-gptokeyb, /usr/local/bin/archr-factory-reset, /usr/local/bin/archr-suspend-mode, /usr/local/bin/archr-usbgadget, /usr/bin/kill, /usr/bin/ln, /usr/bin/dmesg, /usr/bin/chvt, /usr/bin/cp, /usr/bin/chmod, /usr/bin/tee, /usr/bin/systemctl, /bin/bash" > /etc/sudoers.d/archr-perf
|
||||
chmod 440 /etc/sudoers.d/archr-perf
|
||||
|
||||
# Allow archr to use negative nice values (needed for nice -n -19 in ES launch commands)
|
||||
@@ -548,8 +698,8 @@ cat > /etc/systemd/logind.conf.d/fast.conf << 'LOGIND_EOF'
|
||||
[Login]
|
||||
NAutoVTs=1
|
||||
ReserveVT=0
|
||||
HandlePowerKey=ignore
|
||||
HandleSuspendKey=ignore
|
||||
HandlePowerKey=suspend
|
||||
HandleSuspendKey=suspend
|
||||
HandleHibernateKey=ignore
|
||||
HandleLidSwitch=ignore
|
||||
KillUserProcesses=no
|
||||
@@ -645,6 +795,7 @@ for sock in \
|
||||
systemd-mute-console.socket systemd-bootctl.socket \
|
||||
systemd-creds.socket systemd-repart.socket \
|
||||
systemd-importd.socket systemd-machined.socket \
|
||||
systemd-hostnamed.socket \
|
||||
systemd-rfkill.socket dm-event.socket \
|
||||
systemd-coredump.socket systemd-sysext.socket \
|
||||
systemd-ask-password-wall.socket \
|
||||
@@ -672,6 +823,9 @@ for rule in 60-cdrom_id 60-dmi-id 60-fido-id 60-infiniband \
|
||||
ln -sf /dev/null "/etc/udev/rules.d/${rule}.rules"
|
||||
done
|
||||
|
||||
# Allow input group to use /dev/uinput (needed by archr-gptokeyb and input-merge)
|
||||
echo 'KERNEL=="uinput", GROUP="input", MODE="0660"' > /etc/udev/rules.d/99-archr-uinput.rules
|
||||
|
||||
# Pre-build caches NOW (inside chroot) so masks are safe
|
||||
ldconfig 2>/dev/null || true
|
||||
journalctl --update-catalog 2>/dev/null || true
|
||||
@@ -911,6 +1065,9 @@ chmod +x "$ROOTFS_DIR/tmp/setup.sh"
|
||||
# Copy libvlc stub into chroot (needed by bloat cleanup — ES links against libvlc.so.5)
|
||||
cp "$SCRIPT_DIR/scripts/libvlc-stub-aarch64.so" "$ROOTFS_DIR/tmp/libvlc-stub.so"
|
||||
|
||||
# Copy modules.bad into chroot (installed by setup.sh to /etc/archr/)
|
||||
cp "$SCRIPT_DIR/config/modules.bad" "$ROOTFS_DIR/tmp/modules.bad"
|
||||
|
||||
# Run setup inside chroot
|
||||
log " Running setup inside chroot..."
|
||||
chroot "$ROOTFS_DIR" /tmp/setup.sh
|
||||
@@ -928,8 +1085,32 @@ install -m 755 "$SCRIPT_DIR/scripts/perfmax" "$ROOTFS_DIR/usr/local/bin/perfmax"
|
||||
install -m 755 "$SCRIPT_DIR/scripts/perfnorm" "$ROOTFS_DIR/usr/local/bin/perfnorm"
|
||||
install -m 755 "$SCRIPT_DIR/scripts/pmic-poweroff" "$ROOTFS_DIR/usr/local/bin/pmic-poweroff"
|
||||
install -m 755 "$SCRIPT_DIR/scripts/retroarch-launch.sh" "$ROOTFS_DIR/usr/local/bin/retroarch-launch"
|
||||
# RetroArch joypad autoconfig (gpio-keys buttons + adc-joystick analog sticks)
|
||||
# RetroArch core options (per-core tuning for RK3326)
|
||||
install -m 644 "$SCRIPT_DIR/config/retroarch-core-options.cfg" "$ROOTFS_DIR/home/archr/.config/retroarch/retroarch-core-options.cfg"
|
||||
log " ✓ RetroArch core options installed"
|
||||
# Input merger daemon: combines gpio-keys + adc-joystick into single virtual device
|
||||
# RetroArch needs all inputs on one device (udev driver assigns each to separate port)
|
||||
if command -v aarch64-linux-gnu-gcc &>/dev/null; then
|
||||
aarch64-linux-gnu-gcc -static -O2 -o "$ROOTFS_DIR/usr/local/bin/input-merge" \
|
||||
"$SCRIPT_DIR/scripts/input-merge.c"
|
||||
chmod 755 "$ROOTFS_DIR/usr/local/bin/input-merge"
|
||||
log " ✓ input-merge compiled and installed"
|
||||
# Gamepad-to-keyboard mapper for Linux ports (compatible with ROCKNIX .gptk configs)
|
||||
aarch64-linux-gnu-gcc -static -O2 -o "$ROOTFS_DIR/usr/local/bin/archr-gptokeyb" \
|
||||
"$SCRIPT_DIR/scripts/archr-gptokeyb.c"
|
||||
chmod 755 "$ROOTFS_DIR/usr/local/bin/archr-gptokeyb"
|
||||
log " ✓ archr-gptokeyb compiled and installed"
|
||||
else
|
||||
warn "aarch64-linux-gnu-gcc not found — input-merge/gptokeyb not compiled"
|
||||
fi
|
||||
# gptokeyb config files
|
||||
mkdir -p "$ROOTFS_DIR/etc/archr/gptokeyb"
|
||||
install -m 644 "$SCRIPT_DIR/config/gptokeyb/default.gptk" "$ROOTFS_DIR/etc/archr/gptokeyb/default.gptk"
|
||||
install -m 644 "$SCRIPT_DIR/config/gptokeyb/tools.gptk" "$ROOTFS_DIR/etc/archr/gptokeyb/tools.gptk"
|
||||
log " ✓ gptokeyb configs installed (default + tools)"
|
||||
# RetroArch joypad autoconfig (merged device + individual fallbacks)
|
||||
mkdir -p "$ROOTFS_DIR/usr/share/retroarch/autoconfig/udev"
|
||||
install -m 644 "$SCRIPT_DIR/config/autoconfig/udev/archr-gamepad.cfg" "$ROOTFS_DIR/usr/share/retroarch/autoconfig/udev/"
|
||||
install -m 644 "$SCRIPT_DIR/config/autoconfig/udev/gpio-keys.cfg" "$ROOTFS_DIR/usr/share/retroarch/autoconfig/udev/"
|
||||
install -m 644 "$SCRIPT_DIR/config/autoconfig/udev/adc-joystick.cfg" "$ROOTFS_DIR/usr/share/retroarch/autoconfig/udev/"
|
||||
# systemd shutdown hook — runs pmic-poweroff at the very end of shutdown sequence
|
||||
@@ -948,6 +1129,40 @@ install -m 755 "$SCRIPT_DIR/scripts/timezones" "$ROOTFS_DIR/usr/local/bin/timezo
|
||||
install -m 755 "$SCRIPT_DIR/scripts/auto_suspend_update.sh" "$ROOTFS_DIR/usr/local/bin/auto_suspend_update.sh"
|
||||
log " ✓ ES compatibility scripts installed (timezones, auto_suspend_update.sh)"
|
||||
|
||||
# System management scripts
|
||||
install -m 755 "$SCRIPT_DIR/scripts/archr-automount" "$ROOTFS_DIR/usr/local/bin/archr-automount"
|
||||
install -m 755 "$SCRIPT_DIR/scripts/archr-usbgadget" "$ROOTFS_DIR/usr/local/bin/archr-usbgadget"
|
||||
install -m 755 "$SCRIPT_DIR/scripts/archr-bluetooth-agent" "$ROOTFS_DIR/usr/local/bin/archr-bluetooth-agent"
|
||||
install -m 755 "$SCRIPT_DIR/scripts/archr-factory-reset" "$ROOTFS_DIR/usr/local/bin/archr-factory-reset"
|
||||
install -m 755 "$SCRIPT_DIR/scripts/archr-suspend-mode" "$ROOTFS_DIR/usr/local/bin/archr-suspend-mode"
|
||||
install -m 755 "$SCRIPT_DIR/scripts/archr-save-config" "$ROOTFS_DIR/usr/local/bin/archr-save-config"
|
||||
install -m 755 "$SCRIPT_DIR/scripts/archr-memory-manager" "$ROOTFS_DIR/usr/local/bin/archr-memory-manager"
|
||||
log " ✓ System management scripts installed"
|
||||
|
||||
# System sleep hook (called by systemd on suspend/resume)
|
||||
mkdir -p "$ROOTFS_DIR/usr/lib/systemd/system-sleep"
|
||||
install -m 755 "$SCRIPT_DIR/scripts/archr-sleep" "$ROOTFS_DIR/usr/lib/systemd/system-sleep/archr-sleep"
|
||||
log " ✓ Sleep hook installed"
|
||||
|
||||
# ES Tools shared menu library (sourced by tool scripts)
|
||||
mkdir -p "$ROOTFS_DIR/usr/lib/archr"
|
||||
install -m 644 "$SCRIPT_DIR/scripts/opt-system/menu-lib.sh" "$ROOTFS_DIR/usr/lib/archr/menu-lib.sh"
|
||||
|
||||
# ES Tools menu scripts (shown in ES OPTIONS menu via GuiTools)
|
||||
mkdir -p "$ROOTFS_DIR/opt/system"
|
||||
for script in "$SCRIPT_DIR/scripts/opt-system/"*.sh; do
|
||||
[ -f "$script" ] || continue
|
||||
[ "$(basename "$script")" = "menu-lib.sh" ] && continue
|
||||
install -m 755 "$script" "$ROOTFS_DIR/opt/system/$(basename "$script")"
|
||||
done
|
||||
log " ✓ ES Tools menu scripts installed (/opt/system/)"
|
||||
|
||||
# Udev rules
|
||||
mkdir -p "$ROOTFS_DIR/etc/udev/rules.d"
|
||||
install -m 644 "$SCRIPT_DIR/config/udev/99-archr-automount.rules" "$ROOTFS_DIR/etc/udev/rules.d/99-archr-automount.rules"
|
||||
install -m 644 "$SCRIPT_DIR/config/udev/80-archr-usbgadget.rules" "$ROOTFS_DIR/etc/udev/rules.d/80-archr-usbgadget.rules"
|
||||
log " ✓ Udev rules installed (automount, usbgadget)"
|
||||
|
||||
# Install prebuilt libretro cores (not available in ALARM repos)
|
||||
PREBUILT_CORES="$SCRIPT_DIR/prebuilt/cores"
|
||||
if [ -d "$PREBUILT_CORES" ]; then
|
||||
@@ -968,6 +1183,9 @@ log " ✓ Distro version installed (text.plymouth)"
|
||||
install -m 755 "$SCRIPT_DIR/scripts/first-boot.sh" "$ROOTFS_DIR/usr/local/bin/first-boot.sh"
|
||||
log " ✓ First boot script installed"
|
||||
|
||||
# Boot splash: no binary needed in rootfs — splash is embedded in initramfs /init
|
||||
# (built by build-image.sh: archr-init.c + embedded splash BMP → initramfs.img)
|
||||
|
||||
# RetroArch config (install to user's config dir where retroarch expects it)
|
||||
mkdir -p "$ROOTFS_DIR/home/archr/.config/retroarch"
|
||||
cp "$SCRIPT_DIR/config/retroarch.cfg" "$ROOTFS_DIR/home/archr/.config/retroarch/retroarch.cfg"
|
||||
@@ -999,6 +1217,9 @@ log " ✓ Battery LED script installed"
|
||||
install -m 755 "$SCRIPT_DIR/scripts/archr-hotkeys.py" "$ROOTFS_DIR/usr/local/bin/archr-hotkeys.py"
|
||||
log " ✓ Hotkey daemon installed"
|
||||
|
||||
# Screenshots directory (used by MODE+B hotkey)
|
||||
mkdir -p "$ROOTFS_DIR/home/archr/screenshots"
|
||||
|
||||
# Fix ownership of archr home directory (files installed by root in Step 5)
|
||||
chown -R 1001:1001 "$ROOTFS_DIR/home/archr"
|
||||
log " ✓ archr home ownership fixed (UID 1001)"
|
||||
@@ -1012,18 +1233,22 @@ log "Step 6: Installing kernel and modules..."
|
||||
KERNEL_BOOT="$OUTPUT_DIR/boot"
|
||||
KERNEL_MODULES="$OUTPUT_DIR/modules/lib/modules"
|
||||
|
||||
if [ -f "$KERNEL_BOOT/Image" ]; then
|
||||
if [ -f "$KERNEL_BOOT/KERNEL" ]; then
|
||||
mkdir -p "$ROOTFS_DIR/boot"
|
||||
cp "$KERNEL_BOOT/Image" "$ROOTFS_DIR/boot/"
|
||||
log " ✓ Kernel Image installed"
|
||||
cp "$KERNEL_BOOT/KERNEL" "$ROOTFS_DIR/boot/"
|
||||
log " ✓ Kernel installed to rootfs/boot/"
|
||||
|
||||
# Copy R36S DTB
|
||||
for dtb in "$KERNEL_BOOT"/*.dtb; do
|
||||
[ -f "$dtb" ] && cp "$dtb" "$ROOTFS_DIR/boot/" && \
|
||||
log " ✓ DTB installed: $(basename "$dtb")"
|
||||
done
|
||||
# Copy board DTBs (build-image.sh handles BOOT partition separately)
|
||||
if [ -d "$KERNEL_BOOT/dtbs" ]; then
|
||||
mkdir -p "$ROOTFS_DIR/boot/dtbs"
|
||||
for dtb in "$KERNEL_BOOT/dtbs"/rk3326-*.dtb; do
|
||||
[ -f "$dtb" ] && cp "$dtb" "$ROOTFS_DIR/boot/dtbs/"
|
||||
done
|
||||
dtb_count=$(ls "$ROOTFS_DIR/boot/dtbs"/rk3326-*.dtb 2>/dev/null | wc -l)
|
||||
log " ✓ $dtb_count DTBs installed to rootfs/boot/dtbs/"
|
||||
fi
|
||||
else
|
||||
warn "Kernel Image not found. Run build-kernel.sh first!"
|
||||
warn "Kernel not found at $KERNEL_BOOT/KERNEL. Run build-kernel.sh first!"
|
||||
fi
|
||||
|
||||
if [ -d "$KERNEL_MODULES" ]; then
|
||||
|
||||
Executable
+174
@@ -0,0 +1,174 @@
|
||||
#!/bin/bash
|
||||
#==============================================================================
|
||||
# Arch R - Build Mainline U-Boot for R36S Clones
|
||||
#==============================================================================
|
||||
# Uses mainline U-Boot v2025.10 + RK3326 handheld patches
|
||||
# Produces: idbloader.img, uboot.img, trust.img (Rockchip format)
|
||||
#
|
||||
# Usage:
|
||||
# ./build-uboot-clone.sh [--uart5]
|
||||
#
|
||||
# --uart5: Build for K36 clones that use UART5 instead of UART2
|
||||
#==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
UBOOT_SRC="$SCRIPT_DIR/bootloader/u-boot-mainline"
|
||||
RKBIN_DIR="$SCRIPT_DIR/bootloader/rkbin"
|
||||
OUTPUT_DIR="$SCRIPT_DIR/bootloader/u-boot-clone-build"
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
log() { echo -e "${GREEN}[UBOOT-CLONE]${NC} $1"; }
|
||||
warn() { echo -e "${YELLOW}[UBOOT-CLONE] WARNING:${NC} $1"; }
|
||||
error() { echo -e "${RED}[UBOOT-CLONE] ERROR:${NC} $1"; exit 1; }
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Parse arguments
|
||||
#------------------------------------------------------------------------------
|
||||
UART5=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--uart5) UART5=1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Verify prerequisites
|
||||
#------------------------------------------------------------------------------
|
||||
CROSS_COMPILE="aarch64-linux-gnu-"
|
||||
|
||||
if ! command -v ${CROSS_COMPILE}gcc &>/dev/null; then
|
||||
error "Cross-compiler not found. Install: sudo apt install gcc-aarch64-linux-gnu"
|
||||
fi
|
||||
|
||||
if ! python3 -c "import elftools" 2>/dev/null; then
|
||||
error "pyelftools not found. Install: pip3 install pyelftools"
|
||||
fi
|
||||
|
||||
if ! command -v swig &>/dev/null; then
|
||||
error "swig not found. Install: sudo apt install swig"
|
||||
fi
|
||||
|
||||
[ -d "$UBOOT_SRC" ] || error "Mainline U-Boot source not found: $UBOOT_SRC"
|
||||
[ -d "$RKBIN_DIR" ] || error "rkbin not found: $RKBIN_DIR"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Rockchip firmware binaries
|
||||
#------------------------------------------------------------------------------
|
||||
PKG_DDR_BIN="$RKBIN_DIR/bin/rk33/rk3326_ddr_333MHz_v2.11.bin"
|
||||
PKG_MINILOADER="$RKBIN_DIR/bin/rk33/rk3326_miniloader_v1.40.bin"
|
||||
PKG_BL31="$RKBIN_DIR/bin/rk33/rk3326_bl31_v1.34.elf"
|
||||
|
||||
[ -f "$PKG_DDR_BIN" ] || error "DDR binary not found: $PKG_DDR_BIN"
|
||||
[ -f "$PKG_MINILOADER" ] || error "Miniloader not found: $PKG_MINILOADER"
|
||||
[ -f "$PKG_BL31" ] || error "BL31 not found: $PKG_BL31"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# UART5 DDR binary (for K36 clones)
|
||||
#------------------------------------------------------------------------------
|
||||
if [ "$UART5" -eq 1 ]; then
|
||||
log "Building UART5 variant for K36 clones"
|
||||
PKG_DDR_BIN_UART5="$RKBIN_DIR/rk3326_ddr_uart5.bin"
|
||||
|
||||
if [ ! -f "$PKG_DDR_BIN_UART5" ]; then
|
||||
log "Creating UART5-tuned DDR binary..."
|
||||
DDRBIN_TOOL="$RKBIN_DIR/tools/ddrbin_tool"
|
||||
if [ ! -x "$DDRBIN_TOOL" ]; then
|
||||
error "ddrbin_tool not found or not executable: $DDRBIN_TOOL"
|
||||
fi
|
||||
cp "$PKG_DDR_BIN" "$PKG_DDR_BIN_UART5"
|
||||
"$DDRBIN_TOOL" rk3326 -g "$RKBIN_DIR/rk3326_ddr_uart5.txt" "$PKG_DDR_BIN_UART5"
|
||||
sed -i 's|uart id=.*$|uart id=5|' "$RKBIN_DIR/rk3326_ddr_uart5.txt"
|
||||
"$DDRBIN_TOOL" rk3326 "$RKBIN_DIR/rk3326_ddr_uart5.txt" "$PKG_DDR_BIN_UART5" >/dev/null
|
||||
log "UART5 DDR binary created"
|
||||
fi
|
||||
PKG_DDR_BIN="$PKG_DDR_BIN_UART5"
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Build U-Boot
|
||||
#------------------------------------------------------------------------------
|
||||
JOBS=$(nproc)
|
||||
DEFCONFIG="rk3326-handheld_defconfig"
|
||||
|
||||
log "=== Building Mainline U-Boot v2025.10 for R36S Clone ==="
|
||||
log "Cross-compiler: $(${CROSS_COMPILE}gcc --version | head -1)"
|
||||
log "Defconfig: $DEFCONFIG"
|
||||
log "Jobs: $JOBS"
|
||||
[ "$UART5" -eq 1 ] && log "UART: UART5 (0xFF178000)" || log "UART: UART2 (0xFF160000)"
|
||||
|
||||
cd "$UBOOT_SRC"
|
||||
|
||||
log "Step 1: Clean..."
|
||||
make CROSS_COMPILE="$CROSS_COMPILE" ARCH=arm mrproper 2>&1 | tail -1
|
||||
|
||||
log "Step 2: Configure..."
|
||||
make CROSS_COMPILE="$CROSS_COMPILE" ARCH=arm "$DEFCONFIG" 2>&1 | tail -1
|
||||
|
||||
# UART5 variant: override config
|
||||
if [ "$UART5" -eq 1 ]; then
|
||||
./scripts/config --set-val CONFIG_DEBUG_UART_BASE 0xFF178000
|
||||
./scripts/config --set-str CONFIG_DEVICE_TREE_INCLUDES "rk3326-odroid-go2-emmc.dtsi rk3326-odroid-go2-uart5.dtsi"
|
||||
log "UART5 config applied"
|
||||
fi
|
||||
|
||||
log "Step 3: Compile..."
|
||||
make CROSS_COMPILE="$CROSS_COMPILE" ARCH=arm -j"$JOBS" u-boot-dtb.bin 2>&1 | tail -20
|
||||
|
||||
[ -f "u-boot-dtb.bin" ] || error "Build failed: u-boot-dtb.bin not found"
|
||||
log "u-boot-dtb.bin built: $(du -h u-boot-dtb.bin | cut -f1)"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Package: idbloader.img
|
||||
#------------------------------------------------------------------------------
|
||||
log "Step 4: Creating idbloader.img..."
|
||||
"$UBOOT_SRC/tools/mkimage" -n px30 -T rksd -d "$PKG_DDR_BIN" -C bzip2 idbloader.img
|
||||
cat "$PKG_MINILOADER" >> idbloader.img
|
||||
log "idbloader.img: $(du -h idbloader.img | cut -f1)"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Package: uboot.img
|
||||
#------------------------------------------------------------------------------
|
||||
log "Step 5: Creating uboot.img..."
|
||||
"$RKBIN_DIR/tools/loaderimage" --pack --uboot u-boot-dtb.bin uboot.img 0x00200000 2>&1 | tail -3
|
||||
log "uboot.img: $(du -h uboot.img | cut -f1)"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Package: trust.img
|
||||
#------------------------------------------------------------------------------
|
||||
log "Step 6: Creating trust.img..."
|
||||
cat >trust.ini <<EOF
|
||||
[BL30_OPTION]
|
||||
SEC=0
|
||||
[BL31_OPTION]
|
||||
SEC=1
|
||||
PATH=${PKG_BL31}
|
||||
ADDR=0x00010000
|
||||
[BL32_OPTION]
|
||||
SEC=0
|
||||
[BL33_OPTION]
|
||||
SEC=0
|
||||
[OUTPUT]
|
||||
PATH=trust.img
|
||||
EOF
|
||||
"$RKBIN_DIR/tools/trust_merger" --verbose trust.ini 2>&1 | tail -5
|
||||
log "trust.img: $(du -h trust.img | cut -f1)"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Copy to output directory
|
||||
#------------------------------------------------------------------------------
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
cp idbloader.img uboot.img trust.img "$OUTPUT_DIR/"
|
||||
|
||||
log ""
|
||||
log "=== Build Complete ==="
|
||||
log "Output: $OUTPUT_DIR/"
|
||||
ls -lh "$OUTPUT_DIR/"*.img
|
||||
log ""
|
||||
log "Flash with:"
|
||||
log " ./flash-uboot-clone.sh /dev/sdX"
|
||||
+129
-53
@@ -1,90 +1,164 @@
|
||||
#!/bin/bash
|
||||
|
||||
#==============================================================================
|
||||
# Arch R - Build U-Boot for R36S
|
||||
# Arch R - Build U-Boot BSP for RK3326
|
||||
#==============================================================================
|
||||
# Builds U-Boot bootloader for RK3326 (R36S/RG351MP compatible)
|
||||
# Builds U-Boot v2017.09 BSP for all RK3326 handhelds.
|
||||
# Same binary works for both original and clone boards — hwrev.c detects
|
||||
# board variant via SARADC ch0, boot.ini overrides DTB as needed.
|
||||
#
|
||||
# Output: bootloader/u-boot-rk3326/sd_fuse/
|
||||
# idbloader.img — DDR init + miniloader
|
||||
# uboot.img — U-Boot proper
|
||||
# trust.img — ARM Trusted Firmware (BL31 + BL32)
|
||||
#
|
||||
# Usage:
|
||||
# ./build-uboot.sh # build for SD card
|
||||
# ./build-uboot.sh --clean # clean build artifacts first
|
||||
#==============================================================================
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
UBOOT_DIR="$SCRIPT_DIR/bootloader/u-boot-rk3326"
|
||||
RKBIN_DIR="$SCRIPT_DIR/bootloader/rkbin"
|
||||
OUTPUT_DIR="$UBOOT_DIR/sd_fuse"
|
||||
|
||||
# Firmware versions (from rkbin)
|
||||
DDR_BIN="$RKBIN_DIR/bin/rk33/rk3326_ddr_333MHz_v2.11.bin"
|
||||
MINILOADER_BIN="$RKBIN_DIR/bin/rk33/rk3326_miniloader_v1.40.bin"
|
||||
BL31_ELF="$RKBIN_DIR/bin/rk33/rk3326_bl31_v1.34.elf"
|
||||
BL32_BIN="$RKBIN_DIR/bin/rk33/rk3326_bl32_v2.19.bin"
|
||||
|
||||
# Colors
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
log() { echo -e "${GREEN}[$(date '+%H:%M:%S')]${NC} $1"; }
|
||||
warn() { echo -e "${YELLOW}[$(date '+%H:%M:%S')] WARNING:${NC} $1"; }
|
||||
error() { echo -e "${RED}[$(date '+%H:%M:%S')] ERROR:${NC} $1"; exit 1; }
|
||||
log() { echo -e "${GREEN}[U-BOOT]${NC} $1"; }
|
||||
warn() { echo -e "${YELLOW}[U-BOOT] WARNING:${NC} $1"; }
|
||||
error() { echo -e "${RED}[U-BOOT] ERROR:${NC} $1"; exit 1; }
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Configuration
|
||||
# Parse arguments
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
UBOOT_DIR="$SCRIPT_DIR/bootloader"
|
||||
UBOOT_REPO="https://github.com/christianhaitian/RG351MP-u-boot"
|
||||
UBOOT_SRC="$UBOOT_DIR/u-boot-rk3326"
|
||||
OUTPUT_DIR="$SCRIPT_DIR/output/bootloader"
|
||||
|
||||
log "=== Arch R - Build U-Boot ==="
|
||||
CLEAN=false
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--clean) CLEAN=true; shift ;;
|
||||
*) error "Unknown option: $1\nUsage: $0 [--clean]" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 1: Clone U-Boot
|
||||
# Prerequisites
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 1: Checking U-Boot source..."
|
||||
log "=== Arch R U-Boot Builder ==="
|
||||
|
||||
mkdir -p "$UBOOT_DIR"
|
||||
|
||||
if [ ! -d "$UBOOT_SRC" ]; then
|
||||
log " Cloning U-Boot for RK3326..."
|
||||
git clone --depth 1 "$UBOOT_REPO" "$UBOOT_SRC"
|
||||
log " ✓ U-Boot cloned"
|
||||
else
|
||||
log " ✓ U-Boot source exists"
|
||||
if ! command -v aarch64-linux-gnu-gcc &>/dev/null; then
|
||||
error "Cross-compiler not found. Install with: sudo apt install gcc-aarch64-linux-gnu"
|
||||
fi
|
||||
|
||||
cd "$UBOOT_SRC"
|
||||
if [ ! -d "$UBOOT_DIR" ]; then
|
||||
error "U-Boot source not found at: $UBOOT_DIR"
|
||||
fi
|
||||
|
||||
if [ ! -f "$DDR_BIN" ]; then
|
||||
error "rkbin firmware not found at: $RKBIN_DIR\nExpected: $DDR_BIN"
|
||||
fi
|
||||
|
||||
GCC_VER=$(aarch64-linux-gnu-gcc -dumpversion)
|
||||
log "Compiler: aarch64-linux-gnu-gcc $GCC_VER"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 2: Build U-Boot
|
||||
# Clean (optional)
|
||||
#------------------------------------------------------------------------------
|
||||
if [ "$CLEAN" = true ]; then
|
||||
log "Cleaning previous build..."
|
||||
make -C "$UBOOT_DIR" distclean 2>/dev/null || true
|
||||
rm -rf "$OUTPUT_DIR"
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Build U-Boot
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 1: Configuring (odroidgoa_defconfig)..."
|
||||
|
||||
cd "$UBOOT_DIR"
|
||||
|
||||
# GCC 13+ needs these warnings suppressed for 2017.09 codebase
|
||||
export KCFLAGS="-Wno-error=array-bounds -Wno-error=enum-int-mismatch -Wno-error=implicit-function-declaration -Wno-error=format-overflow"
|
||||
|
||||
make odroidgoa_defconfig 2>&1 | tail -3
|
||||
|
||||
log "Step 2: Building U-Boot..."
|
||||
NCPUS=$(nproc 2>/dev/null || echo 4)
|
||||
make CROSS_COMPILE=aarch64-linux-gnu- all --jobs=$NCPUS 2>&1 | tail -5
|
||||
|
||||
# Set up cross-compiler (use Linaro if available, otherwise system)
|
||||
if [ -d "/opt/toolchains/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu" ]; then
|
||||
export PATH=/opt/toolchains/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin:$PATH
|
||||
if [ ! -f "u-boot.bin" ]; then
|
||||
error "Build failed — u-boot.bin not found"
|
||||
fi
|
||||
|
||||
export ARCH=arm64
|
||||
export CROSS_COMPILE=aarch64-linux-gnu-
|
||||
|
||||
# Build for OdroidGoA (compatible with R36S/RG351MP)
|
||||
./make.sh odroidgoa 2>&1 | tail -20 || true
|
||||
|
||||
log " ✓ U-Boot built"
|
||||
log " u-boot.bin built OK"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Step 3: Copy artifacts
|
||||
# Pack images
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 3: Copying bootloader files..."
|
||||
log "Step 3: Packing images..."
|
||||
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
# Copy the bootloader images
|
||||
if [ -d "sd_fuse" ]; then
|
||||
cp sd_fuse/idbloader.img "$OUTPUT_DIR/"
|
||||
cp sd_fuse/uboot.img "$OUTPUT_DIR/"
|
||||
cp sd_fuse/trust.img "$OUTPUT_DIR/"
|
||||
log " ✓ Bootloader files copied"
|
||||
else
|
||||
error "sd_fuse directory not found - U-Boot build may have failed"
|
||||
fi
|
||||
# idbloader.img = DDR init + miniloader
|
||||
"$UBOOT_DIR/tools/mkimage" -n px30 -T rksd -d "$DDR_BIN" "$OUTPUT_DIR/idbloader.img"
|
||||
cat "$MINILOADER_BIN" >> "$OUTPUT_DIR/idbloader.img"
|
||||
log " idbloader.img (DDR v2.11 + miniloader v1.40)"
|
||||
|
||||
# uboot.img = packed U-Boot binary
|
||||
UBOOT_LOAD_ADDR=$(grep -r "CONFIG_SYS_TEXT_BASE" include/autoconf.mk 2>/dev/null | cut -d= -f2 || echo "0x00200000")
|
||||
"$RKBIN_DIR/tools/loaderimage" --pack --uboot u-boot.bin "$OUTPUT_DIR/uboot.img" "$UBOOT_LOAD_ADDR" 2>&1 | tail -1
|
||||
log " uboot.img (load addr: $UBOOT_LOAD_ADDR)"
|
||||
|
||||
# trust.img = BL31 + BL32
|
||||
cat > /tmp/archr-trust.ini << TRUST_EOF
|
||||
[VERSION]
|
||||
MAJOR=1
|
||||
MINOR=0
|
||||
[BL30_OPTION]
|
||||
SEC=0
|
||||
[BL31_OPTION]
|
||||
SEC=1
|
||||
PATH=$BL31_ELF
|
||||
ADDR=0x00010000
|
||||
[BL32_OPTION]
|
||||
SEC=1
|
||||
PATH=$BL32_BIN
|
||||
ADDR=0x08400000
|
||||
[BL33_OPTION]
|
||||
SEC=0
|
||||
[OUTPUT]
|
||||
PATH=$OUTPUT_DIR/trust.img
|
||||
TRUST_EOF
|
||||
|
||||
"$RKBIN_DIR/tools/trust_merger" --rsa 3 /tmp/archr-trust.ini 2>&1 | tail -1
|
||||
rm -f /tmp/archr-trust.ini
|
||||
log " trust.img (BL31 v1.34 + BL32 v2.19)"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Verify
|
||||
#------------------------------------------------------------------------------
|
||||
log ""
|
||||
log "Step 4: Verifying..."
|
||||
|
||||
for img in idbloader.img uboot.img trust.img; do
|
||||
if [ ! -f "$OUTPUT_DIR/$img" ]; then
|
||||
error "Missing: $OUTPUT_DIR/$img"
|
||||
fi
|
||||
SIZE=$(du -h "$OUTPUT_DIR/$img" | cut -f1)
|
||||
log " $img ($SIZE)"
|
||||
done
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Summary
|
||||
@@ -92,9 +166,11 @@ fi
|
||||
log ""
|
||||
log "=== U-Boot Build Complete ==="
|
||||
log ""
|
||||
log "Bootloader files:"
|
||||
ls -la "$OUTPUT_DIR/"
|
||||
log "Output: $OUTPUT_DIR/"
|
||||
log " idbloader.img — DDR v2.11 + miniloader v1.40"
|
||||
log " uboot.img — U-Boot v2017.09 BSP"
|
||||
log " trust.img — BL31 v1.34 + BL32 v2.19"
|
||||
log ""
|
||||
log "These will be automatically installed by build-image.sh"
|
||||
log ""
|
||||
log "✓ U-Boot ready for R36S!"
|
||||
log "Same binary for both original and clone images."
|
||||
log "Board detection: hwrev.c (SARADC ch0)"
|
||||
log "DTB selection: boot.ini (variant A or B)"
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
odroidgoa-uboot-config
|
||||
|
||||
########################################################################
|
||||
# Arch R Boot Configuration — Variant A (BSP U-Boot)
|
||||
#
|
||||
# For: Original R36S, OGA, OGA v1.1, OGS, R33S, RG351V, RG351M,
|
||||
# GameForce Chi, MagicX XU10
|
||||
#
|
||||
# BSP U-Boot reads this file directly.
|
||||
# hwrev is set by BSP's hwrev.c from SARADC ch0 before this runs.
|
||||
#
|
||||
# We ALWAYS load our DTB from partition (not U-Boot embedded) because
|
||||
# our DTBs have archr-* compatible strings for joypad/panel drivers.
|
||||
########################################################################
|
||||
|
||||
# Memory addresses
|
||||
setenv loadaddr "0x02000000"
|
||||
setenv dtb_loadaddr "0x01f00000"
|
||||
setenv dtbo_loadaddr "0x01e00000"
|
||||
|
||||
# Load kernel
|
||||
load mmc 1:1 ${loadaddr} KERNEL
|
||||
|
||||
# Map hwrev to board DTB (always load from partition)
|
||||
if test ${hwrev} = 'v10-go3'; then
|
||||
load mmc 1:1 ${dtb_loadaddr} dtbs/rk3326-odroid-go3.dtb
|
||||
elif test ${hwrev} = 'r33s'; then
|
||||
load mmc 1:1 ${dtb_loadaddr} dtbs/rk3326-gameconsole-r33s.dtb
|
||||
elif test ${hwrev} = 'chi'; then
|
||||
load mmc 1:1 ${dtb_loadaddr} dtbs/rk3326-gameforce-chi.dtb
|
||||
elif test ${hwrev} = 'rg351v'; then
|
||||
gpio input b6
|
||||
if test $? -eq 0; then
|
||||
load mmc 1:1 ${dtb_loadaddr} dtbs/rk3326-anbernic-rg351v.dtb
|
||||
else
|
||||
load mmc 1:1 ${dtb_loadaddr} dtbs/rk3326-gameconsole-r36s.dtb
|
||||
fi
|
||||
elif test ${hwrev} = 'v11'; then
|
||||
load mmc 1:1 ${dtb_loadaddr} dtbs/rk3326-odroid-go2-v11.dtb
|
||||
elif test ${hwrev} = 'v10'; then
|
||||
load mmc 1:1 ${dtb_loadaddr} dtbs/rk3326-odroid-go2.dtb
|
||||
elif test ${hwrev} = 'xu10'; then
|
||||
load mmc 1:1 ${dtb_loadaddr} dtbs/rk3326-magicx-xu10.dtb
|
||||
else
|
||||
load mmc 1:1 ${dtb_loadaddr} dtbs/rk3326-odroid-go2.dtb
|
||||
fi
|
||||
|
||||
# Apply panel overlay
|
||||
if load mmc 1:1 ${dtbo_loadaddr} overlays/mipi-panel.dtbo; then
|
||||
fdt addr ${dtb_loadaddr}
|
||||
fdt resize 8192
|
||||
fdt apply ${dtbo_loadaddr}
|
||||
fi
|
||||
|
||||
# Boot
|
||||
setenv bootargs "boot=LABEL=BOOT disk=LABEL=STORAGE rw console=ttyS2,115200 console=tty0 quiet loglevel=0 vt.global_cursor_default=0 consoleblank=0 fsck.mode=skip"
|
||||
booti ${loadaddr} - ${dtb_loadaddr}
|
||||
|
||||
# Power off if boot fails
|
||||
sleep 15
|
||||
poweroff
|
||||
@@ -67,16 +67,19 @@ CONFIG_DRM_PANFROST=m
|
||||
|
||||
# ============================================================
|
||||
# Framebuffer: fb0 via DRM emulation + fbcon
|
||||
# DEFERRED_TAKEOVER=y: fbcon waits for text output before clearing
|
||||
# screen. With quiet+ttyFIQ0, U-Boot logo persists until Plymouth
|
||||
# takes DRM master. Plymouth handles splash via KMS/DRM natively.
|
||||
# DEFERRED_TAKEOVER DISABLED: With deferred takeover, fbcon does
|
||||
# NOT trigger DRM modeset until text is written to console.
|
||||
# On clone R36S (mainline U-Boot, no BSP display init), this
|
||||
# means display stays BLACK. ROCKNIX explicitly disables this.
|
||||
# FRAMEBUFFER_CONSOLE_ROTATION: Display rotation support.
|
||||
# ============================================================
|
||||
CONFIG_DRM_FBDEV_EMULATION=y
|
||||
CONFIG_DRM_FBDEV_OVERALLOC=200
|
||||
CONFIG_FB=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
|
||||
# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set
|
||||
# CONFIG_LOGO is not set
|
||||
|
||||
# ============================================================
|
||||
@@ -209,6 +212,11 @@ CONFIG_DEBUG_INFO_NONE=y
|
||||
# CONFIG_MEDIA_TEST_SUPPORT is not set
|
||||
# CONFIG_DVB_CORE is not set
|
||||
|
||||
# ============================================================
|
||||
# Panel driver: Arch R Generic DSI (panel_description strings)
|
||||
# ============================================================
|
||||
CONFIG_DRM_PANEL_ARCHR_DSI=y
|
||||
|
||||
# ============================================================
|
||||
# SIZE TRIM: Display drivers — R36S uses ONLY MIPI DSI (~500KB-1MB)
|
||||
# ============================================================
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# Arch R fragment — applied on top of ROCKNIX base config
|
||||
# Only contains overrides specific to Arch Linux
|
||||
|
||||
# Initramfs: embedded in kernel (path set by build-kernel.sh)
|
||||
# CONFIG_INITRAMFS_SOURCE is set dynamically
|
||||
|
||||
# Compression
|
||||
CONFIG_INITRAMFS_COMPRESSION_GZIP=y
|
||||
CONFIG_INITRAMFS_ROOT_UID=0
|
||||
CONFIG_INITRAMFS_ROOT_GID=0
|
||||
@@ -0,0 +1,73 @@
|
||||
# Arch R Gamepad (merged gpio-keys + adc-joystick)
|
||||
# Created by input-merge daemon — combines buttons and analog sticks
|
||||
# into a single virtual device for RetroArch.
|
||||
|
||||
input_driver = "udev"
|
||||
input_device = "Arch R Gamepad"
|
||||
input_device_display_name = "Arch R Gamepad"
|
||||
|
||||
# Face buttons
|
||||
input_b_btn = "0"
|
||||
input_a_btn = "1"
|
||||
input_y_btn = "2"
|
||||
input_x_btn = "3"
|
||||
|
||||
# Shoulders
|
||||
input_l_btn = "4"
|
||||
input_r_btn = "5"
|
||||
input_l2_btn = "6"
|
||||
input_r2_btn = "7"
|
||||
|
||||
# Select / Start / Hotkey
|
||||
input_select_btn = "8"
|
||||
input_start_btn = "9"
|
||||
input_enable_hotkey_btn = "10"
|
||||
|
||||
# Thumbstick clicks
|
||||
input_l3_btn = "11"
|
||||
input_r3_btn = "12"
|
||||
|
||||
# D-Pad
|
||||
input_up_btn = "13"
|
||||
input_down_btn = "14"
|
||||
input_left_btn = "15"
|
||||
input_right_btn = "16"
|
||||
|
||||
# Left analog stick
|
||||
input_l_x_plus_axis = "+0"
|
||||
input_l_x_minus_axis = "-0"
|
||||
input_l_y_plus_axis = "+1"
|
||||
input_l_y_minus_axis = "-1"
|
||||
|
||||
# Right analog stick
|
||||
input_r_x_plus_axis = "+2"
|
||||
input_r_x_minus_axis = "-2"
|
||||
input_r_y_plus_axis = "+3"
|
||||
input_r_y_minus_axis = "-3"
|
||||
|
||||
# Labels
|
||||
input_b_btn_label = "B"
|
||||
input_a_btn_label = "A"
|
||||
input_y_btn_label = "Y"
|
||||
input_x_btn_label = "X"
|
||||
input_l_btn_label = "L1"
|
||||
input_r_btn_label = "R1"
|
||||
input_l2_btn_label = "L2"
|
||||
input_r2_btn_label = "R2"
|
||||
input_select_btn_label = "Select"
|
||||
input_start_btn_label = "Start"
|
||||
input_enable_hotkey_btn_label = "Mode"
|
||||
input_l3_btn_label = "L3"
|
||||
input_r3_btn_label = "R3"
|
||||
input_up_btn_label = "D-Pad Up"
|
||||
input_down_btn_label = "D-Pad Down"
|
||||
input_left_btn_label = "D-Pad Left"
|
||||
input_right_btn_label = "D-Pad Right"
|
||||
input_l_x_plus_axis_label = "LS Right"
|
||||
input_l_x_minus_axis_label = "LS Left"
|
||||
input_l_y_plus_axis_label = "LS Down"
|
||||
input_l_y_minus_axis_label = "LS Up"
|
||||
input_r_x_plus_axis_label = "RS Right"
|
||||
input_r_x_minus_axis_label = "RS Left"
|
||||
input_r_y_plus_axis_label = "RS Down"
|
||||
input_r_y_minus_axis_label = "RS Up"
|
||||
@@ -0,0 +1,48 @@
|
||||
odroidgoa-uboot-config
|
||||
|
||||
########################################################################
|
||||
# Arch R Boot Configuration — Variant B (Clone boards)
|
||||
#
|
||||
# For: K36 clones, Powkiddy RGB20S, Powkiddy RGB10X, MagicX XU-Mini-M
|
||||
#
|
||||
# hwrev is set by U-Boot's board file from SARADC ch0 before this runs.
|
||||
# This script overrides the kernel DTB for boards that need a different
|
||||
# DTB than what U-Boot loaded internally.
|
||||
#
|
||||
# hwrev mappings (clone boards):
|
||||
# r33s = Powkiddy RGB10X (shares ADC range with R33S)
|
||||
# xu10 = MagicX XU-Mini-M (shares ADC range with XU10)
|
||||
# rg351v = K36 clone / R36Max / EE clone boards
|
||||
########################################################################
|
||||
|
||||
# Memory addresses
|
||||
setenv loadaddr "0x02000000"
|
||||
setenv dtb_loadaddr "0x01f00000"
|
||||
setenv dtbo_loadaddr "0x01e00000"
|
||||
|
||||
# Load kernel
|
||||
load mmc 1:1 ${loadaddr} KERNEL
|
||||
|
||||
# Override DTB for clone boards
|
||||
if test ${hwrev} = 'r33s'; then
|
||||
load mmc 1:1 ${dtb_loadaddr} dtbs/rk3326-powkiddy-rgb10x.dtb
|
||||
elif test ${hwrev} = 'xu10'; then
|
||||
load mmc 1:1 ${dtb_loadaddr} dtbs/rk3326-magicx-xu-mini-m.dtb
|
||||
elif test ${hwrev} = 'rg351v'; then
|
||||
load mmc 1:1 ${dtb_loadaddr} dtbs/rk3326-gameconsole-r36max.dtb
|
||||
fi
|
||||
|
||||
# Apply panel overlay
|
||||
if load mmc 1:1 ${dtbo_loadaddr} overlays/mipi-panel.dtbo; then
|
||||
fdt addr ${dtb_loadaddr}
|
||||
fdt resize 8192
|
||||
fdt apply ${dtbo_loadaddr}
|
||||
fi
|
||||
|
||||
# Boot
|
||||
setenv bootargs "boot=LABEL=BOOT disk=LABEL=STORAGE rw console=ttyS2,115200 console=tty0 quiet loglevel=0 vt.global_cursor_default=0 consoleblank=0 fsck.mode=skip"
|
||||
booti ${loadaddr} - ${dtb_loadaddr}
|
||||
|
||||
# Power off if boot fails
|
||||
sleep 15
|
||||
poweroff
|
||||
@@ -1,28 +0,0 @@
|
||||
ODROIDGOA-UBOOT-CONFIG
|
||||
|
||||
########################################################################
|
||||
# Arch R Boot Configuration for R36S — Kernel 6.6 + Systemd
|
||||
# Default panel: Panel 4-V22 (hardcoded in base DTB, no overlay needed)
|
||||
# Primary boot: extlinux/extlinux.conf (U-Boot tries it first)
|
||||
# This boot.ini is a fallback if extlinux is missing.
|
||||
########################################################################
|
||||
|
||||
# Memory addresses — kernel at 0x02008000 (matches working R36S firmware)
|
||||
setenv dtb_loadaddr "0x01f00000"
|
||||
setenv loadaddr "0x02008000"
|
||||
|
||||
# Load kernel Image
|
||||
if load mmc 1:1 ${loadaddr} Image
|
||||
then
|
||||
# Load DTB
|
||||
if load mmc 1:1 ${dtb_loadaddr} rk3326-gameconsole-r36s.dtb
|
||||
then
|
||||
# Boot without initrd — use device path directly
|
||||
setenv bootargs "root=/dev/mmcblk1p2 rootwait rw console=ttyFIQ0 loglevel=0 quiet vt.global_cursor_default=0 consoleblank=0 printk.devkmsg=off fsck.mode=skip"
|
||||
booti ${loadaddr} - ${dtb_loadaddr}
|
||||
fi
|
||||
fi
|
||||
|
||||
# Power off if boot fails
|
||||
sleep 15
|
||||
poweroff
|
||||
@@ -0,0 +1,36 @@
|
||||
# Arch R — Default gamepad-to-keyboard mapping
|
||||
# Used by archr-gptokeyb for Linux ports that need keyboard input.
|
||||
# Per-game overrides: /etc/archr/gptokeyb/<game>.gptk
|
||||
# Format: button_name = key_name (compatible with ROCKNIX .gptk)
|
||||
|
||||
# Action buttons
|
||||
a = space
|
||||
b = backspace
|
||||
x = c
|
||||
y = v
|
||||
|
||||
# Shoulder buttons
|
||||
l1 = a
|
||||
r1 = s
|
||||
l2 = q
|
||||
r2 = e
|
||||
|
||||
# Menu
|
||||
back = esc
|
||||
start = enter
|
||||
guide = f1
|
||||
|
||||
# D-pad
|
||||
up = up
|
||||
down = down
|
||||
left = left
|
||||
right = right
|
||||
|
||||
# Left analog → mouse movement
|
||||
left_analog_as_mouse = true
|
||||
|
||||
# Right analog → arrow keys
|
||||
right_analog_up = up
|
||||
right_analog_down = down
|
||||
right_analog_left = left
|
||||
right_analog_right = right
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user