UP  |  HOME
RSS | RSS Complete

testament (NanoPi R2C)

Table of Contents

Summary

testament is a FriendlyElec NanoPi R2C. Intended use is a test server on a mini network that mostly runs duplicates of services I use.

Notes

TODO

Hardware

Make FriendlyElec
Year 2020
Model NanoPi R2C
Chassis R2C Metal Case
Power Supply 5V USB C
Processor Rockchip RK3328
Memory 1GB DDR4
Ports USB C power/OTG
  USB A 2.0
  2x RJ-45 LAN
  Micro SD
Graphics -
Storage 32GB MicroSD card
Int. Peripherals 2x UART
  GPIO
  I2C
  RTL8153B USB 3.0 Gigabit NIC
  YT8521S Gigabit PHY
Ext. Peripherals -
Dimensions  
Length/Depth 6.0 cm
Width 6.1 cm
Height/Thickness 2.7 cm
Weight 152 g (5.4 oz)

Software

Operating System Debian
Unique applications  

Log

[2021-09-15 Wed] Initial Impressions

I ordered the "NanoPi R2C Combo with Metal Case" from FriendlyElec. Turnaround was pretty quick from China at about 2.5 weeks.

[2022-02-02 Wed] Debian Install (part 1)

Went down a slight rabbit hole trying to cross-compile before discovering the Nano Pi R2S has device trees in the kernel and u-boot. The main difference between R2C and R2S is the ethernet PHY used for the SoC network interface. However I needed a host running testing or unstable, and the u-boot package needed to be rebuilt with a target added for the nanopi-r2s-rk3328.

I decided to use the Pi 4 (ragna) to build the new package and installe image. The basic steps look like:

  • Rebuild u-boot with r2s target added, and install on Pi host
  • Build installer u-boot and netboot images
  • Create an SD card and install Debian

Building u-boot

The dependencies of u-boot weren't all available on arm64 (powerpc cross-compiler) so I had to manually install the other dependencies. Use the rules-target (-T) option to only build arch specific packages, and -d to ignore build deps.

Modify debian/targets.mk to add a new target. I copied a similar rk3328 target, renamed it, and modified it to use the r2s device tree. It looks like:

u-boot-rockchip_platforms += nanopi-r2s-rk3328
nanopi-r2s-rk3328_assigns := BL31=/usr/lib/arm-trusted-firmware/rk3328/bl31.elf
nanopi-r2s-rk3328_targets := arch/arm/dts/rk3328-nanopi-r2s.dtb idbloader.img \
  spl/u-boot-spl.bin tpl/u-boot-tpl.bin u-boot-nodtb.bin u-boot.bin \
  u-boot.img u-boot.itb uboot.elf

Build and install:

apt-get source u-boot
cd u-boot<TAB>
export $(dpkg-architecture)
dpkg-buildpackage -T binary-arch -d
dpkg -i ../u-boot-rockchip*.deb

Save the u-boot-rockchip and maybe u-boot-tools packages for later to install on the target machine. I just put them on a FAT usb stick, but you can probably scp from within the chroot.

Building the Debian installer images

Mostly follow the wiki guide: https://wiki.debian.org/DebianInstaller/Build

Basic rundown:

  • Clone the repo, checkout all the sub-repos
  • Prep the build (which release/udebs are you using)
  • Add the new targets for nanopi-r2s-rk3328
  • Build the u-boot and netboot targets
  • Concatenate your images and write to SD card

For adding the new targets when you've changed to the installer/build directory you need to modify two files. config/arm64/u-boot.cfg and config/arm64/netboot.cfg Find the line with "rock64-rk3328" target and add a "nanopi-r2s-rk3328" target.

Now from the build directory you can run:

fakeroot make build_u-boot build_netboot
zcat dest/netboot/SD-card-images/firmware.nanopi-r2s-rk3328.img.gz \
    dest/netboot/SD-card-images/partition.img.gz > ./nanopi-r2s-sd-card.img
dd if=nanopi-r2s-sd-card.img of=/dev/disk/by-id/...

Create the SD card and install Debian WIP

Write your image to the SD card device (not a partition of it):

dd if=nanopi-r2s-sd-card.img of=/dev/disk/by-id/...

I plugged the SD card in, hooked up a 3.3V FTDI adapter to the debug serial port. Be sure to attach a network cable. I forget which port works so you may have to swap around during install. Apply power to boot.

Attach to the serial console:

screen /dev/ttyUSB0 1500000

The text install goes pretty smooth until it gets to the bootloader. Go back to the install menu and open a shell.

Get those u-boot packages you made earlier onto the machine and copy them somewhere in /target. I just throw them in root's directory. This ensures you have the device tree for installing u-boot.

for i in /dev /dev/pts /proc /sys /sys/firmware/efi/efivars /run; do sudo mount --rbind $i /target$i; done
chroot /target
dpkg -i /root/u-boot...deb
exit

Install u-boot to the SD card:

TARGET=/target/usr/lib/u-boot/nanopi-r2s-rk3328 /target/usr/bin/u-boot-install-rockchip /dev/mmcblk0

This is where I'm stuck. u-boot loads and fails to boot. I try loading the kernel as below, but it always fails with "zimage: Bad magic!".

load mmc 1:1 0x12000000 /vmlinuz
load mmc 1:1 0x13000000 /initrd.img
load mmc 1:2 0x18000000 /usr/lib/u-boot/nanopi-r2s-rk3328/rk3328-nanopi-r2s.dtb
bootz 0x12000000 0x13000000 0x18000000

I tried without the initrd and device tree to prevent clobbering vmlinuz, but it has no effect. I'm out of ideas. I've tried inspecting the kernel image that gets loaded into memory and it appears to match the arm64 kernel I have on the raspberry pi 4. I don't understand how my u-boot can be bad since it was capable of booting the intstaller netboot image. The last idea I have is the kernel is broken on this platform, but the installer kernel worked because it was different.

[2022-02-07 Mon] Debian Install (part 2)

Still not working, but minor improvements

I recompleted the install process, but now I leave the install partition intact with the possibility of using it as an EFI partition. So during install I chose to partition using the largest free space, then mount the installer partition at /boot/efi.

This still requires chroot after the install to set up bootloader things. Now I go to install some slightly different things to try (chroot as before):

for i in /dev /dev/pts /proc /sys /sys/firmware/efi/efivars /run; do sudo mount --rbind $i /target$i; done
chroot /target
dpkg -i /root/u-boot...deb
apt install grub-efi-arm64 u-boot-menu syslinux-efi
update-grub
grub-install --dtb=/usr/lib/u-boot/nanopi-r2s-rk3328/rk3328-nanopi-r2s.dtb \
    --efi-directory=/boot/efi --target=arm64-efi
u-boot-update
TARGET=/target/usr/lib/u-boot/nanopi-r2s-rk3328 /target/usr/bin/u-boot-install-rockchip /dev/mmcblk0

Now we have a menu on boot, but it fails with a message from u-boot that we are lacking some compile-time feature (despite fdt commands working at the u-boot prompt):

mmc1 is current device
Scanning mmc 1:2...
Found /extlinux/extlinux.conf
Retrieving file: /extlinux/extlinux.conf
U-Boot menu
1:      Debian GNU/Linux bookworm/sid 5.15.0-3-arm64
2:      Debian GNU/Linux bookworm/sid 5.15.0-3-arm64 (rescue target)
Enter choice: 1
1:      Debian GNU/Linux bookworm/sid 5.15.0-3-arm64
Retrieving file: /initrd.img-5.15.0-3-arm64
Retrieving file: /vmlinuz-5.15.0-3-arm64
append: root=UUID=11111111-1111-1111-1111-111111111111 ro quiet
Moving Image from 0x2080000 to 0x2200000, end=3ee0000
   Loading Ramdisk to 3bf32000, end 3df2db38 ... OK
FDT and ATAGS support not compiled in
resetting ...

Lets try booting grub efi. Interrupt the boot loop by pressing a key before u-boot's autoboot. Load a kernel and fdt much like before, but now our kernel is the grub efi.

load mmc 1:1 ${fdt_addr_r} dtbs/rockchip/rk3328-nanopi-r2s.dtb
load mmc 1:1 ${kernel_addr_r} EFI/grub/grubaa64.efi
bootefi ${kernel_addr_r} ${fdt_addr_r}

After a DMA reset timeout we have gotten to a grub prompt. Seems like update-grub was ineffective or other mistakes were made. Load the kernel anyway.

Point grub's root to our /boot partition. Tell linux that root is partition 3.

root=(hd0,msdos2)
linux /vmlinuz root=/dev/mmcblk0p3
initrd /initrd.img
boot

Note: If root partition isn't found, you may have skipped loading the device tree. Then the kernel puts the SD card at mmcblk1 instead.

Finally we have booted into the system.

Making it happen automatically

  • With flash-kernel

    Add an entry to /etc/flash-kernel/db. Copying the examples from /usr/share/flash-kernel/db/all.db. Pull the Machine: entry from /proc/device-tree/model.

    Note: because I have the EFI partition first u-boot searches it first and finds my grub efi there. That's why my boot script path is /boot/efi instead of just /boot like the examples.

    Machine: FriendlyElec NanoPi R2S
    Kernel-Flavors: arm64
    DTB-Id: rockchip/rk3328-nanopi-r2s.dtb
    Boot-Script-Path: /boot/efi/boot.scr
    U-Boot-Script-Name: bootscr.uboot-generic
    Required-Packages: u-boot-tools u-boot-rockchip
    

    Run flash-kernel to install (should automatically match from the machine name). Remove efi stuff in /boot/efi because u-boot seems to prefer it.

    One last issue left. Only the Realtek NIC is functional. The Motocomm PHY needs to be added to the device tree, and the driver is not in mainline.

[2022-06-01 Wed] Testament seems dead

I went to try and use testament to build the installer for akatsuki, but it didn't come up on the network. So I hooked up the serial console incorrectly and played around. Then I realized the correct way. In any case it doesn't produce any output now. The SYS LED lights up. I checked a few voltages and they seems reasonable. The board draws a constant 200 mA. Sadly it may just be garbage. Maybe I can get a proper R2S and re-use the case.