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:
- https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64_be-linux-gnu/
- https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabi/
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 theA3700-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.