Embedded Handbook/Boards/NanoPI/Neo3

Gentoo for NanoPI Neo3
The NanoPI Neo3 is Article description::a tiny IoT offered by NanoPI having many more features than initially shown This document tries to guide you how to install Gentoo on a SD card, and boot a bare system on it. Probably you'll want to keep the crossdev live, as the cortex A53 chips are not really suited for recompiling the whole device. NanoPI R2S and Neo 3 are very very similar: they only differ by a few hw features, so this guide should be a good start for R2S too. This guide focuses on a minimal setup with all performance we could get, A53 chips are made for power-saving, not performance, and as such we need to use every feature that may be useful

License
U-boot: GPL-2+ https://github.com/01org/edison-u-boot

Features List

 * working u-boot
 * booting
 * working kernel
 * able to build using crossdev
 * able to unlock special features not in standard dts
 * TODO: ddr controller

Steps to install
1. prepare the crossdev setup:

Please note that it may be useful to add multilib support for ARMv8, as it _may_ allow armv7 code to compile. Also, I prefer to use custom cflags here, as the Rockchip RK3328 chip has SIMD + crypto extensions not defined in standard ARMv8-A.

In order to tune options for gcc, glibc, ...:

other details could be found in Embedded Handbook, Run it until at compiling the kernel.

Starting from below, all packages which are not in portage are fetched into /usr/aarch64-unknown-linux-gnu/tmp

2. Prepare U-BOOT

U-boot only contains an image for NanoPi R2S, which requires a few modifications to run properly. Also, fancy stuff like boot from pxe, etc .. makes no sense because the device needs an SDcard anyway. In order to compile everything, it could be useful to download the latest ARM firmware first:

git clone https://github.com/ARM-software/arm-trusted-firmware

and then u-boot (may be useful to add -d 5 to limit the history): see here on github

Embedded Handbook/Bootloaders/Das U-Boot

This is where it becomes tricky, in order to understand, The following boot steps are important:
 * 1) initial CPU start (onboard SRAM), search for MMC card block 0x40
 * 2) initial boot loader (U-BOOT) (also referenced as idbloader)
 * 3) Second program loader (U-BOOT) (setup initial devices, buses, and loads a primary device tree)
 * 4) Tertiary program loader (U-BOOT) (runs DDR setup)
 * 5) U-BOOT executable (U-BOOT) (somewhat comparable to EFI boot loader)
 * 6) Kernel loading

Previously, steps 2-5 all required separate files on separate partitions. This is no longer the case: u-boot generates an image "u-boot-rockchip.bin" which could be written to sector 0x40 of your SD card:

Knowing this, the SDCard partition layout (using msdos here, but gpt should work as well) can be created. It is important to keep the order, size and start sector of the FAT32 boot partition. Other things like root fs, swap partition etc are not, and enjoy the flexibility of Gentoo OS.

SDCard layout
Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x31a5b84a

Device    Boot     Start       End   Sectors  Size Id Type /dev/sdd1 *        32768    262143    229376  112M  b W95 FAT32 /dev/sdd2         262144 113246174 112984031 53.9G 83 Linux /dev/sdd3      113246175 121634815   8388641    4G 82 Linux swap / Solaris

BOOT Partition
There are 2 ways U-BOOT can boot from the SDCard: 1. Using an exlinux config file 2. Using default UEFI image

It is possible to make U-BOOT load grub and configure it before booting the kernel, but the advantage of it is pretty minimal: if boot customization is required, use extlinux.

And for the extlinux.conf file:

A little explanation about the layout here:
 * 1) the boot partition contains a default EFI folder (for the kernel image), an extlinux folder (for extlinux config), and a rockchip folder for the device tree, which is necessary to present the devices to the OS.
 * 2) the EFI partition has the kernel stored as bootaarch4.efi, which makes it the default boot image in case extlinux wouldn't work.
 * 3) rockchip folder contains the dtb file (a compiled dts file) which was generated while compiling u-boot / the linux kernel.  It is located at (u-boot)/arch/arm/dts/, or use the default linux dts file in (linux source)/arch/arm64/boot/dts/
 * 4) In the extlinux folder, write something like explained above
 * 5) Default image is gento
 * 6) the kernel image is at ....
 * 7) the fdt file is at ...
 * 8) the kernel arguments are .... it could be, depending on your DTS settings, that mmcblk1 or mmcblk0 is required: if the eMMC controller of the rockchip is enabled in DTS and thus in DTB, it will take first place, even though not specified. rootwait is required, as it is not guaranteed that the MMC controller is online when Linux tries to mount the root filesystem.
 * 9) In this example, the netconsole is enabled.  This is for debugging: when something goes wrong inside the kernel, it possible to perform some diagnosis using the logs here.

if no configuration is required, simply append the kernel arguments while compiling the kernel, but the dts magic may be a little more complicated.

Setting up base system
There are a number of _essential_ things that need to be verified before gentoo can boot:
 * 1) It must be able to mount root fs (see extlinux.conf layout above)
 * 2) It must be able to run init.  This is a caveat: ARM setups tend to default to busybox, but it also replaces the /sbin/init with its own variant.  This variant does not load /etc/inittab the way openrc init does.  As such, due to these confusions, it is recommended to use init=/bin/openrc-init at kernel boot, or go for busybox all the way and remove openrc entirely

Using crossdev, a normal baselayout has already been fixed, but it's always useful to emerge it, even though already marked as "installed". Make sure every service that might be needed to bring up the devices is listed in /etc/runlevels. If not, a debug setup is required to run.

an example listing of /usr/aarch64/etc/init.d/sysinit

and boot:

And at last some defaults:

It is always a good idea to include both a telnet and ssh server: even though you don't need telnet or ssh, if the first one fails you could continue with the other one. The people constrained about the ram usage of ssh server or telnetd could use xinetd, but there should _always_ be a failover scenario in case xinetd fails.

Creating a kernel
Every kernel has a number of default config files.