Allwinner Nezha

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.

= Identification =

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 AWDL logo. The newer version has the AWDL anagram silkscreened on the front 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:
 * https://d1.docs.allwinnertech.com?device=d1nezha#serial (with #serial replaced by the serial number)

= General Notes = The device is are sometimes being shipped with an SD with Debian installed. Console logs: https://gist.github.com/heitbaum/e4dceeb7b236560b94cc66fce91cdd11

Sometimes the device only ships with TinaLinux in NAND. Console logs booting into TinaLinux: https://ovsienko.info/D1/minicom1.cap.txt

The Debian images for the D1 can be found here: https://ovsienko.info/D1/

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

= Sunxi support =

Current status
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.

U-Boot
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: https://github.com/smaeul/sun20i_d1_spl

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 https://github.com/smaeul/sun20i_d1_spl -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 popd

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.

OpenSBI
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 https://github.com/smaeul/opensbi -b d1-wip pushd opensbi CROSS_COMPILE=riscv64-linux-gnu- PLATFORM=generic FW_PIC=y make popd

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 https://github.com/smaeul/u-boot -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: [opensbi] file = ../opensbi/build/platform/generic/firmware/fw_dynamic.bin addr = 0x40000000 [dtb] file = arch/riscv/dts/sun20i-d1-nezha.dtb addr = 0x44000000 [u-boot] file = u-boot-nodtb.bin addr = 0x4a000000

Now, continuing in the U-Boot build 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</tt> in boot0.) sudo dd if=u-boot.toc1 of=/dev/sdX bs=512 seek=32800

(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.)

Mainline kernel
A WIP branch is available at https://github.com/smaeul/linux/commits/riscv/d1-wip which supports enough hardware for headless use (Audio, Ethernet, MMC, NAND, USB). It relies on some T-HEAD MMU patches that may not get merged upstream.

Use the sun20i-d1-nezha.dtb device-tree binary.

= Tips, Tricks, Caveats =

FEL mode
The FEL</tt> button triggers FEL mode.

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

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 - http://mirrors.perfxlab.cn/debian-ports 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 Configuration file wrong or corrupted
 * 1) fw_printenv

Default Firmware Environment
The default firmware environment for the InaLinux board:

root[at]TinaLinux:/# fw_printenv earlyprintk=sunxi-uart,0x02500000 initcall_debug=0 console=ttyS0,115200 nand_root=/dev/ubiblock0_5 mmc_root=/dev/mmcblk0p5 mtd_name=sys rootfstype=squashfs root_partition=rootfs boot_partition=boot init=/sbin/init loglevel=8 cma=8M mac= wifi_mac= bt_mac= specialstr= keybox_list=widevine,ec_key,ec_cert1,ec_cert2,ec_cert3,rsa_key,rsa_cert1,rsa_cert2,rsa_cert3 dsp0_partition=dsp0 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 boot_fastboot=fastboot bootcmd=run setargs_nand boot_dsp0 boot_normal bootdelay=0

= Adding a serial port =



The DEBUG</tt> 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.

= Pictures =

= Schematic =


 * V1.0 board schematic
 * V1.0 board layout and silkscreen

= Also known as =

= See also =


 * IndieGogo campaign
 * Data gathering thread on whycan.com (chinese)

Manufacturer images

 * D1_Nezha_HDMI_test_firmware Image from whycan.com (requires regristration)