Back to Articles

Compiling U-Boot for the BeagleBone Black and OSD335x

How to build a custom U-Boot for BeagleBone Black and Octavo Systems OSD335x designs

Compiling U-Boot for the BeagleBone Black and OSD335x

If you have created your own design based on the BeagleBone family, one issue you may encounter is trying to boot your board with U-Boot when the EEPROM is blank. In that case, the standard method of creating a complete system may fail.

As part of the boot process, U-Boot reads fields from the EEPROM to determine the board type for configuration. If the EEPROM is blank, U-Boot cannot read the board ID and therefore will not boot.

At that point you have two main options:

  • Hard-code the board ID
  • Recognise a blank EEPROM and treat it as a known board

Both approaches require compiling your own version of U-Boot.

Pre-Requisites for Compiling U-Boot

To compile U-Boot, you will need:

  • A Linux system. Tried and tested distributions are:
    • Debian
    • Fedora
    • Ubuntu
  • An ARM cross-compiler and toolchain, such as Linaro
  • Das U-Boot source tree

While it is easier to do this on dedicated hardware, I have also managed to compile U-Boot successfully in a virtual machine.

ARM GCC Toolchain - Linaro

While you could compile your own version of gcc and the associated toolchain, it is much easier to use a pre-built one.

Download the Toolchain

I like to keep tools under ~/tools, so you may need to adjust the following commands for your own setup:

cd ~/tools
wget -c https://releases.linaro.org/components/toolchain/binaries/6.5-2018.12/arm-linux-gnueabihf/gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf.tar.xz

Extract the Toolchain

tar xf gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf.tar.xz

Define the Cross-Compiler Prefix

This allows the host gcc and the ARM toolchain binaries to co-exist cleanly on the same system.

export CC=`pwd`/gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-

Test the Toolchain

Ensure you can run the toolchain compiler:

${CC}gcc --version

You should see output along the lines of:

arm-linux-gnueabihf-gcc (Linaro GCC 6.5-2018.12) 6.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

You will need to set the CC environment variable for each new shell session. If you use the toolchain often, it is worth adding it to your ~/.profile, replacing pwd with the actual installation path.

Das U-Boot

Downloading U-Boot is simply a matter of cloning the Git repository. I tend to keep working copies under ~/wip.

Clone U-Boot

cd ~/wip
git clone https://github.com/u-boot/u-boot
cd u-boot/
git checkout v2019.04 -b tmp

Download and Apply the Patches

wget -c https://github.com/eewiki/u-boot-patches/raw/master/v2019.04/0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
wget -c https://github.com/eewiki/u-boot-patches/raw/master/v2019.04/0002-U-Boot-BeagleBone-Cape-Manager.patch

patch -p1 < 0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
patch -p1 < 0002-U-Boot-BeagleBone-Cape-Manager.patch

Decide Which Method to Use

At this point you need to decide whether to:

  • Hard-code the board ID
  • Recognise a blank EEPROM and assume a known board

Hard-Coding the Board ID

This is the simplest option, but it is only suitable if your design is very close to the BeagleBone variant you intend to claim. It also means that if you ever want to change that identifier, you will need to build a new U-Boot binary.

In the U-Boot source tree, locate:

./board/ti/am335x/board.h

This header contains the tests used to identify each board type. To force a specific board type, simply return 1 from the relevant helper function.

To force U-Boot to always identify as a BeagleBone Black, for example:

static inline int board_is_bone_lt(void)
{
//      return board_ti_is("A335BNLT");  -- Hard code board ID to BeagleBone Black
        return 1;
}

Recognising a Blank ID

The alternative is to modify U-Boot so that if it finds a blank EEPROM, it assumes the board is a blank BeagleBone Black.

wget -c https://github.com/RobertCNelson/Bootloader-Builder/raw/master/patches/v2019.04/0003-NFM-Production-eeprom-assume-device-is-BeagleBone-Bl.patch
patch -p1 < 0003-NFM-Production-eeprom-assume-device-is-BeagleBone-Bl.patch

This also makes U-Boot look for a file at:

/boot/.eeprom.txt

It can then read variables from that file in order to program the EEPROM.

Build U-Boot

At this point you can compile U-Boot from the source directory:

make ARCH=arm CROSS_COMPILE=${CC} distclean
make ARCH=arm CROSS_COMPILE=${CC} am335x_evm_defconfig
make ARCH=arm CROSS_COMPILE=${CC}

This should create:

  • MLO (the secondary program loader)
  • u-boot.img
  • tools/mkimage

The tools/mkimage utility can also be used when programming the EEPROM.

Install U-Boot

You can then continue with installation using your normal BeagleBone Black process, skipping the bootloader build step since you have already completed it here.