Skip to content

WIP: Add Seeed Studio reComputer RK3576/RK3588 DevKit support#9719

Draft
baorepo wants to merge 32 commits intoarmbian:mainfrom
Seeed-Studio:main
Draft

WIP: Add Seeed Studio reComputer RK3576/RK3588 DevKit support#9719
baorepo wants to merge 32 commits intoarmbian:mainfrom
Seeed-Studio:main

Conversation

@baorepo
Copy link
Copy Markdown

@baorepo baorepo commented Apr 24, 2026

Summary

Add board support for Seeed Studio's reComputer RK3576 DevKit and reComputer RK3588 DevKit to the Armbian build framework. These are industrial-grade single-board computers based on Rockchip RK3576 (octa-core A72/A53) and RK3588 (octa-core A76/A55) SoCs, targeting edge AI and IoT applications.

Board Support

  • reComputer RK3576 DevKit (config/boards/recomputer-rk3576-devkit.conf): RK3576 SoC, BOARDFAMILY=rk35xx, vendor kernel, custom bootscript, PCA953X GPIO expander, AD5398 DAC for fan control, X11 KMS on card0, ES8311 audio codec
  • reComputer RK3588 DevKit (config/boards/recomputer-rk3588-devkit.conf): RK3588 SoC, BOARDFAMILY=rockchip-rk3588, vendor kernel, custom bootscript, Mali-G610 GPU (libmali), Realtek r8125 Ethernet DKMS, multi-display audio naming (HDMI0/HDMI1/HDMI-In/DP0/ES8311)
  • Shared configuration (config/boards/recomputer-rk35xx-common.inc): Extracted ~300 lines of common hooks covering wireless, Bluetooth, USB gadget, security hardening, PATH, and OTA support. BT UART selection uses ${BOOT_SOC} case branching (rk3576→ttyS4, rk3588→ttyS6)

Hardware Support

  • Wireless: AIC8800 SDIO WiFi/BT with custom modprobe options and module loading; Morse FGH100M WiFi (HaLow) firmware and tools via GitHub releases
  • Bluetooth: Custom bluez package for FCS960K headset support; AIC8800 BT UART service with SoC-specific serial port selection
  • USB Gadget: Dual-mode ACM serial + RNDIS network gadget on usb0 (192.168.42.1/24) with dnsmasq DHCP, NetworkManager static IP, and serial console on ttyGS0 with proper systemd dependency handling
  • Security: SSH hardening, fail2ban, DHCP privacy (MAC randomization), Terrapin mitigation via security-hardening/recomputer-security.sh
  • USB Auto-mount: udev-based auto-mounting of USB storage under /media/seeed/LABEL
  • OTA: Recovery OTA and A/B dual-partition OTA with rollback support (via seeed_armbian_extension)
  • Encrypted Disk: LUKS root with OP-TEE auto-unlock (RK_AUTO_DECRYP=yes)
  • Camera: RKAIQ camera engine packages for both SoCs

Boot & Firmware

  • Custom U-Boot boot scripts (boot-seeed-rk3576.cmd, boot-seeed-rk35xx.cmd) with SPI flash boot support
  • U-Boot defconfigs for both boards (EEPROM boot, I2C config, HDMI voltage swing patches)
  • Device trees: rk3576-recomputer-rk3576-devkit.dts, rk3588-recomputer-rk3588-devkit.dts
  • Kernel config additions: AD5398 DAC, PCA953X GPIO, fan control for RK3576

Build Framework Integration

  • lib/functions/compilation/patch/drivers_network.sh: Driver harness integration for Morse wireless FGH100M kernel module
  • lib/functions/compilation/patch/drivers-harness.sh: Hook for Morse driver build
  • External extension system: ENABLE_SEEED_RK_EXTENSION=yes clones seeed_armbian_extension from GitHub for OTA, encryption, and secure boot features

Changed Files

File Description
config/boards/recomputer-rk3576-devkit.conf RK3576 board config (113 lines)
config/boards/recomputer-rk3588-devkit.conf RK3588 board config (107 lines)
config/boards/recomputer-rk35xx-common.inc Shared hooks for both boards (305 lines)
config/bootscripts/boot-seeed-rk3576.cmd RK3576 U-Boot boot script
config/bootscripts/boot-seeed-rk35xx.cmd RK3588 U-Boot boot script
config/kernel/linux-rk35xx-vendor.config Kernel config: AD5398, PCA953X, fan
patch/kernel/rockchip-rk35xx-legacy/ RK3576 DTS, fan curve, camera engine
patch/kernel/rockchip-rk3588-legacy/ RK3588 DTS, HDMI voltage, camera engine
patch/kernel/rockchip64-7.0/ Upstream kernel patch refresh
patch/misc/wireless-fgh100m.patch Morse FGH100M HaLow WiFi driver
patch/u-boot/* U-Boot defconfigs, EEPROM boot, flash patches
lib/functions/compilation/patch/ Morse driver build integration

How to Test

# RK3576 minimal build
./compile.sh BOARD=recomputer-rk3576-devkit BRANCH=vendor RELEASE=noble \
    BUILD_MINIMAL=yes BUILD_DESKTOP=no KERNEL_CONFIGURE=no

# RK3588 full desktop with OTA + encryption
./compile.sh BOARD=recomputer-rk3588-devkit BRANCH=vendor RELEASE=noble \
    BUILD_MINIMAL=no BUILD_DESKTOP=yes DESKTOP_ENVIRONMENT=xfce \
    KERNEL_CONFIGURE=no ENABLE_SEEED_RK_EXTENSION=yes \
    OTA_ENABLE=yes CRYPTROOT_ENABLE=yes RK_AUTO_DECRYP=yes \
    CRYPTROOT_PASSPHRASE=<64-char-hex>

Serial console: minicom -b 1500000 -D /dev/ttyUSB0

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for Seeed Studio reComputer RK3576 and RK3588 DevKit boards with complete hardware enablement.
    • Added camera engine support for reComputer devices.
    • Added USB gadget mode with network connectivity capabilities.
    • Added Morse WiFi wireless driver support.
    • Enhanced audio device naming and X11 display configuration.
  • Bug Fixes

    • Fixed boot device type reinitialization to handle missing environment variables.
    • Adjusted HDMI voltage swing configuration for improved stability.

ackPeng and others added 17 commits April 14, 2026 10:43
Extract duplicated hooks from rk3576 and rk3588 board configs into
recomputer-rk35xx-common.inc. Both configs source the shared file and
keep only SoC-specific hooks.

Common hooks: bluez (FCS960K), USB gadget, Morse FGH100M tools,
AIC8800 wireless, security hardening, PATH config, USB auto-mount.

Key fixes included:
- USB gadget: NM managed via ExecStartPost in usbdevice.service drop-in
  (not via broken keyfile unmanaged-devices exception)
- dnsmasq: After=usbdevice + Restart=on-failure for reliable boot
- serial-getty@ttyGS0: ordering via drop-in, not custom service
- USB auto-mount: udev SYSTEMD_WANTS triggers usb-automount@.service,
  mounts under /media/seeed/ with proper ownership
- SSH: MaxAuthTries 6 (OpenSSH default) to support multi-key clients

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When usbdevice fails on first attempt, serial-getty@ttyGS0 tries to
start before ttyGS0 exists and stays dead. Add Restart=on-failure
so it retries after usbdevice eventually succeeds.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
bind-interfaces fails if usb0 doesn't exist at startup, requiring
After=usbdevice + Restart=on-failure workarounds. bind-dynamic
tolerates missing interfaces and serves DHCP when usb0 appears,
removing the need for the dnsmasq systemd drop-in entirely.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Clear BindsTo=dev-ttyGS0.device from the base unit via drop-in override.
ttyGS0 is a USB gadget device not present at boot, so the base unit's
BindsTo causes a dependency failure. Also drop Restart=on-failure override
to preserve the base unit's Restart=always, preventing the getty from
staying dead after a normal logout.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 24, 2026

Important

Review skipped

Ignore keyword(s) in the title.

⛔ Ignored keywords (2)
  • wip
  • draft

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 85c2bf21-8c58-4689-b776-17dd9f0f8c39

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added size/large PR with 250 lines or more 05 Milestone: Second quarter release Needs review Seeking for review Hardware Hardware related like kernel, U-Boot, ... Framework Framework components Patches Patches related to kernel, U-Boot, ... labels Apr 24, 2026
Pillar1989 and others added 2 commits April 24, 2026 15:08
The BT UART assignment is per-board, not per-SoC.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move BT UART selection from BOOT_SOC-based case logic in common.inc to
per-board BT_UART variables. RK3576 DevKit uses ttyS4, RK3588 DevKit
uses ttyS6. Remove redundant pre_umount_final_image BT UART hook from
RK3576 config since common.inc BSP hook now handles it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AIC8800_TYPE="sdio"
enable_extension "radxa-aic8800"

source "${SRC}/config/boards/recomputer-rk35xx-common.inc"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, this is not standard. There's no real standard for this, really, except using extensions and/or using family code. Long ago I've tried a "vendor" common dir for the Mekotronics, see sources/vendors/mekotronics and config/boards/mekotronics-r58x.csc? In the end it's just about the file/folder structure.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I made revisions based on your two references. Thanks

@armbian armbian deleted a comment from github-actions Bot Apr 24, 2026
@armbian armbian deleted a comment from github-actions Bot Apr 25, 2026
@armbian armbian deleted a comment from github-actions Bot Apr 25, 2026
@armbian armbian deleted a comment from github-actions Bot Apr 25, 2026
@armbian armbian deleted a comment from github-actions Bot Apr 25, 2026
@armbian armbian deleted a comment from github-actions Bot Apr 25, 2026
@baorepo
Copy link
Copy Markdown
Author

baorepo commented Apr 25, 2026

@EvilOlaf Thanks for the feedback on custom_kernel_config. We've investigated the cache mechanism in detail.

What we found:

The kernel artifact cache key is LINUXFAMILY + BRANCH (see artifact-kernel.sh:11BOARD is explicitly excluded). Armbian tracks config modifications through the kernel_config_modifying_hashes array, which feeds into the cache hash. However, kernel_config_set_y/n/m/val directly calls scripts/config and does not populate this array — so our board-level custom_kernel_config hooks modify .config without affecting the cache key. This means the first build's kernel gets cached and reused for all boards in the same family, with our custom options baked in.

We checked: no other board in rockchip-rk3588 or rk35xx families defines a custom_kernel_config hook. The opts_y/opts_n/opts_m array approach is used at the family level (e.g., filogic.conf, meson-s4t7.conf) and in extensions (e.g., kernel-rust.sh, gateway-dk-ask.sh), but never at the board level.

Options we're considering:

  1. Convert to opts_y/opts_n/opts_m arrays — minimal change, cache hash is tracked correctly. But this still puts kernel config at the board level, which no other board does.

  2. Create a new board family (e.g., recomputer-rk35xx) — most correct per Armbian conventions, independent cache. But we'd diverge from upstream rockchip-rk3588 / rk35xx families, losing shared kernel patches and configs. Maintenance burden increases significantly.

  3. Move our kernel config additions to a shared family include — e.g., config/sources/families/include/recomputer_common.inc, sourced from the existing family configs. This follows the meson64_common.inc / uefi_common.inc pattern. But it modifies files shared with other boards.

Our preference is option 1 for now — it's the smallest fix that correctly tracks the cache hash, and we can revisit the family structure later if needed. What do you think?

@EvilOlaf
Copy link
Copy Markdown
Member

EvilOlaf commented Apr 25, 2026

I be totally honest, I don't know exactly how the internals on this work, I just know from previous PRs that on various occasions board-level kernel adjustments are flagged as a bad idea since it breaks apt repo
#9600 (comment)

Anyway it might be possible to move all of this to family level and work around this. I just throw in some random thoughts, may be totally wrong though.

  # GPIO PCA953X - enable as built-in (needed for I2C GPIO expander)
  kernel_config_set_y CONFIG_GPIO_PCA953X

If the issue is that, when built as module, it loads (too) late, perhaps create a hook for initramfs generation to force the module into initramfs image? Then it should behave similar to being built-in I guess

  # RTC driver PCF8563 - enable as built-in
  kernel_config_set_y CONFIG_RTC_DRV_PCF8563

If module is sufficient, I'd do the same as above

  # Morse Wireless (FGH100M) configuration
  kernel_config_set_m CONFIG_WLAN_VENDOR_MORSE
  kernel_config_set_y CONFIG_MORSE_SPI
  kernel_config_set_y CONFIG_MORSE_USER_ACCESS
  kernel_config_set_y CONFIG_MORSE_VENDOR_COMMAND
  kernel_config_set_y CONFIG_MORSE_MONITOR
  kernel_config_set_y CONFIG_MAC80211_MESH
  kernel_config_set_val CONFIG_MORSE_DEBUG_MASK "1"

Without looking deeper, tbh not sure how to exactly handle this. Perhaps there are other extensions already that add some sort of drivers which obviously also come with kernel config settings.

  # Regulator for Raspberry Pi Touchscreen V2 and camera v3
  kernel_config_set_y CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_V2
  kernel_config_set_y CONFIG_VIDEO_IMX708
  kernel_config_set_y CONFIG_VIDEO_DW9800W
  kernel_config_set_y CONFIG_REGULATOR_AD5398
  # fan
  kernel_config_set_y CONFIG_SENSORS_PWM_FAN

If added as module I don't see a reason not to add to family kernel config and if needed again force move into initramfs.

@SteeManMI
Copy link
Copy Markdown
Contributor

Do be totally honest, I don't know exactly how the internals on this work, I just know from previous PRs that on various occasions board-level kernel adjustments are flagged as a bad idea since it breaks apt repo #9600 (comment)

At a high level the issue is with the software deployment lifecycle via apt and the Armbian apt repositories. kernel apt packages are produced and populated into the apt repositories keyed by Family-Branch. So after initial image creation when an apt update/upgrade is run the latest kernel package from the repositories will be deployed to the device which will upgrade the kernel to the standard kernel for the Family-Branch. Which will effectively remove any board specific kernel that was originally installed.

The Armbian concept of Family is a superset of kernel features that work for all boards within the family. Generally adding additional board feature to the family kernel won't be a problem, but it can sometimes cause conflicts.

The other consideration is that this is done to minimize Armbian infrastructure costs. If each board had its own kernel, the storage and infrastructure cost for the build farms and the apt mirrors would be unmaintainable.

@baorepo
Copy link
Copy Markdown
Author

baorepo commented Apr 27, 2026

@EvilOlaf @SteeManMI Thanks both for the detailed explanation — that clears up a lot.

@SteeManMI The apt repository deployment angle makes perfect sense now. We hadn't considered the full lifecycle beyond the build cache — the fact that apt upgrade would pull the family-standard kernel and wipe board-specific config is the real blocker. So board-level custom_kernel_config is indeed not the right approach.

@EvilOlaf The initramfs hook approach for forcing module load is a good idea for PCA953X and RTC. For the Morse wireless bits we'll look at how other extensions handle driver kernel config additions.

The direction seems clear: move our config changes to family level (or an extension, for the Morse driver parts), prefer modules over built-in, and use initramfs hooks for anything that needs to be available early. We'll take some time to figure out the right split and come back with a concrete proposal. Thanks again for the guidance.

is-qian and others added 3 commits April 27, 2026 14:24
Move enable_extension "seeed_armbian_extension" back to top-level code
in recomputer-rk35xx-common.inc. The armbian framework finalizes the
extension system before post_family_config hooks run, so calling
enable_extension inside a hook triggers "already initialized" error.
The git clone/pull remains in the hook to defer network I/O.
Reverts the split introduced by 3f3a384 and partially reverted by
ade3393. Both the git clone/pull and enable_extension must execute
at top-level in recomputer-rk35xx-common.inc; they cannot be deferred
to a post_family_config hook.

Root cause
----------
The Armbian extension system has a strict initialization sequence:

  1. Board/family config files are sourced (top-level code runs)
  2. enable_extension() calls register extensions
  3. initialize_extension_manager() scans all __-separated hook
     functions via compgen -A function, then locks further
     enable_extension() calls (counter > 0 → fatal exit)
  4. post_family_config hooks are called

enable_extension() is hard-gated after step 3 (see
lib/functions/general/extensions.sh:461-465). All hooks, including
post_family_config, run at step 4 — too late to call
enable_extension().

Previous attempts
-----------------
- 3f3a384 moved both clone and enable_extension into a
  post_family_config hook → "already initialized" fatal error
  because enable_extension runs after the manager is locked.

- ade3393 moved enable_extension back to top-level but kept
  git clone in the hook → "cant find extension 'seeed_armbian_extension'
  anywhere" because enable_extension runs before the hook clones the
  extension files to disk.

Both attempts fail because they split an atomic operation: the
extension files must exist on disk before enable_extension() is
called, and enable_extension() must run before the extension manager
initializes. Therefore both steps must happen at top-level during
config file sourcing (step 1).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous dpkg --force-depends installation can leave apt dependency
tracking in a broken state. Add --fix-broken install to repair it.
baorepo pushed a commit to baorepo/armbian.github.io that referenced this pull request Apr 30, 2026
- board-images/recomputer-rk3576-devkit.png
- board-images/recomputer-rk3588-devkit.png
- board-vendor-logos/seeed-studio-logo.png

Required by armbian/build#9719
Replace manual prebuilt deb downloads and source compilation with
apt-get install from the Seeed APT repository hosted on GitHub Pages.
This applies to all Seeed packages across RK3576 and RK3588 boards:

- fcs960k-aic-bluez, usbdevice-gadget, morse tools (common)
- camera-engine-rkaiq-rk3576 (RK3576)
- libmali-g610, camera-engine-rkaiq-rk3588, realtek-r8125-dkms (RK3588)

Use chroot_sdcard instead of chroot_sdcard_apt_get_install to avoid
the framework's bind-mounted apt lists cache overwriting the Seeed
repo index. Extract seeed_recomputer_install_from_apt() helper to
centralize the add-repo/install/remove cycle.
igorpecovnik added a commit to armbian/armbian.github.io that referenced this pull request Apr 30, 2026
* Add Seeed Studio reComputer board images and vendor logo

- board-images/recomputer-rk3576-devkit.png
- board-images/recomputer-rk3588-devkit.png
- board-vendor-logos/seeed-studio-logo.png

Required by armbian/build#9719

* Add border to Seeedstudio logo and run trough size optimizer

---------

Co-authored-by: pillar1989 <zuobaozhu@gmail.com>
Co-authored-by: Igor Pecovnik <igor@armbian.com>
…lict

- Add post_family_tweaks_bsp hook to write seeed.list with signed-by
  GPG key into the final image, enabling apt upgrade for Seeed packages
- Import GPG key with gpg --dearmor (binary format required by signed-by)
- Only refresh Seeed source index during build (skip Ubuntu/Armbian)
  to cut build time from ~54 min to ~22 min
- Move fcs960k-aic-bluez install to post_repo_customize_image hook
  so it replaces bluez after desktop packages are installed
@armbian armbian deleted a comment from github-actions Bot May 6, 2026
@armbian armbian deleted a comment from github-actions Bot May 6, 2026
@armbian armbian deleted a comment from github-actions Bot May 6, 2026
@armbian armbian deleted a comment from github-actions Bot May 6, 2026
@armbian armbian deleted a comment from github-actions Bot May 6, 2026
@armbian armbian deleted a comment from github-actions Bot May 6, 2026
@armbian armbian deleted a comment from github-actions Bot May 6, 2026
The package uses generic Rockchip configfs USB gadget which works on
both RK3576 and RK3588.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

🚫 Missing required board assets

This PR adds new board configuration(s). Required assets must already exist in github/armbian/armbian.github.io.
They are required by Armbian Imager to ensure all boards are displayed with proper images.

  • Board images: board-images/<board>.png (1920x1080 px transparent)
  • Vendor logos: board-vendor-logos/<vendor>-logo.png (512x512 px transparent)

Missing items

  • Vendor logo missing for vendor seeed studio (used by board recomputer-rk3576-devkit)

    • Expected: board-vendor-logos/seeed studio-logo.png
    • Fix: add the file to armbian/armbian.github.io (folder board-vendor-logos/)
    • Naming rules: lowercase, dashes (e.g. kobol-logo.png, not Kobol_logo.png)
  • Vendor logo missing for vendor seeed studio (used by board recomputer-rk3588-devkit)

    • Expected: board-vendor-logos/seeed studio-logo.png
    • Fix: add the file to armbian/armbian.github.io (folder board-vendor-logos/)
    • Naming rules: lowercase, dashes (e.g. kobol-logo.png, not Kobol_logo.png)

Once the missing files are added (or a PR is opened in armbian/armbian.github.io), re-run this check.

@armbian armbian deleted a comment from github-actions Bot May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

05 Milestone: Second quarter release Framework Framework components Hardware Hardware related like kernel, U-Boot, ... Needs review Seeking for review Patches Patches related to kernel, U-Boot, ... size/large PR with 250 lines or more

Development

Successfully merging this pull request may close these issues.

7 participants