U-Boot combines a second and third stage bootloaders for variety of microcomputers. It is able to initialize basic hardware, like DRAM and storage, and boot main operating system. At the time of writing this article, UBoot has some basic configuration for Orange Pi Win board, which has less DRAM and other small hardware discrepancies that we would not care right now.
First, we should clone u-boot repository to the local machine:
git clone git://git.denx.de/u-boot.git
This will give us the latest (but might be not greatest) u-boot sources. Once the source tree is ready, we can take a look at the README.sunxi64 file located at u-boot/board/sunxi directory. It contains a brief description how to compile those sources and quick introduction to the boot process on A64 SoCs in general.
Few things that I want to add to this description:
You want to use aarch64 toolset to build it. On my Ubuntu 16.04 machine with x86-64 CPU I have downloaded and unpacked this version of gcc linaro tools
https://releases.linaro.org/components/toolchain/binaries/6.3-2017.05/aarch64-linux-gnu/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu.tar.xz
I was not able to use FEL or upload UBoot to built-in SPI flash. My board does not have an optional EMMC, so I have used good old 4GB microSD card.
Before starting to compile, we need to make sure that tools are ready unpacked. No need to install them into the system paths (e.g. /usr/bin). Just not the path it was unpacked, I will call it $TOOLS thereafter.
Check out and build ARM trusted firmware (ATF)
git clone https://github.com/apritzel/arm-trusted-firmware.git
cd arm-trusted-firmware
git checkout allwinner
make PLAT=sun50iw1p1 DEBUG=1 CROSS_COMPILE=$TOOLS/bin/aarch64-linux-gnu- bl31
once make is completed, copy bl31.bin to the root of u-boot repository cloned.
Tweak board config if necessary. (configs/orangepi_win_defconfig)
Configure and build u-boot:
make orangepi_win_config
make CROSS_COMPILE=$TOOLS/bin/aarch64-linux-gnu-all
This would take a while. Be patient. Hope you will see no errors.
Now, it is time to prepare the microSD card. See my layout below. You should reserve first 1MB for the UBoot as first stage bootloader in A64 ROM has no filesystem support. Therefore, it will be loading raw from predefined location.
Disk /dev/mmcblk0: 3.7 GiB, 3980394496 bytes, 7774208 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x0009694f
Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 40960 143359 102400 50M c W95 FAT32 (LBA)
/dev/mmcblk0p2 143360 7329791 7186432 3.4G 83 Linux
Save both boot loaders to the card.
dd if=spl/sunxi-spl.bin of=/dev/sdx bs=8k seek=1
dd if=u-boot.itb of=/dev/sdx bs=8k seek=5
sync
Now, insert microSD card into the board and power cycle it. Use serial console to monitor the boot process and access u-boot command prompt.
Few questions are still open:
Do we really need a dedicated FAT partition for UBoot files and Linux kernel? It seems like that UBoot has EXT2 and EXT4 support. Can this stuff coexist with RootFS?
How to initialize HDMI?
How to add support for onboard SPI flash?