YOCTO uBoot: How to add support for a custom board (or OpenRex)

Here you will find information about how to get the YOCTO uBoot source code, how to modify it for your custom board and how to test it. As an example, we will be porting uBoot on OpenRex board.

Content

See also


Important: Before you start, be sure you go through the previous chapter: How to prepare a Host machine for YOCTO

uBoot: Upload the original YOCTO source code to github

Be sure you start with an empty meta-openrex (no patches inside). Run this to get a clean starting source code:
cd ~/fsl-community-bsp/ //run this command in case bitbake is not found, otherwise you don't have to run it
source setup-environment build //run this command in case bitbake is not found, otherwise you don't have to run it
cd ~/fsl-community-bsp/build/
bitbake -c clean u-boot-fslc
bitbake -c compile -f u-boot-fslc
bitbake core-image-minimal
We need to do a small correction for github (because we would like to work with our own github, not the YOCTO one). Delete the old .git:
cd ~/fsl-community-bsp/build/tmp/work/imx6qsabresd-poky-linux-gnueabi/u-boot-fslc/v2015.10+gitAUTOINC+1b6aee73e6-r0/git
rm -rf .git
and edit .gitignore
nano .gitignore
Go on the end of the file and add following line (a folder .pc/ is added during applying patches and we dont want to have it in github):
/.pc/*
We need to upload the original YOCTO u-Boot source code to our own github. Create a new repository and put it there.
cd ~/fsl-community-bsp/build/tmp/work/imx6qsabresd-poky-linux-gnueabi/u-boot-fslc/v2015.10+gitAUTOINC+1b6aee73e6-r0/git
git init
git add .
git commit -m 'Initial version'
git remote add origin https://github.com/FEDEVEL/openrex-uboot-v2015.10.git
git push -u origin master
I normally also create a branch (I use the same name as the YOCTO branch):
git branch jethro
git push origin jethro
Change to the branch 'jethro':
git checkout jethro

uBoot: How to add support for OpenRex (Or your custom board)

Now the hard part. Very often, there are differences between software versions. Therefore, there are no general instruction how to add custom support into the software. You may need to figure out by yourself what everything has to be changed and added to support a new board.

One of the ways how to do it, is to search for files with your reference board name. For example, in our case we look for "TARGET_MX6SABRESD":
cd ~/fsl-community-bsp/build/tmp/work/imx6qsabresd-poky-linux-gnueabi/u-boot-fslc/v2015.10+gitAUTOINC+1b6aee73e6-r0/git
grep -r "TARGET_MX6SABRESD"
Here are the results:
arch/arm/cpu/armv7/mx6/Kconfig:config TARGET_MX6SABRESD
arch/arm/cpu/armv7/mx6/Kconfig~:config TARGET_MX6SABRESD
mx6qsabresd_config/.config:CONFIG_TARGET_MX6SABRESD=y
mx6qsabresd_config/include/config/auto.conf:CONFIG_TARGET_MX6SABRESD=y
mx6qsabresd_config/include/generated/autoconf.h:#define CONFIG_TARGET_MX6SABRESD 1
board/freescale/mx6sabresd/Kconfig:if TARGET_MX6SABRESD
configs/mx6dlsabresd_defconfig:CONFIG_TARGET_MX6SABRESD=y
configs/mx6qsabresd_defconfig:CONFIG_TARGET_MX6SABRESD=y
configs/mx6sabresd_spl_defconfig:CONFIG_TARGET_MX6SABRESD=y

Start editing and adding the files

Edit: "arch/arm/cpu/armv7/mx6/Kconfig"
cd ~/fsl-community-bsp/build/tmp/work/imx6qsabresd-poky-linux-gnueabi/u-boot-fslc/v2015.10+gitAUTOINC+1b6aee73e6-r0/git 
gedit arch/arm/cpu/armv7/mx6/Kconfig
Find "TARGET_MX6SABRESD" and add:
config TARGET_MX6OPENREX
	bool "mx6openrex"
	select SUPPORT_SPL
	select DM
	select DM_THERMAL
This is how it will look:
config TARGET_MX6SABRESD
	bool "mx6sabresd"
	select SUPPORT_SPL
	select DM
	select DM_THERMAL

config TARGET_MX6OPENREX
	bool "mx6openrex"
	select SUPPORT_SPL
	select DM
	select DM_THERMAL

config TARGET_MX6SLEVK
	bool "mx6slevk"
	select SUPPORT_SPL
Into the "arch/arm/cpu/armv7/mx6/Kconfig" add also:
source "board/fedevel/mx6openrex/Kconfig"
It will look like:
source "board/embest/mx6boards/Kconfig"
source "board/fedevel/mx6openrex/Kconfig"
source "board/freescale/mx6qarm2/Kconfig"
Now, create directory where our company & board specific files will be located:
cd ~/fsl-community-bsp/build/tmp/work/imx6qsabresd-poky-linux-gnueabi/u-boot-fslc/v2015.10+gitAUTOINC+1b6aee73e6-r0/git
mkdir board/fedevel
mkdir board/fedevel/mx6openrex
Edit: "board/fedevel/mx6openrex/Kconfig"
In the next steps, we will be copying the reference board files an updating them. Start with Kconfig:
cp board/freescale/mx6sabresd/Kconfig board/fedevel/mx6openrex/
gedit board/fedevel/mx6openrex/Kconfig 
Have a look inside and update it. When you finish, it will look this (board/fedevel/mx6openrex/Kconfig):
if TARGET_MX6OPENREX

config SYS_BOARD
	default "mx6openrex"

config SYS_VENDOR
	default "fedevel"

config SYS_CONFIG_NAME
	default "mx6openrex"

endif
Edit: "board/fedevel/mx6openrex/MAINTAINERS"
cp board/freescale/mx6sabresd/MAINTAINERS board/fedevel/mx6openrex/
gedit board/fedevel/mx6openrex/MAINTAINERS 
When you edit MAINTAINERS of your reference board, you will find there also a list of the files which you need to edit. This is how "MAINTAINERS" file will look when you are finished:
MX6OPENREX BOARD
M:	Robert Feranec <info@fedevel.com>
S:	Maintained
F:	board/fedevel/mx6openrex/
F:	include/configs/mx6openrex.h
F:	configs/mx6dlopenrex_defconfig
F:	configs/mx6qopenrex_defconfig
F:	configs/mx6openrex_spl_defconfig
*Note: don't forget to remember all the files and directories which you will need to create: board/fedevel/mx6openrex/, mx6openrex.h, mx6dlopenrex_defconfig, mx6qopenrex_defconfig, mx6openrex_spl_defconfig

Edit: "board/fedevel/mx6openrex/Makefile"
cp board/freescale/mx6sabresd/Makefile board/fedevel/mx6openrex/
gedit board/fedevel/mx6openrex/Makefile
Here is an example of the new content of the Makefile:
#
# Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
#
# (C) Copyright 2011 Freescale Semiconductor, Inc.
#
# SPDX-License-Identifier:	GPL-2.0+
#

obj-y  := mx6openrex.o 
Edit: "configs/mx6dlopenrex_defconfig"
cp configs/mx6dlsabresd_defconfig configs/mx6dlopenrex_defconfig
gedit configs/mx6dlopenrex_defconfig
Content of "configs/mx6dlopenrex_defconfig" after you update it:
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6OPENREX=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/fedevel/mx6openrex/mx6dlopenrex.cfg,MX6DL"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
CONFIG_SPI_FLASH=y
Edit: "configs/mx6qopenrex_defconfig"
cp configs/mx6qsabresd_defconfig configs/mx6qopenrex_defconfig
gedit configs/mx6qopenrex_defconfig
Content of "configs/mx6qopenrex_defconfig" after you update it:
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6OPENREX=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/fedevel/mx6openrex/mx6q_4x_mt41j256.cfg,MX6Q"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
CONFIG_SPI_FLASH=y
Edit: "configs/mx6openrex_spl_defconfig"
cp configs/mx6sabresd_spl_defconfig configs/mx6openrex_spl_defconfig
gedit configs/mx6openrex_spl_defconfig
Content of "configs/mx6openrex_spl_defconfig" after you update it:
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6OPENREX=y
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6Q"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
CONFIG_SPI_FLASH=y

Edit board related files

Now it's getting even more complicated. You will need to update board specific files according to your hardware. I am going to mention some of the changes I made. Advice: Initially, only do minimal changes and try to compile the uBoot. If it compiles correctly, start doing more and more changes.

Edit: "include/configs/mx6openrex.h"
cp include/configs/mx6sabresd.h include/configs/mx6openrex.h
gedit include/configs/mx6openrex.h
Based on what was inside the mx6openrex.h we can immediately see, that we need to create also mx6openrex_common.h. Again, initially use the reference board file:
cp include/configs/mx6sabre_common.h include/configs/mx6openrex_common.h
gedit include/configs/mx6openrex_common.h
Now update mx6openrex.h and change the following line:
#include "mx6sabre_common.h"
Replace it with:
#include "mx6openrex_common.h"
Have a look inside the reference board directory ("board/freescale/mx6sabresd/") and copy the rest of the files to our board directory (board/fedevel/mx6openrex/). Rename them accordingly. Always have a look inside the files:
cp board/freescale/mx6sabresd/mx6dlsabresd.cfg board/fedevel/mx6openrex/mx6dlopenrex.cfg
gedit board/fedevel/mx6openrex/mx6dlopenrex.cfg

cp board/freescale/mx6sabresd/mx6q_4x_mt41j128.cfg board/fedevel/mx6openrex/mx6q_4x_mt41j256.cfg
gedit board/fedevel/mx6openrex/mx6q_4x_mt41j256.cfg

cp board/freescale/mx6sabresd/mx6sabresd.c board/fedevel/mx6openrex/mx6openrex.c
gedit board/fedevel/mx6openrex/mx6openrex.c
After you finish, compare if you have similar files in "board/freescale/mx6sabresd/" and "board/fedevel/mx6openrex/"

Edit: "README.md"
Update or create README.md file. Add some info about how to compile the software for your board. It may look like this:
# openrex_uboot_v2015_10
mx6q/dl/s/spl openrex u-boot v2015.10 

# Download repository
    git clone https://github.com/FEDEVEL/openrex-uboot-v2015.10.git
    cd openrex-uboot-v2015.10

# Install cross compiler
    apt-get install gcc-arm-linux-gnueabihf

# Setup cross compiler
    export CROSS_COMPILE=arm-linux-gnueabihf-
    export ARCH=arm

# Build (imx6q)
    make distclean
    make mx6qopenrex_config
    make
    cp u-boot.imx /tftp/uboot-mx6qopenrex.imx

# Build (imx6dl)
    TODO

# Build (imx6s)
    TODO

uBoot: Test to compile your new custom board source code

*Note: if you are having problems with compilation, read README.md file >

Install & select cross compiler

If you do not have any compiler installed (or you are not sure)
sudo apt-get install gcc-arm-linux-gnueabihf
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm
If you have a compiler installed
export CROSS_COMPILE=/opt/freescale/usr/local/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-none-linux-gnueabi-
export ARCH=arm

Compile

As I mentioned before, for the very first compilation only do minimum changes in the source code. Basically all your new custom board files will be still the reference board files (just renamed). Now, try to compile it:
cd ~/fsl-community-bsp/build/tmp/work/imx6qsabresd-poky-linux-gnueabi/u-boot-fslc/v2015.10+gitAUTOINC+1b6aee73e6-r0/git
make distclean
make mx6qopenrex_config
make
IMPORTANT NOTE: The "mx6qopenrex_config" parameter in "make" command is the name of file you have created as defconfig (in our case "mx6qopenrex_defconfig"). Just remove "def".

When you try to compile it, you may see some small errors. Try to fix them, it should not be very difficult. For example, for OpenRex I had to do do:
mkdir board/fedevel/common
cp board/freescale/common/pfuze.h board/fedevel/common/
cp board/freescale/common/pfuze.c board/fedevel/common/
cp board/freescale/common/Makefile board/fedevel/common/
gedit board/fedevel/common/Makefile

uBoot: How to compile

*Note: if you are having problems with compilation, read README.md file >

Now, you can start doing changes. For the very first compilation, run all these commands:
cd ~/fsl-community-bsp/build/tmp/work/imx6qsabresd-poky-linux-gnueabi/u-boot-fslc/v2015.10+gitAUTOINC+1b6aee73e6-r0/git
make distclean
make mx6qopenrex_config
make
However, most of the time, you can only use "make", that will re-compile the files you changed:
make

uBoot: Useful stuff

Initially, I had to edit following files:
README.md
arch/arm/cpu/armv7/mx6/Kconfig
board/fedevel/common/Makefile
board/fedevel/mx6openrex/Kconfig
board/fedevel/mx6openrex/MAINTAINERS
board/fedevel/mx6openrex/Makefile

//config files
configs/mx6dlopenrex_defconfig
configs/mx6openrex_spl_defconfig
configs/mx6qopenrex_defconfig

//add SPI support
drivers/mtd/spi/sf_internal.h
drivers/mtd/spi/sf_ops.c
drivers/mtd/spi/sf_params.c

//board files
include/configs/mx6openrex.h
include/configs/mx6openrex_common.h
board/fedevel/mx6openrex/mx6openrex.c
board/fedevel/mx6openrex/mx6q_4x_mt41j256.cfg
board/fedevel/mx6openrex/mx6dlopenrex.cfg
Here you can see detailed description of all the changes I have done FEDEVEL/openrex-uboot-v2015.10 Commit: Initial updates to support OpenRex >

Useful files when you will be updating pin assigment:
arch/arm/include/asm/imx-common/iomux-v3.h
arch/arm/include/asm/arch-mx6/mx6q_pins.h

uBoot: Trying and testing the freshly compiled uBoot

When you would like to try your new uBoot, initially you may want to run it from MFGTOOL. It's fast and easy comparing to flashing it on SD or to SPI flash. Also, some of your uBoot compilations may not start properly and if you are trying it from SD or SPI, you may not be able to reflash it and you would be stuck. So, just use MFGTOOL, here you will find some info how: Run uBoot on an empty board >

IMPORTANT: To test your uBoot, you will need to use the u-boot.imx located at "~/fsl-community-bsp/build/tmp/work/imx6qsabresd-poky-linux-gnueabi/u-boot-fslc/v2015.10+gitAUTOINC+1b6aee73e6-r0/git". DO NOT USE u-boot.bin, it will not work!

IMPORTANT: When you use MFGTOOL and your OpenRex board has eFuses programmed (it probably has) do not forget to fit jumper JP2!

uBoot: Flashing

Once you are done with editing and testing uBoot through MFGTOOL, you can flash it. First, do not forget to copy the uBoot image on your Ubuntu 14 host machine to "/tftp" directory:
cd ~/fsl-community-bsp/build/tmp/work/imx6qsabresd-poky-linux-gnueabi/u-boot-fslc/v2015.10+gitAUTOINC+1b6aee73e6-r0/git
cp u-boot.imx /tftp/uboot-mx6qopenrex.imx
Then, go to your OpenRex board and run uBoot through MFGTOOL. *Note: you may need to set temporary ethernet variables (because ethernet will not work if your uBoot can not read environmental variables from SPI or SD ... depends if you already added that support into your source code). Switch on your OpenRex and run following commands:
setenv serverip 192.168.0.37 //this is IP address of your Ubuntu 14.04 host machine
setenv ipaddr 192.168.0.150 //this is IP address of your OpenRex board
setenv ethaddr 00:01:02:03:04:05 //this is MAC address of your board
Now, you can flash the uBoot. Run these commands on your OpenRex:
mw.b 0x10800000 0xFF 0x80000;tftp 0x10800000 u-boot-imx6q-openrex.imx;sf probe;sf erase 0x0 0x80000;sf write 0x10800000 0x400 0x80000
It will look like this:
U-Boot 2015.10+fslc+g1b6aee7 (Mar 03 2016 - 23:55:53 -0800)

CPU:   Freescale i.MX6Q rev1.2 996 MHz (running at 792 MHz)
CPU:   Automotive temperature grade (-40C to 125C) at 44C
Reset cause: POR
Board: iMX6-OpenRex
I2C:   ready
DRAM:  2 GiB
MMC:   FSL_SDHC: 0
SF: Detected SST26VF032B with page size 256 Bytes, erase size 4 KiB, total 4 MiB
In:    serial
Out:   serial
Err:   serial
Net:   FEC
Hit any key to stop autoboot:  0
OpenRex U-Boot> setenv serverip 192.168.0.37
OpenRex U-Boot> setenv ipaddr 192.168.0.150
OpenRex U-Boot> setenv ethaddr 00:01:02:03:04:05
OpenRex U-Boot> mw.b 0x10800000 0xFF 0x80000;tftp 0x10800000 u-boot-imx6q-openrex.imx;sf probe;sf erase 0x0 0x80000;sf write 0x10800000 0x400 0x80000
Using FEC device
TFTP from server 192.168.0.37; our IP address is 192.168.0.150
Filename 'u-boot-imx6q-openrex.imx'.
Load address: 0x10800000
Loading: #################################################################
         ###########
         829.1 KiB/s
done
Bytes transferred = 384000 (5dc00 hex)
SF: Detected SST26VF032B with page size 256 Bytes, erase size 4 KiB, total 4 MiB
SF: 524288 bytes @ 0x0 Erased: OK
device 0 offset 0x400, size 0x80000
SF: 524288 bytes @ 0x400 Written: OK
OpenRex U-Boot>
Unconnect power and connect it back to check if the board boots up oki. IMPORTANT! Do not forget to remove jumper JP2!

DON'T FORGET: Normally, OpenRex is shipped with eFuses set to boot up from SPI. In case you have a board from production with unprogrammed eFuses, you may need to have a look at: How to update eFuses (“fuse” command)

uBoot: Upload your changes to github

When you are happy with your source code, you can upload it to github. In case you would like to contribute to OpenRex source code, use pull request. If you have your own github, run following commands:
 
git branch #check branch, should be jethro
git status #check all the changes you done, are they correct?
git add . #if status shows the correct files, use . to add all at once, if not, add each file individually
git diff origin/jethro
git commit -m 'Initial updates to support OpenRex' #use your own comment, describe what you have done
git push origin jethro