How to cross-compile Embedded Linux (Part 3): Buildroot

Kasi Viswanathan V Mar 02 - 10 min read

Audio : Listen to This Blog.

This is the continuation of series of blogs about cross compiling, loading bootloader, Linux kernel and filesystem into an embedded development platform. Please check the previous blog for the target hardware and setup that is needed.

In short, the embedded development platform is beaglebone black with MicroSD card. We have already partitioned the card in the first blog and please look into it for more info
So far we have compiled U-Boot, Linux kernel and then loaded the builded images into the target hardware which is beaglebone black. At the end of the Linux kernel bootup log we got an error like “No working init found”. What it actually means is that it is not able to find the init binary which can be executed. Init in *nix based machines is the parent of all the processes except the kernel threads.

Basically to solve this issue we need a filesystem which provides us the init binary.

Buildroot

Buildroot is free and open-source software, maintained by Peter Korsgaard and licensed under version 2 or later of the GNU General Public License (GPL). It is a group of Makefiles and build script files which simplifies and automates the process of building a complete embedded Linux environment. For cross compiling to different target processor it can automatically build the required cross compilation toolchain. It has the support to create bootloader, Linux kernel and a root filesystem. It builds these independently also depending upon the user input.
It is primarily intended to be used with small or embedded systems based on various computer architectures including x86, ARM, MIPS and PowerPC.Numerous architectures and it also supports their variants. It also comes with default configurations for several development platforms such as Raspberry Pi, Cubieboard, etc. It is used as the basis for many third party projects and by many product development teams as it makes the process simple. It is organized as automatically downloaded packages which contain the source code of various userspace applications, libraries and system utilities. Root file system images, which are the final results, may be built using various file systems, including cramfs, JFFS2, romfs, SquashFS and UBIFS.

kasi@kasi-desktop:~/git$ git clone git://git.buildroot.net/buildroot

Configure the Buildroot

kasi@kasi-desktop:~/git$ cd buildroot/

The following command shows the list of files that is provided by buildroot.

kasi@kasi-desktop:~/git/buildroot$ ls -l/

Now execute the following command:

kasi@kasi-desktop:~/git/buildroot$ make menuconfig/

Figure 1. Initial menu when menuconfig is executed.

We need to select “Target options” here.
In the following image (figure 2), architecture is shown as i386 by default target.

Figure 2. Target Architecture selection

We need to change that to ARM little endian as in the following image:

Figure 3. Target Architecture selection — ARM processor is selected.

Next we need to move to the Target Architecture variant option. After choosing target architecture we can see that the Target Architecture variant is set to arm926t.
Check the following image.

Figure 4. Target Architecture variant

Beagle bone black is actually based on Cortex-A8 variant and it is exactly what we need to choose.

Figure 5. Target Architecture variant — Cortex-A8 is selected.

After choosing these two parameters we need to save this config file and start the build. There are a lot of other options like choosing which C library to use and various packages selection options, for the moment let us save the config file as below.

Figure 6. Save the config file

configuration written to /home/kasi/git/buildroot/.config
*** End of the configuration.
*** Execute ‘make’ to start the build or try ‘make help'[/vc_column_text]

Build

As with other blogs we now need to give ‘make’ command to start the compilation process.

kasi@kasi-desktop:~/git/buildroot$ make

We need to wait for 15 to 20 minutes depending upon the build machine hardware specs and network bandwidth available for the build to complete.

Final Steps

Generating root filesystem image rootfs.tar
rm -f /home/kasi/git/buildroot/output/build/_fakeroot.fs
rm -f /home/kasi/git/buildroot/output/target/THIS_IS_NOT_YOUR_ROOT_FILESYSTEM
rm -f /home/kasi/git/buildroot/output/build/_users_table.txt
echo '#!/bin/sh' > /home/kasi/git/buildroot/output/build/_fakeroot.fs
echo "set -e" >> /home/kasi/git/buildroot/output/build/_fakeroot.fs
echo "chown -h -R 0:0 /home/kasi/git/buildroot/output/target" >> /home/kasi/git/buildroot/output/build/_fakeroot.fs
printf '   \n' >> /home/kasi/git/buildroot/output/build/_users_table.txt
PATH="/home/kasi/git/buildroot/output/host/bin:/home/kasi/git/buildroot/output/host/sbin:/home/kasi/git/buildroot/output/host/usr/bin:/home/kasi/git/buildroot/output/host/usr/sbin:/home/kasi/git/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf/bin:/home/kasi/bin:/home/kasi/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" /home/kasi/git/buildroot/support/scripts/mkusers /home/kasi/git/buildroot/output/build/_users_table.txt /home/kasi/git/buildroot/output/target >> /home/kasi/git/buildroot/output/build/_fakeroot.fs
cat system/device_table.txt > /home/kasi/git/buildroot/output/build/_device_table.txt
printf '   	/bin/busybox                     f 4755 0  0 - - - - -\n /dev/console c 622 0 0 5 1 - - -\n\n' >> /home/kasi/git/buildroot/output/build/_device_table.txt
echo "/home/kasi/git/buildroot/output/host/usr/bin/makedevs -d /home/kasi/git/buildroot/output/build/_device_table.txt /home/kasi/git/buildroot/output/target" >> /home/kasi/git/buildroot/output/build/_fakeroot.fs
printf '   	tar  -cf /home/kasi/git/buildroot/output/images/rootfs.tar --numeric-owner -C /home/kasi/git/buildroot/output/target .\n' >> /home/kasi/git/buildroot/output/build/_fakeroot.fs
chmod a+x /home/kasi/git/buildroot/output/build/_fakeroot.fs
PATH="/home/kasi/git/buildroot/output/host/bin:/home/kasi/git/buildroot/output/host/sbin:/home/kasi/git/buildroot/output/host/usr/bin:/home/kasi/git/buildroot/output/host/usr/sbin:/home/kasi/git/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf/bin:/home/kasi/bin:/home/kasi/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" /home/kasi/git/buildroot/output/host/usr/bin/pseudo-wrapper -- /home/kasi/git/buildroot/output/build/_fakeroot.fs
rootdir=/home/kasi/git/buildroot/output/target
table='/home/kasi/git/buildroot/output/build/_device_table.txt'
/usr/bin/install -m 0644 support/misc/target-dir-warning.txt /home/kasi/git/buildroot/output/target/THIS_IS_NOT_YOUR_ROOT_FILESYSTEM
kasi@kasi-desktop:~/git/buildroot$

The build is completed and the zipped file system is available in the following location:

kasi@kasi-desktop:~/git/buildroot$ ls output/images/
rootfs.tar
kasi@kasi-desktop:~/git/buildroot$

We need to untar this file and copy the contents into the Micro SD card’s fs partition (ext4 partition with size more than 4GB).

kasi@kasi-desktop:~/git/buildroot$ cd output/images/
kasi@kasi-desktop:~/git/buildroot/output/images$ ls
rootfs.tar
kasi@kasi-desktop:~/git/buildroot/output/images$ mount
/dev/sdc2 on /media/kasi/fs type ext4 (rw,nosuid,nodev,relatime,data=ordered,uhelper=udisks2)
/dev/sdc1 on /media/kasi/BOOT type vfat (rw,nosuid,nodev,relatime,uid=1000,gid=1000,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks2)
kasi@kasi-desktop:~/git/buildroot/output/images$

It is a better idea to copy the zip file into the Micro SD card’s fs partition and unzip it there.

kasi@kasi-desktop:~/git/buildroot/output/images$ sudo cp rootfs.tar /media/kasi/fs/
[sudo] password for kasi:
kasi@kasi-desktop:~/git/buildroot/output/images$ sync
kasi@kasi-desktop:~/git/buildroot/output/images$ cd /media/kasi/fs
kasi@kasi-desktop:/media/kasi/fs$ ls
lost+found  rootfs.tar
kasi@kasi-desktop:/media/kasi/fs$ sudo tar xf rootfs.tar
kasi@kasi-desktop:/media/kasi/fs$ ls -l
total 1488
drwxr-xr-x 2 root root	4096 Nov 18 16:48 bin
drwxr-xr-x 4 root root	4096 Nov 18 16:48 dev
drwxr-xr-x 5 root root	4096 Nov 18 16:48 etc
drwxr-xr-x 2 root root	4096 Nov 18 16:48 lib
lrwxrwxrwx 1 root root   	3 Nov 18 16:38 lib32 -> lib
lrwxrwxrwx 1 root root  	11 Nov 18 16:47 linuxrc -> bin/busybox
drwx------ 2 root root   16384 Nov  5 18:53 lost+found
drwxr-xr-x 2 root root	4096 Nov 18 16:22 media
drwxr-xr-x 2 root root	4096 Nov 18 16:22 mnt
drwxr-xr-x 2 root root	4096 Nov 18 16:22 opt
drwxr-xr-x 2 root root	4096 Nov 18 16:22 proc
drwx------ 2 root root	4096 Nov 18 16:22 root
-rw-r--r-- 1 root root 1443840 Nov 22 11:39 rootfs.tar
drwxr-xr-x 2 root root	4096 Nov 18 16:22 run
drwxr-xr-x 2 root root	4096 Nov 18 16:48 sbin
drwxr-xr-x 2 root root	4096 Nov 18 16:22 sys
drwxrwxrwt 2 root root	4096 Nov 18 16:22 tmp
drwxr-xr-x 6 root root	4096 Nov 18 16:47 usr
drwxr-xr-x 4 root root	4096 Nov 18 16:48 var
kasi@kasi-desktop:/media/kasi/fs$

The Micro SD card now contains all the needed images/binaries to boot up a complete embedded Linux machine. Remove the Micro SD card from the build machine and by following the boot procedure to boot using Micro SD card we should now be able to get the shell prompt.

Sample Log from Target

U-Boot SPL 2016.11-rc3-00044-g38cacda-dirty (Nov 14 2016 - 13:02:35)
############################
##### MSYS Technologies ####
#####   We were here	####
############################
Trying to boot from MMC1
reading uboot.env
** Unable to read "uboot.env" from mmc0:1 **
Using default environment
reading u-boot.img
reading u-boot.img
reading u-boot.img
reading u-boot.img
U-Boot 2016.11-rc3-00044-g38cacda-dirty (Nov 14 2016 - 13:02:35 +0530)
CPU  : AM335X-GP rev 2.0
Model: TI AM335x BeagleBone Black
DRAM:  512 MiB
NAND:  0 MiB
MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
reading uboot.env
** Unable to read "uboot.env" from mmc0:1 **
Using default environment
 not set. Validating first E-fuse MAC
Net:   Could not get PHY for ethernet@4a100000: addr 0
eth0: ethernet@4a100000
Hit any key to stop autoboot:  0
switch to partitions #0, OK
mmc0 is current device
SD/MMC found on device 0
reading boot.scr
** Unable to read file boot.scr **
reading uEnv.txt
193 bytes read in 3 ms (62.5 KiB/s)
Loaded env from uEnv.txt
Importing environment from mmc0 ...
Running uenvcmd ...
reading uImage
3852896 bytes read in 251 ms (14.6 MiB/s)
reading am335x-boneblack.dtb
34185 bytes read in 8 ms (4.1 MiB/s)
## Booting kernel from Legacy Image at 80008000 ...
   Image Name:   Linux-4.8.7
   Created:  	2016-11-15   9:57:37 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:	3852832 Bytes = 3.7 MiB
   Load Address: 80008000
   Entry Point:  80008000
   Verifying Checksum ... OK
## Flattened Device Tree blob at 88008000
   Booting using the fdt blob at 0x88008000
   Loading Kernel Image ... OK
   Loading Device Tree to 8fff4000, end 8ffff588 ... OK
Starting kernel ...
[	0.000000] Booting Linux on physical CPU 0x0
[	0.000000] ##################################
[	0.000000] ######   MSYS Technologies  ######
[	0.000000] ######   We were here too   ######
[	0.000000] ##################################
[	0.000000] Linux version 4.8.7 (kasi@kasi-desktop) (gcc version 6.1.1 20160711 (Linaro GCC 6.1-2016.08) ) #3 SMP Tue Nov 15 15:27:26 IST 2016
[	0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c5387d
[	1.850061] EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incompatibilities
[	1.873734] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[	1.882582] VFS: Mounted root (ext4 filesystem) readonly on device 179:2.
[	1.892735] devtmpfs: mounted
[	1.898228] Freeing unused kernel memory: 1024K (c0b00000 - c0c00000)
[	2.005862] EXT4-fs (mmcblk0p2): warning: mounting fs with errors, running e2fsck is recommended
[	2.018977] EXT4-fs (mmcblk0p2): re-mounted. Opts: data=ordered
Starting logging: OK
Initializing random number generator... done.
Starting network: OK
            	##### MSYS Technologies -- Welcome to Buildroot #####
                   	##### 	We are everywhere	#####
buildroot login: root
# uname -a
Linux buildroot 4.8.7 #3 SMP Tue Nov 15 15:27:26 IST 2016 armv7l GNU/Linux

We are able reach the shell prompt with the file system we have created.
Hope this series of blogs helps you to bring up an embedded device based on Linux.

Leave a Reply

MSys Technologies has holistic experience in IoT, Machine Learning, and Artifical Intelligence. We can be your partner if you are dabbling into the Internet of Things or are looking for a solution provider with expertise in that domain.