Allwinner’s Nezha D1 is a SoC based on RISC-V CPU with XuanTie C906 which is a 64-bit RV64GC CPU @ 1 GHz capable to run Linux distributions. The SoC is also has 512 Mb/1 Gb/2 Gb of RAM, Ethernet, WiFi, 256 MB of NAND flash memory and HDMI. The detailed description of the board with schematics could be found here. I have a model with 1 Gb of RAM. On the right side is a few photos of this SoC. This SoC ships with a 32 Gb microSD card with bootloaders and Debian distribution. The default partition table is a bit sophisticated:
1
2
3
4
5
6
7
8
9
Number Start (sector) End (sector) Size Code Name
1 41464 49527 3.9 MiB 0700 boot-resource
2 49528 50031 252.0 KiB 0700 env
3 50032 50535 252.0 KiB 0700 env-redund
4 50536 71199 10.1 MiB 0700 boot
5 71200 72207 504.0 KiB 0700 dsp0
6 72208 100431 13.8 MiB 0700 recovery
7 100432 16877647 8.0 GiB 0700 rootfs
8 16877648 60456925 20.8 GiB 0700 UDISK
Basically it has Debian 11 on it and a test program for LCD or HDMI /home/sipeed/test_lcd.sh
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/bash
echo "----:$1"
if [ "$1" == "hdmi" ] ; then
cd /sys/kernel/debug/dispdbg ;
echo disp0 > name;
echo switch1 > command;
echo 4 10 0 0 0x4 0x101 0 0 0 8 > param;
echo 1 > start;
fi
if [ "$1" == "lcd" ] ; then
cd /sys/kernel/debug/dispdbg ;
echo disp0 > name;
echo switch1 > command;
echo 4 10 0 0 0x4 0x101 0 0 0 8 > param;
echo 1 > start;
cd /sys/kernel/debug/dispdbg ;
echo disp0 > name;
echo switch1 > command;
echo 1 10 0 0 0x4 0x101 0 0 0 8 > param;
echo 1 > start;
fi
#cat /dev/urandom > /dev/fb0 ;
#echo 1 > /sys/class/disp/disp/attr/colorbar
#echo 0 > /sys/class/disp/disp/attr/colorbar
exit 0
After I’ve got familiar with the default system I decided to install Arch Linux on it. My partition table is based on the table from this by Cezary Sobczak:
I decided to have a single partition with EXT 4 file system for rootfs and /boot/
. The start of this partition is 67 Mb from the beginning, a bit extra than needed. Basically, the first stage bootloader (FSBL) and u-boot were placed in the first 21 Mb. For the FSBL I used OpenSBI and for the U-Boot I used this fork that doesn’t have (at the moment of writing) ported changes related to the Nezha D1 board.
OpenSBI building is straightforward:
1
$ CROSS_COMPILE=riscv64-linux-gnu- make PLATFORM=generic PLATFORM_DEFCONFIG=allwinner LATFORM_RISCV_XLEN=64 -j7
To build U-Boot with OpenSBI I used the following commands:
1
2
3
$ CROSS_COMPILE=riscv64-linux-gnu- make ARCH=riscv nezha_defconfig
$ export OPENSBI=<path to opensbi repo>/build/platform/generic/firmware/fw_dynamic.bin
$ CROSS_COMPILE=riscv64-linux-gnu- make V=1 VERBOSE=1 ARCH=riscv
Now we can write the fused bootloader into microSD card:
1
$ sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdX bs=512 seek=16
Once the bootloader is in we can create a rootfs and build a Linux kernel. To set up the rootfs one can use this small article with a few additions:
-
Pick Arch Linux rootfs ported to rv64gc.
-
QEMU and binfmt might help with tweaking the system, bootloader, etc on the x86 machine.
A custom Linux kernel is needed because of specific patches needed for peripheral of the board to be able to work. As far as I know, at the moment, the mainline Linux kernel doesn’t have these patches merged in so far. I used the following repo that has the patches for the board. To build it (/mnt
is where the microSD is mounted on) and install:
1
2
3
$ CROSS_COMPILE=riscv64-linux-gnu- make V=1 VERBOSE=1 ARCH=riscv nezha_defconfig
$ make VERBOSE=1 ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- INSTALL_HDR_PATH=/mnt/usr headers_install
$ make VERBOSE=1 ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- INSTALL_MOD_PATH=/mnt/ modules_install
And that’s it. Now you should be able to put the microSD in and boot the system up.