Allwinner Nezha

Jump to: navigation, search
Allwinner Nezha
Allwinner Nezha Front.jpg
Manufacturer Allwinner
Dimensions 85mm x 56mm x 15mm
Release Date April 2021
Website Product Page
SoC D1 @ 1.0Ghz
DRAM 512MiB/1GiB/2GiB DDR3 @ 792MHz, 2×H5TQ4G63EFR
Power DC 5V @ 2A (via OTG or dedicated USB Type-C connector)
Video HDMI (Type A - full), LVDS
Audio 3.5mm headphone plug, HDMI, microphone array board connector, I2S
Network WiFi 802.11 b/g/n (XRadioTech XR829), 10/100/1000Mbps Ethernet (Realtek RTL8211F)
Storage µSD, SPI NAND
USB 1 USB2.0 Host, 1 USB Type-C OTG

This page needs to be properly filled according to the New Device Howto and the New Device Page guide.

The Allwinner Nezha is the first D1 based board made available to the general public. It was sold through several distributors, including RVBoards and Sipeed (Indiegogo campaign).

The indiegogo campaign page states that "Nezha is Open Source". But the hardware itself is not OSHW, and the open source SDK that that page refers to requires registering for an "Allwinner account". Seems like the Nezha is just as open source as all the other devices who are based on u-boot and the linux kernel, and who follow the basic premise of the GPL.

In fact, the disclaimer that Allwinner requires you to click through reads the following: "This deliverable may not be altered, copied, reversed, sold, distributed, or otherwise engaged in commercial activities without prior written permission of the company." And they seem to be using this disclaimer since at least 2018-11-21 according to the date on that disclaimer. This disclaimer is 100% at odds with the GPL license that Allwinners whole business depends on.


There are at least two known revisions of the board. The older version is silkscreened D1_DEV_DDR3_16X2_V1_0 on the top and does not have the AWOL logo. The newer version has the AWOL anagram silkscreened on the front ( being the official documentation website with the same logo), and the identifier D1_DEV_DDR3_16X2_V1_2 on the back.

The front side of both PCB versions has a variant of the Nezha logo.

The back also has a sticker containing a QR code, with the board serial number below it. Scanning the QR code reveals the following URL:

General Notes

The device is are sometimes being shipped with an SD with Debian installed. Console logs:

Sometimes the device only ships with TinaLinux in NAND. Console logs booting into TinaLinux:

The Debian images for the D1 can be found here:

It is unknown how to boot from any of those images on the NAND only device.

Sunxi support

Current status

Work based on mainline versions of Linux/U-Boot is very much a work in progress, and nothing finished/merged is currently available.

The BSP U-Boot/kernel use a NAND layout which merges a pair of pages from consecutive blocks into a super-page. Mainline uses the physical layout as-is. So while SPI NAND contents are accessible from both mainline and BSP kernels, they are only usable by one driver or the other. For this reason, it is recommended to install mainline software to an SD card, and leave the SPI NAND alone.

Disabling the CONFIG_AW_SPINAND_SIMULATE_MULTIPLANE option in the BSP kernel should make its layout compatible with mainline, but this has not been tested.

Manual build

You can build things for yourself by following the instructions below. There are some differences from the normal build howto because it needs a modified boot0 for early MMC and DRAM init, not U-Boot SPL.

To build, you need a cross-compiler (riscv64-linux-gnu-gcc) and swig.


Boot firmware on the D1 consists of three parts, which largely correspond to the components used by 64-bit ARM SoCs:

  1. boot0 or U-Boot SPL (Secondary Program Loader) which is responsible for initializing DRAM and loading further firmware from storage.
  2. OpenSBI, which runs in machine mode and provides a standard "SBI" interface to less privileged modes. This is similar to how TF-A runs in EL3 and provides PSCI on 64-bit ARM.
  3. U-Boot proper, which initializes additional hardware and loads Linux from storage or the network.

BSP boot0 SPL

Because the early sunxi device drivers in U-Boot are tightly intertwined with the ARM architecture, and because DRAM init has not yet been reverse engineered, we are using the BSP's boot0 as SPL. Download it from here:

This version has been modified so it can be built outside the BSP's build system, so it compiles with mainline GCC, and so it cooperates better with mainline firmware binaries. See the commit history for more details. Below is the process for building it and writing it to an SD card:

git clone -b mainline
pushd sun20i_d1_spl
make CROSS_COMPILE=riscv64-linux-gnu- p=sun20iw1p1 mmc
sudo dd if=nboot/boot0_sdcard_sun20iw1p1.bin of=/dev/sdX bs=8192 seek=1

The Nezha boot ROM can read the boot0 SPL from two different locations:

  • starting at sector 16
  • starting at sector 256

The location in sector 16 is incompatible with GPT partioning which by default uses 34 sectors. In gdisk you will have to reduce the number of entries in the partition table to ≤ 56 via the expert settings. So it may be preferable to write boot0 starting at sector 256 instead:

sudo dd if=nboot/boot0_sdcard_sun20iw1p1.bin of=/dev/sdX bs=8192 seek=16

A boot message tells you which location was used for booting:

Loading boot-pkg Succeed(index=1)
Index Sector
0 16
1 256

Note that boot0 does some magic like enabling the T-HEAD ISA and MMU extensions. Those stay enabled all the way through entering Linux, which expects the custom PTE format.


Mainline OpenSBI supports the C906 out of the box, but it needs a few tweaks and a new reset driver for the sunxi watchdog. Download a patched version and compile it like so:

git clone -b d1-wip
pushd opensbi
CROSS_COMPILE=riscv64-linux-gnu- PLATFORM=generic FW_PIC=y make

BSP U-Boot

BSP U-Boot is a heavily hacked U-Boot 2018-05 branch, Which is avaliable at

The main change is the modification of Makefle to suit the Tina Linux build system.

There are some simple patches for port the BSP U-Boot to Buildroot:

Mainline U-Boot

Mainline U-Boot is very hacked up, but the basic function of booting Linux from an SD card works. Some major refactoring of the various sunxi device drivers will be needed before any RISC-V sunxi platforms can be upstreamed. Download a patched version and compile it like so:

git clone -b d1-wip
pushd u-boot
make CROSS_COMPILE=riscv64-linux-gnu- nezha_defconfig
make CROSS_COMPILE=riscv64-linux-gnu-

boot0 expects to load a TOC1 image containing OpenSBI and U-Boot (and a DTB). This is similar to, but incompatible with, mainline U-Boot SPL, which expects a FIT image.

The version of mkimage you just compiled contains rudimentary support for making TOC1 images. Since a TOC1 can contain multiple items, we must create a config file telling mkimage where to find them. Use the following content, adjusting the path to OpenSBI as needed:

file = ../opensbi/build/platform/generic/firmware/fw_dynamic.bin
addr = 0x40000000
file = u-boot.dtb
addr = 0x44000000
file = u-boot-nodtb.bin
addr = 0x4a000000

Now, continuing in the U-Boot directory, create the TOC1:

vim toc1.cfg # or your editor of choice; see above
tools/mkimage -T sunxi_toc1 -d toc1.cfg u-boot.toc1

You should get output that looks like this:

Allwinner TOC1 Image
Size: 592896 bytes
Contents: 3 items
 00000000:00000490 Headers
 00000600:00018720 => 40000000 opensbi
 00018e00:00007387 => 44000000 dtb
 00020200:00070820 => 4a000000 u-boot

Now you can write this TOC1 to your SD card. Note the large (16+ MiB) offset! You will need to leave a gap before your first partition; 20 MiB should be plenty. (Or you can change UBOOT_START_SECTOR_IN_SDMMC in include/spare_head.h in boot0.)

sudo dd if=u-boot.toc1 of=/dev/sdX bs=512 seek=32800

If boot0 fails to load from the SD card sector 32800, it falls back to loading from the backup sector 24576. So it makes sense to write a U-Boot backup there:

sudo dd if=u-boot.toc1 of=/dev/sdX bs=512 seek=24576

(While the above instructions will compile both U-Boot proper and U-Boot's SPL, this SPL is unused for now and can be ignored.)

Linux Kernel

BSP Linux Kernel

The bsp Linux Kernel is available at

You can find a simple Buildroot usage at

Mainline kernel

A WIP branch is available at which supports enough hardware for headless use (Audio, Ethernet, MMC, SPI NAND, USB). It relies on some T-HEAD MMU patches that may not get merged upstream.

Use the devicetree from U-Boot (already in DRAM at $fdtcontroladdr). Do not load a DTB from storage.

Build using:

$ make ARCH=riscv nezha_defconfig
$ make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu-

Writing the kernel to SD card

You can create an ext4 partition that holds your kernel, but that partition needs to leave a gap at the start of the disk, as described above.

In this filesystem, place the kernel in /boot/Image and in addition to this, create the file /boot/extlinux/extlinux.conf that looks similar to this:

label default
	linux /Image
	append root=/dev/mmcblk0p2 rootwait console=ttyS0,115200 earlycon=sbi ignore_loglevel init=/lib/systemd/systemd

Tips, Tricks, Caveats

Add MANUFACTURER DEVICE specific tips, tricks, Caveats and nice to have changes here.

RV 86

If you have a Lichee RV 86 Panel then build u-boot with the lichee_rv_86_panel_defconfig instead.

FEL mode

The FEL button triggers FEL mode.

The xfel tool has support for the D1 chip. Currently sunxi-fel (from Sunxi-tools) lists the SoC as unknown.


While in FEL mode, run `xfel jtag` to enable JTAG access.

Use an adjusted copy of Sipeed's config file ( ) with OpenOCD for RISC-V:

openocd --file tools/openocd/openocd-usb-sipeed.cfg
Open On-Chip Debugger 0.11.0-rc1+dev-00001-g0dd3b7fa6-dirty (2020-12-24-20:50)
Licensed under GNU GPL v2
For bug reports, read
SiPEED USB-JTAG/TTL Ready for Remote Connections
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 1000 kHz
Info : JTAG tap: riscv.cpu tap/device found: 0x08052b43 (mfg: 0x5a1 (<unknown>), part: 0x8052, ver: 0x0)
Error: riscv.cpu: IR capture error; saw 0x1f not 0x01
Warn : Bypassing JTAG setup events due to errors
Error: dtmcontrol is 0. Check JTAG connectivity/board power.
Warn : target riscv.cpu.0 examination failed
Info : starting gdb server for riscv.cpu.0 on 3333
Info : Listening on port 3333 for gdb connections
Info : accepting 'gdb' connection on tcp/3333

TODO: figure out the "examination"

Enabling U-Boot command line

The preinstalled version of U-Boot requires holding down "S" during boot to enter the command line. From a booted Linux system (like the Tina Linux preinstalled in the on-board NAND) run the following command to set a three second delay during which it's possible to enter the command line on the built-in serial port:

fw_setenv bootdelay 3

Note: With the Debian image being shipped - the fw_setenv and fw_printenv are not aligned to the saveenv location.

Debian GNU/Linux 11 RVBoards ttyS0
Linux RVBoards 5.4.61 #22 PREEMPT Wed Jun 16 07:27:49 UTC 2021 riscv64
# fw_printenv
Configuration file wrong or corrupted

Default Firmware Environment

The default firmware environment for the TinaLinux board:

root[at]TinaLinux:/# fw_printenv 
setargs_nand=setenv bootargs ubi.mtd=${mtd_name} ubi.block=0,${root_partition} earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${nand_root} rootfstype=${rootfstype} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1
setargs_nand_ubi=setenv bootargs ubi.mtd=${mtd_name} ubi.block=0,${root_partition} earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${nand_root} rootfstype=${rootfstype} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1
setargs_mmc=setenv  bootargs earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${mmc_root} rootwait  init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1
boot_dsp0=sunxi_flash read 45000000 ${dsp0_partition};bootr 45000000 0 0
boot_normal=sunxi_flash read 45000000 ${boot_partition};bootm 45000000
boot_recovery=sunxi_flash read 45000000 recovery;bootm 45000000
bootcmd=run setargs_nand boot_dsp0 boot_normal

Oops tracing

To get a valid callstack from an OOPS, you need to enable CONFIG_FRAME_POINTER or else the callstacks are not reliable.

Adding a serial port

Allwinner Nezha UART pads

The DEBUG header at the top-right corner of the board can be used as a serial port. See the UART howto for instructions about how to attach to it. The default baud rate is 115200.

Adding a reset pin

The test pin T6, as per the manual and verified, is the reset pin (RST). A wire can be attached to it, and for convenience, routed to one of the N/C (not connected) pins on the GPIO header. It can be used for test and development automation.

Development and test automation

A simple strategy for test automation and bringup development is as follows:

  • attach a wire to the FEL button (possibly route to an N/C pin on the GPIO header)
  • attach a wire to the reset pin
  • attach to the UART interface
  • connect to the USB-C OTG
  • connect to the ethernet port

To test an firmware/OS image, hold FEL, trigger reset, release FEL, then use xfel to bring up DRAM, load the image, and execute it. Watch the output on the UART, try input, and see if the device becomes visible on the network.

This can be fully automated, e.g., using another development board offering all the necessary interfaces. It can be instrumented via CI, e.g., as a GitLab runner using ConTest.



Also known as

List rebadged devices here.

See also

Manufacturer images