Jump to content

NixOS on ARM/Radxa ROCK 4: Difference between revisions

From NixOS Wiki
Add NixOS on ROCK 4 page
 
Added instructions to build and write U-Boot to SPI flash present on various Rock 4 boards
 
(7 intermediate revisions by 3 users not shown)
Line 33: Line 33:
* '''PCIe''': M.2 M Key M connector (4-lane PCIe 2.1) supports NVMe SSD
* '''PCIe''': M.2 M Key M connector (4-lane PCIe 2.1) supports NVMe SSD


The @msgilligan PR below has been tested with both the ROCK 4B+ and ROCK 4 SE variants.
The [https://github.com/nabam/nixos-rockchip nixos-rockchip] SD-card images have been tested with both the ROCK 4B+ and ROCK 4 SE variants.


== Status ==
== Status ==
Line 43: Line 43:
* U-Boot
* U-Boot
** [https://github.com/u-boot/u-boot/ Mainline] - Supports ?? boot options
** [https://github.com/u-boot/u-boot/ Mainline] - Supports ?? boot options
** [https://github.com/NixOS/nixpkgs/blob/master/pkgs/misc/uboot/default.nix Nixpkgs] - not tested yet by @msgilligan
** [https://github.com/NixOS/nixpkgs/blob/master/pkgs/misc/uboot/default.nix Nixpkgs] - tested by @ryjelsum, seemingly working but not thoroughly used


The official hardware documentation can be found [https://docs.radxa.com/en/rock4 on the Radxa wiki].
The official hardware documentation can be found [https://docs.radxa.com/en/rock4 on the Radxa Documentation site].


== Bootloader Firmware ==
== Bootloader Firmware ==
Line 51: Line 51:
=== U-Boot Firmware ===
=== U-Boot Firmware ===


* The @msgilligan PR rely's on `nixos-rockchip` which in turn uses the mainline U-Boot repository.
* <code>nixos-rockchip</code> uses the mainline U-Boot repository.
* There is also support for ROCK 4 U-Boot in Nixpkgs, but testing and documentation for using this version of U-Boot is not available here yet.
* As an alternative for using nixos-rockchip, There is also support for ROCK 4 U-Boot in Nixpkgs.
This build of u-boot is built using the defconfig from u-boot's repositories, so it should be equivalent to 'stock' u-boot, but be aware there may be unknown differences, as it has not been thoroughly tested. The following command will build the u-boot bootloader with Nix on a non-aarch64 system, and output its path as a 'result' symlink in the current directory:
 
<code>nix-build '<nixpkgs>' -A pkgsCross.aarch64-multiplatform.ubootRockPi4</code> 
 
This will build u-boot as two separate files, <code>idbloader.img</code> and <code>u-boot.itb</code>. To flash the bootloader, follow the directions provided in u-boot's repos for [https://github.com/u-boot/u-boot/blob/af69289d61876d8e62449ee2da2dc6683bcb8198/doc/README.rockchip#L486 how to transfer these files to storage (SD card or EMMC) for usage].
 
<code>sudo dd if=idbloader.img of=/dev/sdc seek=64; sudo dd if=u-boot.itb of=/dev/sdc seek=16384</code> 
 
After this, take special care to leave the first ~16mb of the target disk unpartitioned during installation, as this will contain u-boot and overwriting this region will overwrite the bootloader. 
 
The stock UEFI ISO boots fine for installation purposes. If you wish to flash directly to SD/EMMC, the extlinux 'sdimage' may require a minor u-boot env change (<code>env set ramdisk_addr_r 0x06800000</code>, <code>env save</code>) in order to boot, but should work after this change has been made. 
 
==== SPI flash installation from SD card ====
In Nixpkgs only SD card binaries are built by default. To get U-Boot binary for SPI flash and change other relevant settings the image needs to be built with overrides. To include <code>u-boot-rockchip-spi.bin</code> in <code>result/</code> folder it needs to added to the <code>filesToInstall</code>. Also included here is <code>u-boot-rockchip.bin</code> which includes <code>idbloader.img</code> and <code>u-boot.itb</code> in a single file.
 
By default this image is meant for Rock (Pi) 4A board. You might want to change this to another Rock 4 family board like Rock (Pi) 4C by setting <code>defconfig</code> to be <code>"rock-pi-4c-rk3399_defconfig"</code> or Rock 4SE with <code>"rock-4se-rk3399_defconfig"</code>. Another option is <code>extraConfig</code> where you can add overrides of defconfigs for example to use Rock (Pi) 4A defconfig but change device tree path to plus version of the boards by changing <code>CONFIG_DEFAULT_DEVICE_TREE</code> and <code>CONFIG_DEFAULT_FDT_FILE</code>.
 
Lastly at least on Rock (Pi) 4C there seems to be an issue upstream with a diagnostic blue LED turned on preventing SPI flash access. Here is a patch included to fix this in <code>extraPatches</code>.<syntaxhighlight lang="bash">
nix-build -E "
with import <nixpkgs> { };
pkgsCross.aarch64-multiplatform.ubootRockPi4.override {
  defconfig = \"rock-pi-4c-rk3399_defconfig\";
  filesToInstall = [ \"u-boot-rockchip.bin\" \"u-boot-rockchip-spi.bin\" ];
  extraPatches = [ (fetchpatch {
    url=\"https://gist.githubusercontent.com/Diamondtroller/e82d1c4a8b55beac26cc38209414a8b8/raw/ae4795cd4bf690c575fafa6b98714c47d548da1d/spi.patch\";
    hash=\"sha256-rEbmywPeOR5smIRhYUwcsfPeK+LiEMO2b3lmwrnJ+k4=\";
    }) ];
}"
 
</syntaxhighlight>After building U-Boot images SD card needs to be modified to have two partitions. One partition is meant for U-Boot, which will be the environment to flash the SPI chip, while second partition will contain the U-Boot binary file suitable for SPI chip. Create file system for second partition. Start of the first partition shouldn't be changed, other values can be changed as long as the files fit.<syntaxhighlight lang="bash">
echo -e 'label: gpt\nunit: sectors\nsector-size: 512\nfirst-lba:64\n\nstart=64, size=16M, name="U-Boot"\nsize=8M, name="Payload"' | sudo sfdisk /dev/mmcblk0
sudo mkfs.ext4 /dev/mmcblk0p2
 
</syntaxhighlight>Here are provided commands to copy the file to the second partition.<syntaxhighlight lang="bash">
mkdir /tmp/mnt
sudo mount /dev/mmcblk0p2 /tmp/mnt
sudo cp result/u-boot-rockchip-spi.bin /tmp/mnt
sudo umount /dev/mmcblk0p2
</syntaxhighlight>And here is the command to write U-Boot to the first partition.<syntaxhighlight lang="bash">
sudo dd if=result/u-boot-rockchip.bin of=/dev/mmcblk0p1 bs=1M
</syntaxhighlight>Insert the SD card into your board and boot into it. In case where you have corrupted or non-booting U-Boot in the flash you need to short SPI clock pin. Pin 25 is the ground pin and pin 23 is the SPI clock pin, connect those. You can see diagram of pins in [https://docs.radxa.com/en/rock4/hardware/rock4-gpio official docs]. However when you have booted into the U-Boot on SD card, this wire should be removed to access the flash. The idea is to prevent BootROM from trying to boot off of SPI flash. You can read about bootflow more in [https://opensource.rock-chips.com/wiki_Boot_option#Boot_flow Rockchip wiki]. When the board has booted into U-Boot enter these commands based on [https://docs.u-boot.org/en/latest/board/rockchip/rockchip.html#spi U-Boot docs]:
 
# probe the SPI flash for reading and writing, you should get SF: followed by info about SPI flash chip.
# load u-boot-rockchip-spi.bin file from mmc (SD card) on bus 1, partition 2 to the memory just after U-Boot.
# write to the SPI flash the contents of the file which are loaded into the memory.
<syntaxhighlight>
=> sf probe
=> load mmc 1:2 $kernel_addr_r u-boot-rockchip-spi.bin
=> sf update $fileaddr 0 $filesize
</syntaxhighlight>


== System configuration ==
== System configuration ==


Use the instructions in the [https://github.com/nabam/nixos-rockchip/blob/main/README.md README], but until the PR is merged, you'll need to checkout the PR branch.
The following directions are for usage with <code>nixos-rockchip</code>.
 
Use the instructions in the [https://github.com/nabam/nixos-rockchip/blob/main/README.md README].


Use the following command to build the image:
Use the following command to build the Rock 4B image:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
Line 64: Line 116:
</syntaxhighlight>
</syntaxhighlight>


=== @msgilligan's PR to @nabam's flake ===
or for the Rock 4SE:
 
<syntaxhighlight lang="bash">
nix build .#RadxaRock4SE
</syntaxhighlight>
 
=== nabam/nixos-rockchip GitHub Project ===


Nix flake for building several Rockchip SBC images, see [https://github.com/nabam/nixos-rockchip GitHub nabam/nixos-rockchip]
[https://github.com/nabam/nixos-rockchip nabam/nixos-rockchip] is a Nix flake for building several Rockchip SBC images, including Rock 4B and Rock 4SE.


@msgilligan's WIP PR to add ROCK 4 support (WIP, but tested on ROCK 4B+ and ROCK 4 SE): [https://github.com/nabam/nixos-rockchip/pull/27 nabam/nixos-rockchip PR #27]
[[Category:NixOS on ARM]]

Latest revision as of 14:46, 28 August 2025

Radxa ROCK 4
Radxa Rock 4
Manufacturer Radxa
Architecture AArch64
Bootloader U-Boot
Boot order SPI NOR Flash, eMMC, SD
Maintainer msgilligan

The Radxa ROCK 4B+ is a Single-Board Computer with a Rockchip RK3399 SoC.

  • CPU: ARM Cortex-A72 and Cortex-A53
  • GPU: Mali-T860 MP4
  • RAM: 2GB/4GB LPDDR4
  • MMC: eMMC Connector for up to 128GB
  • NET: 1 Gigabit Ethernet
  • USB: 1x USB3 OTG/HOST Type-A, 1x USB 3 Type-A, 2x USB 2 Type-A
  • PCIe: M.2 M Key M connector (4-lane PCIe 2.1) supports NVMe SSD

The nixos-rockchip SD-card images have been tested with both the ROCK 4B+ and ROCK 4 SE variants.

Status

Support of this system is YMMV (your mileage may vary).

U-Boot bootloaders are available in different variants:

  • U-Boot
    • Mainline - Supports ?? boot options
    • Nixpkgs - tested by @ryjelsum, seemingly working but not thoroughly used

The official hardware documentation can be found on the Radxa Documentation site.

Bootloader Firmware

U-Boot Firmware

  • nixos-rockchip uses the mainline U-Boot repository.
  • As an alternative for using nixos-rockchip, There is also support for ROCK 4 U-Boot in Nixpkgs.

This build of u-boot is built using the defconfig from u-boot's repositories, so it should be equivalent to 'stock' u-boot, but be aware there may be unknown differences, as it has not been thoroughly tested. The following command will build the u-boot bootloader with Nix on a non-aarch64 system, and output its path as a 'result' symlink in the current directory:

nix-build '<nixpkgs>' -A pkgsCross.aarch64-multiplatform.ubootRockPi4

This will build u-boot as two separate files, idbloader.img and u-boot.itb. To flash the bootloader, follow the directions provided in u-boot's repos for how to transfer these files to storage (SD card or EMMC) for usage.

sudo dd if=idbloader.img of=/dev/sdc seek=64; sudo dd if=u-boot.itb of=/dev/sdc seek=16384

After this, take special care to leave the first ~16mb of the target disk unpartitioned during installation, as this will contain u-boot and overwriting this region will overwrite the bootloader.

The stock UEFI ISO boots fine for installation purposes. If you wish to flash directly to SD/EMMC, the extlinux 'sdimage' may require a minor u-boot env change (env set ramdisk_addr_r 0x06800000, env save) in order to boot, but should work after this change has been made.

SPI flash installation from SD card

In Nixpkgs only SD card binaries are built by default. To get U-Boot binary for SPI flash and change other relevant settings the image needs to be built with overrides. To include u-boot-rockchip-spi.bin in result/ folder it needs to added to the filesToInstall. Also included here is u-boot-rockchip.bin which includes idbloader.img and u-boot.itb in a single file.

By default this image is meant for Rock (Pi) 4A board. You might want to change this to another Rock 4 family board like Rock (Pi) 4C by setting defconfig to be "rock-pi-4c-rk3399_defconfig" or Rock 4SE with "rock-4se-rk3399_defconfig". Another option is extraConfig where you can add overrides of defconfigs for example to use Rock (Pi) 4A defconfig but change device tree path to plus version of the boards by changing CONFIG_DEFAULT_DEVICE_TREE and CONFIG_DEFAULT_FDT_FILE.

Lastly at least on Rock (Pi) 4C there seems to be an issue upstream with a diagnostic blue LED turned on preventing SPI flash access. Here is a patch included to fix this in extraPatches.

nix-build -E "
with import <nixpkgs> { };
pkgsCross.aarch64-multiplatform.ubootRockPi4.override {
  defconfig = \"rock-pi-4c-rk3399_defconfig\";
  filesToInstall = [ \"u-boot-rockchip.bin\" \"u-boot-rockchip-spi.bin\" ];
  extraPatches = [ (fetchpatch {
    url=\"https://gist.githubusercontent.com/Diamondtroller/e82d1c4a8b55beac26cc38209414a8b8/raw/ae4795cd4bf690c575fafa6b98714c47d548da1d/spi.patch\";
    hash=\"sha256-rEbmywPeOR5smIRhYUwcsfPeK+LiEMO2b3lmwrnJ+k4=\";
    }) ];
}"

After building U-Boot images SD card needs to be modified to have two partitions. One partition is meant for U-Boot, which will be the environment to flash the SPI chip, while second partition will contain the U-Boot binary file suitable for SPI chip. Create file system for second partition. Start of the first partition shouldn't be changed, other values can be changed as long as the files fit.

echo -e 'label: gpt\nunit: sectors\nsector-size: 512\nfirst-lba:64\n\nstart=64, size=16M, name="U-Boot"\nsize=8M, name="Payload"' | sudo sfdisk /dev/mmcblk0
sudo mkfs.ext4 /dev/mmcblk0p2

Here are provided commands to copy the file to the second partition.

mkdir /tmp/mnt
sudo mount /dev/mmcblk0p2 /tmp/mnt
sudo cp result/u-boot-rockchip-spi.bin /tmp/mnt
sudo umount /dev/mmcblk0p2

And here is the command to write U-Boot to the first partition.

sudo dd if=result/u-boot-rockchip.bin of=/dev/mmcblk0p1 bs=1M

Insert the SD card into your board and boot into it. In case where you have corrupted or non-booting U-Boot in the flash you need to short SPI clock pin. Pin 25 is the ground pin and pin 23 is the SPI clock pin, connect those. You can see diagram of pins in official docs. However when you have booted into the U-Boot on SD card, this wire should be removed to access the flash. The idea is to prevent BootROM from trying to boot off of SPI flash. You can read about bootflow more in Rockchip wiki. When the board has booted into U-Boot enter these commands based on U-Boot docs:

  1. probe the SPI flash for reading and writing, you should get SF: followed by info about SPI flash chip.
  2. load u-boot-rockchip-spi.bin file from mmc (SD card) on bus 1, partition 2 to the memory just after U-Boot.
  3. write to the SPI flash the contents of the file which are loaded into the memory.
=> sf probe
=> load mmc 1:2 $kernel_addr_r u-boot-rockchip-spi.bin
=> sf update $fileaddr 0 $filesize

System configuration

The following directions are for usage with nixos-rockchip.

Use the instructions in the README.

Use the following command to build the Rock 4B image:

nix build .#RadxaRock4

or for the Rock 4SE:

nix build .#RadxaRock4SE


nabam/nixos-rockchip GitHub Project

nabam/nixos-rockchip is a Nix flake for building several Rockchip SBC images, including Rock 4B and Rock 4SE.