How to boot the A10 or A20 over the network

Prerequisites
You'll need a Linux box, a microSD card, a card reader and a serial console adapter for this tutorial. I've used VirtualBox on my Win8 x64 host with an Ubuntu 10.04 x64 guest and connected the SD card directly to the VM using the USB gateway feature of Virtualbox.


 * Get a toolchain


 * Build U-Boot


 * Prepare an SD Card
 * Please follow instructions in Bootable_SD_card and Bootable SD card


 * SD Card is now ready to take for a spin. Put it into your board and connect your serial console and fire up a terminal on your host PC so you can interact with u-boot. Now power on the board. After booting you should see something like this:

U-Boot SPL 2013.01-05621-gb7b6374 (Jan 18 2013 - 23:01:07) Board: Cubieboard DRAM: 1024MB SUNXI SD/MMC: 0 U-Boot 2013.01-05621-gb7b6374 (Jan 18 2013 - 23:01:07) Allwinner Technology CPU:  SUNXI Family Board: Cubieboard I2C:  ready DRAM: 1 GiB MMC:  SUNXI SD/MMC: 0 In:   serial Out:  serial Err:  serial Net:  wemac Hit any key to stop autoboot: 0 sun4i#

I've stopped autoboot because we don't have any partitions on the SD card yet so it'll not succeed booting.

TFTP/NFS booting with the A10

 * Let's bring up the ethernet interface.
 * First we must set the ethaddr variable to the MAC address of the NIC on the board. Probably you'll have no clue what's yours just like me. For testing purposes you can use something dummy like this:

sun4i#setenv ethaddr 12:34:56:78:99:aa


 * but please don't do this in production environment. I've also recommend you to use

sun4i#setenv autoload no


 * because by default once you execute the next 'dhcp' command and autoload is enabled it will automatically try to load an image from TFTP, named as the ip address in hex followed by .img, which is not really useful for us.


 * Let's save this config to the SD card so you won't have to type it again next time

sun4i#saveenv Saving Environment to MMC...   Writing to MMC(0)... done


 * Now request an IP address via DHCP. Connect your ethernet cable and type 'dhcp' into u-boots prompt.

sun4i#dhcp ENET Speed is 100 Mbps - FULL duplex connection BOOTP broadcast 1 DHCP client bound to address 192.168.1.206
 * Now you're ready to try out TFTP or NFS. I'm using TFTP in this example but NFS work similarly. See the u-boot manual or type 'help' into the u-boot terminal to get help on other commands.


 * You have to specify the server IP address where the TFTP server is running. You can pass this to the 'tftp' command or save it permanently in the environment:

setenv serverip 192.168.1.202 saveenv
 * Let's say you now have a TFTP server running on the IP address saved above and serving files and have a kernel named 'kernel' in the server file system. Type

tftp kernel to load it to the default address 0x50000000 in the SRAM:

sun4i#tftp kernel Using wemac device TFTP from server 192.168.1.202; our IP address is 192.168.1.206 Filename 'kernel'. Load address: 0x50000000 Loading: ################################################################# #################################################################            #################################################################             #################################################################             #################################################################             #################################################################             #################################################################             #################################################################             #################################################################             #################################################################             #################################################################             #################################################################             #####################################################             266.6 KiB/s done Bytes transferred = 4261224 (410568 hex)


 * Now if you've prepared the kernel for booting with u-boot's mkimage tool you can execute

bootm
 * to boot the kernel you've just downloaded. This is not really useful because the kernel has no rootfs to work with right now. You can download the rootfs similarly to the SRAM of the board or use an NFS share to host this. See the u-boot documentation to know how to do this.

Web resources

 * I've found this wiki page quite useful for explaining the kernel booting with u-boot: http://processors.wiki.ti.com/index.php/Booting_Linux_kernel_using_U-Boot


 * You can read more about mkimage's usage here: http://www.linuxfordevices.com/c/a/Linux-For-Devices-Articles/Introduction-to-Das-UBoot-the-universal-open-source-bootloader/


 * I followed this tutorial to fire up a TFTP server in Ubuntu: http://www.davidsudjiman.info/2006/03/27/installing-and-setting-tftpd-in-ubuntu/ I've installed this into to VM I'm compiling stuff to the Cubieboard and set Virtualbox to bridge the internal NIC adapter directly to my local network where the Cubieboard is also connected. This way i have a straight VM to Cubieboard development environment.

Booting from an NFS share

 * In this tutorial I'm going to load the kernel and script.bin from the NFS share.
 * Build the kernel
 * You have to compile a custom kernel because you have to enable root NFS support to work with NFS mounted root filesystems. Follow the build instructions described here: http://linux-sunxi.org/Linux#Building but before executing the second build command modify .config file in the kernel's source directory to contain the following lines:

CONFIG_IP_PNP=y CONFIG_ROOT_NFS=y
 * You might get some question from the next build command but you just have to say yes when it asks for the values above. You'll find the built kernel at arch/boot/uImage if you did everything right.


 * Prepare NFS share
 * I'm using Ubuntu 10.04 for this, you have to install the required package

apt-get install nfs-kernel-server
 * Create a share directory.

mkdir -p /var/nfsexport/arch/
 * Edit /etc/exports to include this directory. Put the following line to the end:

/var/nfsexport *(rw,sync,no_root_squash,no_subtree_check)
 * Finally restart the daemon

/etc/init.d/nfs-kernel-server restart
 * Copy required files
 * Copy uImage from the first step to /var/nfsexport/arch/
 * We have to build a script.bin file for the kernel to work properly. Clone the https://github.com/linux-sunxi/sunxi-boards and https://github.com/linux-sunxi/sunxi-tools repository and compile sunxi tools (make). After that you have to convert your boards fex file with the fex2bin you've just built. In my case:

./sunxi-tools/fex2bin sunxi-boards/sys_config/a10/cubieboard.fex > script.bin
 * Copy script.bin next to the kernel
 * Download and extract Arch rootfs image. I'm using the MeleA100 image from the Arch ARM Linux site. Extract it to the NFS export folder:

wget http://archlinuxarm.org/os/ArchLinuxARM-sun4i-latest.tar.gz  tar xzf ArchLinuxARM-sun4i-latest.tar.gz -C /var/nfsexport/arch/
 * Configure uboot
 * Boot into uboot with the serial console attached and halt autoboot by pressing a key
 * Modify bootargs. You have to replace serverip with your NFS server's IP.

setenv serverip  setenv bootcmd "nfs 0x43000000 ${serverip}:/var/nfsexport/arch/script.bin; nfs 0x48000000 ${serverip}:/var/nfsexport/arch/uImage; bootm 0x48000000" setenv bootargs "console=ttyS0,115200 noinitrd root=/dev/nfs nfsroot=${serverip}:/var/nfsexport/arch ip=${ipaddr}:${netmask}:${gatewayip}:::eth0" saveenv
 * Reset the board


 * Known bugs if using Arch Linux rootfs:
 * Reboot is not working; network interface is stopped but Arch wants to write something to the NFS mount which can't be done after that.
 * No output on HDMI but you can interact with Arch through the serial console or by using an SSH client and connect to the IP you've specified in uboot.

Yet another configuration
setenv bootargs ' ' setenv nfsargs 'setenv bootargs console=ttyS0,115200 root=/dev/nfs nfsroot=${serverip}:/home/nfs/arch mac_addr=${ethaddr}     ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}::eth0:::' setenv bootcmd 'dhcp; run nfsargs; nfs 0x43000000 ${serverip}:/home/nfs/arch/script.bin;  nfs 0x48000000$ ${serverip}:/home/nfs/arch/uImage;     bootm 0x48000000' setenv serverip 10.0.0.109 #in my case NFS server setenv ethaddr 00:4e:56:a1:45:01 #the MAC i choose saveenv #"/home/nfs/arch" is the path in my nfs server

Troubleshooting

 * Make sure bootargs are enclosed in double quotes ("")