Building u-boot for the ESPRESSObin

The ESPRESSObin is a tiny single board computer similar to the raspberry pi but with a heavy focus on networking and attached storage with its own 2 port topaz networking switch and SATA interface making it ideal as a router or media server.

I got my 1GB model board over a year ago and have been using it from time to time with openwrt and ArchLinux. My experience of using it has been pretty good, though if you look at the site for supported software and the documentation, they haven’t been updated since launch and still lists u-boot images and software from 2017.

Since I plan on using this board for many more years and don’t want to be confined to 2017 software, my goal here is to build u-boot using the latest version possible with as many up-streamed projects as I can. Unfortunately I was unable to get the up-streamed u-boot to work on my board so will be use the latest available Marvell u-boot of 2018.03-armada-18.12 with an up-streamed ARM Trusted Firmware.

mxs25fl256s SPI chip fix

Another good reason for compiling our own u-boot is that only the release u-boot image has support for the mxs25fl256s SPI chip, and none of the regular u-boot or recovery images provided by espressobin.net are able to detect and use the SPI chip. That is correct, if you flashed an image onto the board and it is using this chip it will brick u-boot into an unrecoverable state.

If you are just here because you bricked your u-boot image and don’t feel like compiling it yourself we provide pre-compiled u-boot and recovery images with the SPI patch:

The espressobin wiki has a good section on how to boot recovery images over uart so you are able to fix the board:

http://wiki.espressobin.net/tiki-index.php?page=Bootloader+recovery+via+UART

Building u-boot

Disclaimer

It is entirely possible if something goes wrong that this could brick your board when flashing. If this happens you can use one of our pre-compiled recovery images by via uart or sata.

Setting up the toolchian

The ESPRESSObin board uses the Linaro toolchain for build binary kernel and system images.

to start make a directory for your new toolchain (e.g. in /home/user/toolchain)

mkdir toolchain && cd toolchian

The toolchains we will be using are the aarch64-linux-gnu and arm-linux-gnueabi which can be found at:

At time of writing (July, 2020) the latest toolchians can be got with:

wget https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabi/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabi.tar.xz

With the toolchians we can also get the checksums:

wget https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz.asc
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabi/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabi.tar.xz.asc

and verify our toolchains downloaded correctly using md5sum -c *.asc:

michael@fedora ~/toolchain » md5sum -c *.asc                                                                                        
gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz: OK
gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabi.tar.xz: OK

With the checksums being successful we can now extract the archives with:

cat *.tar | tar -xf - -i

Finally, add the toolchains to your PATH:

export PATH=$PATH:/home/michael/toolchain/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin:/home/michael/toolchain/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabi/bin

Note: make sure to change the path to where you downloaded the toolchains.

Building

Firstly create a directory for our source files, we are gonna need to pull a lot of repositories:

mkdir armada-3720 && cd armada-3720

Also for convenience as we’ll need it later set an environment variable for our source directory so we can refer back to it:

export ARMADA=/path/to/armada-3720

u-boot

The first repository we need is u-boot which we can clone using git:

git clone https://github.com/MarvellEmbeddedProcessors/u-boot-marvell -b u-boot-2018.03-armada-18.12 && cd u-boot-marvell

To build u-boot we need to set the CROSS_COMPILE variable so u-boot knows to build it with our aarch64 toolchain:

export CROSS_COMPILE=aarch64-linux-gnu-

Now we can create a .config file for the ESPRESSObin:

make mvebu_espressobin-88f3720_defconfig

With the .config we can now build u-boot using the armada-3720-espressobin device tree:

make DEVICE_TREE=armada-3720-espressobin

when building u-boot it is possibly to encounter this error:

/usr/bin/ld: scripts/dtc/dtc-parser.tab.o:(.bss+0x10): multiple definition of `yylloc'; scripts/dtc/dtc-lexer.lex.o:(.bss+0x0): first defined here

if you do no big deal, we can fix it with:

sed -i 's/^YYLTYPE yylloc;$/extern YYLTYPE yylloc;/' scripts/dtc/dtc-lexer.l 
sed -i 's/^YYLTYPE yylloc;$/extern YYLTYPE yylloc;/' scripts/dtc/dtc-lexer.lex.c

and rerun the previous make command.

If successfully built we should see a generated u-boot.bin file in your current directory.

ATF (ARM Trusted Firmware)

Next we need to build the ARM Trusted Firmware but first we require a couple more repositories that it depends on.

Go back to our armada-3720 source directory with cd $ARMADA so we can git clone the required dependencies:

git clone https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell.git -b A3700_utils-armada-18.12-fixed
git clone https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git -b mv_ddr-armada-atf-mainline

with all the dependencies we can also get the ATF repository:

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

We might not want to use master so we can also change the branch to the latest stable release right now which is v.2.3 with:

git checkout -b v2.3

We should now have everything we need to build the ATF.

Note: To build the ATF for your specifc ESPRESSObin change the DDR_TOPOLOGY variable in the make command to correspond to the memory configuation of your board:

  • ESPRESSObin DDR3 2CS 1GB: DDR_TOPOLOGY=2
  • ESPRESSObin DDR3 2CS 2GB: DDR_TOPOLOGY=7
  • ESPRESSObin DDR4 1CS 1GB: DDR_TOPOLOGY=5
  • ESPRESSObin DDR4 2CS 2GB: DDR_TOPOLOGY=6

More information about DDR_TOPOLOGY and to set a custom profile can be found in the A3700-utils-marvell repository at /tim/ddr/

Addtionally if you want to build a u-boot image for SATA change the BOOTDEV FLAG below from SPINOR to SATA.

Example, for the 1GB DDR3 ESPRESSObin using DDR_TOPOLOGY 2 we can build with:

make \
    MV_DDR_PATH=$ARMADA/mv-ddr-marvell \
    WTP=$ARMADA/A3700-utils-marvell \
    BL33=$ARMADA/u-boot-marvell/u-boot.bin \
    CLOCKSPRESET=CPU_1000_DDR_800 DDR_TOPOLOGY=2 \
    BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 DEBUG=0 \
    USE_COHERENT_MEM=0 LOG_LEVEL=20 SECURE=0 \
    all fip

After building is complete our new bootloader image flash-image.bin can be found in the build/a3700/release directory:

michael@fedora ~/git/armada-3720/arm-trusted-firmware(v2.2) » ls build/a3700/release
atf-ntim.txt  bl2      bl31.bin          fip.bin          lib         romlib        uart-images
bl1           bl2.bin  boot-image.bin    flash-image.bin  libc        sys_init.bin  uart-images.tgz
bl1.bin       bl31     boot-image_h.bin  fuse.bin         libwrapper  TIM_ATF.bin   wtmi.bin

Flashing u-boot image

Disclaimer

It is entirely possible if something goes wrong that this could brick your board when flashing. If this happens you can use one of our pre-compiled recovery images by via uart or sata.

To flash our new u-boot image we are first going to need a usb device formatted to ext4 so we can load the new bootloader

Insert your usb stick and run lsblk to list the block devices in your system:

michael@fedora ~ » lsblk
NAME                                          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda                                             8:0    0 232.9G  0 disk
└─sda1                                          8:1    0   512M  0 part  /boot/efi
└─sda2                                          8:2    0     1G  0 part  /boot
└─sda3                                          8:3    0 231.4G  0 part
  └─luks-6d3b55be-e286-48ac-9588-b344d530a547 253:4    0 231.4G  0 crypt
    ├─fedora-root                             253:5    0    30G  0 lvm   /
    ├─fedora-swap                             253:6    0     8G  0 lvm   [SWAP]
    └─fedora-home                             253:7    0   193G  0 lvm   /home
sdb                                             8:16   0 931.5G  0 disk
└─sdb1                                          8:17   0 931.5G  0 part
sdc                                             8:32   1   3.7G  0 disk
└─sdc1                                          8:33   1   3.7G  0 part

The usb device I insert is at 3.7G drive /dev/sdc (replace /dev/sdX with the id of your usb drive), first we are going to make sure its clean writing zeros to the beginning of the drive (this will wipe the drive and make anything on it currently unaccessible):

sudo dd if=/dev/zero of=/dev/sdX bs=1M count=16 # replace /dev/sdX

Partition the drive for ext4:

sudo parted -s /dev/sdX mklabel msdos
sudo parted -a opt /dev/sdX mkpart primary ext4 0% 100%

Now format the drive with:

sudo mkfs.ext4 /dev/sdX1

We can now mount the the usb drive and copy over the flash-image.bin for our u-boot bootloader:

sudo mkdir /mnt/usb
sudo mount /dev/sdX1 /mnt/usb
sudo cp /path/to/flash-image.bin /mnt/usb
sudo umount /mnt/usb

With the drive unmounted plug it into the USB 3.0 port on the ESPRESSObin and connect the board via serial and power it on.

sudo screen /dev/ttyUSB0 115200,cs8,-ixon,-ixoff,-istrip

From the serial console run usb start to check if the usb device has been detected:

Marvell>> usb start
starting USB...
USB0:   Register 2000104 NbrPorts 2
Starting the controller
USB XHCI 1.00
USB1:   USB EHCI 1.00
scanning bus 0 for devices... 2 USB Device(s) found
scanning bus 1 for devices... 1 USB Device(s) found
scanning usb for storage devices... 1 Storage Device(s) found

We can now also check the filesystem on the usb drive to see our flash-image.bin:

Marvell>> ext4ls usb 0 /
<DIR>       4096 .
<DIR>       4096 ..
<DIR>      16384 lost+found
          944092 flash-image.bin

Lastly now using the bubt command flash your flash-image.bin to the board with:

Marvell>> bubt flash-image.bin spi usb

Once done run reset to reboot into the new u-boot bootloader. To check the version of our new bootloader you can use the version command:

Marvell>> version
U-Boot 2018.03-devel-18.12.3-gc9aa92ce70-dirty (Jul 05 2020 - 22:30:10 +0100)

aarch64-linux-gnu-gcc (Linaro GCC 7.5-2019.12) 7.5.0
GNU ld (Linaro_Binutils-2019.12) 2.28.2.20170706

Congratulation you’ve successfully compiled u-boot for the espressobin.

1 Like