Monday, December 29, 2014

Creating a custom Linux distribution for an ARM Cortex-A9 SBC

The Yocto project provides an ideal platform for building a custom Linux distribution.  It's design was intended to model a machine.  The Yocto project or machine should take a number of inputs and produce an output.  The inputs to the machine are the specifications for the Linux distribution.  The output of the machine is the Linux distribution.

 

The Yocto project is the most widely supported system for building custom Linux distributions.
The Yocto project is very well supported by both communities and companies.  The project consists of a tool called bitbake and a build system that is based off of OpenEmbedded.  Together, these two components along with a defined set of metadata comprise what is called the Poky reference platform.

Yocto supports numerous architectures through OpenEmbedded. These include x86, ARM®, MIPS, and PowerPC.  Yocto's most attractive feature is its support of what are called layers.  Layers allow the abstraction of individual components or sets of components within a board support package (BSP). New layers can be derived from existing layers to enhance functionality, patch source code, or remove subsets of unneeded components.  

Building support for a custom boot loader, custom kernel, custom rootfs, and development application layer is both very clean and straightforward.  SELinux has become a necessary component of almost every Linux distribution.  It is very simple to integrate SELinux into Yocto via an OpenEmbedded layer.   Consequently, building a "Carrier Grade" Linux distribution for one of the many (several hundred) processors is attainable in a short amount of time.

Embest Technology created the RIoTboard.  The board design is fairly simple.  The board contains an i.MX 6 Solo processor.  Embest Technology and Element 14 provide links to download prebuilt Linux and Android images.  Embest Technology also has a github repository where source code can be downloaded to build a complete BSP.  The complete BSP consists of the u-boot boot loader, kernel, and root filesystem.

Embest Technology took a snapshot of the Freescale Community BSP Platform source code repository at some point in the past.  The BSP source download from github, which consists of the Yocto layers for building a riotboard BSP, is not up to date with Freescale, Yocto, and OpenEmbedded.

Consequently, Freescale's community BSP platform will be used.  The platform is comprised of both the Poky reference build system and an additional series of layers which will allow us to build a custom Linux distribution for the i.MX 6 processor architecture.  

A custom Linux distribution that will be used for development should include support for only the peripheral components that will be used. The custom development distribution should be minimized to the maximum extent possible.  All I/O interfaces should be clearly documented.  Bootable media types should be documented and partition maps should be created.  These steps greatly ease development and debugging, and prevent unknown issues from cropping up after production release.  Layering in SELinux at a later time is simple.  Creating new layers for shared library development, or userspace application development is also simple and layers can be added for slicing out pieces of the kernel that aren't now, but may be needed later on.  Last but not least, blowing the appropriate fuses prior to production is critical.

To keep things simple, a new BSP or custom Linux distribution will be derived from the riotboard specifications that have already been incorporated into Freescale's community BSP platform.  

The goal here is to produce a minimal Linux distribution that can be used for development and easily extended from any level in the stack - u-boot, kernel, root filesystem, and userspace libraries or executables.  Most importantly, the architecture of this distribution will conform to the standards that have been outlined by the Yocto Project and OpenEmbedded.  This means anyone can easily pick up.

The input specifications for a generic i.MX 6 solo machine have been mostly documented in the meta-fsl-arm-extra layer.  The output image that is produced from these input specifications is an image that consists of the u-boot boot loader, i.MX 6 Solo/Dual kernel, and ext3 root filesystem.
In an effort to build a custom Linux distribution for the i.MX 6 Solo/Dual with the least amount of packages in the shortest amount of time, slimming down the input specifications, configuring the distribution, and naming it should only require modification of a few files.  Here are the steps.

First, the riotboard or target must be connected to the Fedora 20 x86_64 host via serial UART (see last blog post).  A card reader must be connected to the host via USB. 

The new distribution will be called the bsec distribution.  The bsec distribution will consist of a minimal Linux image, u-boot boot loader, and ext3 root filesystem configured for the i.MX 6 based riotboard.

Perform the following steps on the host.

1.  Pull the Freescale community BSP platform source code from github.  Dizzy is the Yocto 1.7.1 branch.   Execute the following commands on the host.

 $ mkdir $HOME/bin  
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x $HOME/bin/repo
$ echo "PATH=$PATH:$HOME/bin" >> $HOME/.bashrc
$ source .bashrc
$ mkdir -p $HOME/src/fsl-community-bsp
$ cd $HOME/src/fsl-community-bsp
$ repo init -u https://github.com/Freescale/fsl-community-bsp-platform -b dizzy
$ repo sync

2.  Setup the build environment using the predefined imx6dl-riotboard machine.

 $ MACHINE=imx6dl-riotboard . ./setup-environment build  

3.  Create a new layer for the custom Linux distribution

 $ cd $HOME/src/fsl-community-bsp/sources  
$ mkdir -p meta-bsec/conf/distro
$ mkdir -p meta-bsec/recipes-bsec/images
$ cd poky/meta/recipes-core/images
$ cp core-image-minimal.bb ../../../../meta-bsec/recipes-bsec/images/bsec-image.bb

4.  Create the layer.conf file in the meta-bsec layer. 

sources/meta-bsec/conf/layer.conf should contain the following
 BBPATH .= ":${LAYERDIR}"  
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILE_COLLECTIONS += "bsec"
BBFILE_PATTERN_bsec = "^${LAYERDIR}/"
BBFILE_PRIORITY_bsec = "6"

5.  Create the distribution configuration file in the meta-bsec layer. 

sources/meta-bsec/conf/distro/bsecdist.conf should contain the following
 require conf/distro/poky.conf  
DISTRO = "bsecdist"
DISTRO_NAME = "bsecdist distribution"
DISTRO_VERSION = "1.0"
DISTRO_CODENAME = "bsc"
SDK_VENDOR = "-bsecdistsdk"
SDK_VERSION := "${@'${DISTRO_VERSION}'.replace('snapshot-${DATE}','snapshot')}"
MAINTAINER = "bsecdist <e-mail-address>"
INHERIT += "buildhistory"
BUILDHISTORY_COMMIT = "1"

6.  Added the new layer to bblayers.conf

build/conf/bblayers.conf should contain the following
 LCONF_VERSION = "6"  
BBPATH = "${TOPDIR}"
BSPDIR := "${@os.path.abspath(os.path.dirname(d.getVar('FILE', True)) + '/../..')}"
BBFILES ?= ""
BBLAYERS = " \
${BSPDIR}/sources/poky/meta \
${BSPDIR}/sources/poky/meta-yocto \
\
${BSPDIR}/sources/meta-openembedded/meta-oe \
${BSPDIR}/sources/meta-openembedded/meta-multimedia \
\
${BSPDIR}/sources/meta-fsl-arm \
${BSPDIR}/sources/meta-fsl-arm-extra \
${BSPDIR}/sources/meta-fsl-demos \
${BSPDIR}/sources/poky/meta-selinux \
${BSPDIR}/sources/meta-bsec \
"

7.  Set the distribution to the bsec distribution in local.conf

build/conf/local.conf should contain the following
 MACHINE ??= 'imx6dl-riotboard'  
DISTRO ?= 'bsecdist'
PACKAGE_CLASSES ?= "package_rpm"
EXTRA_IMAGE_FEATURES = "debug-tweaks"
USER_CLASSES ?= "buildstats image-mklibs image-prelink"
PATCHRESOLVE = "noop"
BB_DISKMON_DIRS = "\
STOPTASKS,${TMPDIR},1G,100K \
STOPTASKS,${DL_DIR},1G,100K \
STOPTASKS,${SSTATE_DIR},1G,100K \
ABORT,${TMPDIR},100M,1K \
ABORT,${DL_DIR},100M,1K \
ABORT,${SSTATE_DIR},100M,1K"
PACKAGECONFIG_append_pn-qemu-native = " sdl"
PACKAGECONFIG_append_pn-nativesdk-qemu = " sdl"
ASSUME_PROVIDED += "libsdl-native"
CONF_VERSION = "1"
BB_NUMBER_THREADS = '1'
PARALLEL_MAKE = '-j 1'
DL_DIR ?= "${BSPDIR}/downloads/"
ACCEPT_FSL_EULA = "1"

8.  Pull the OpenEmbedded SELinux meta layer for later configuration

 $ cd sources/poky   
$ git clone -b dizzy git://git.yoctoproject.org/meta-selinux
$ cd ../..

9.  Perform the build

 $ cd build  
$ bitbake bsec-image

10.  Write the image to the SD card

 $ cd tmp/deploy/images/imx6dl-riotboard  
$ sudo dd if=bsec-image-imx6dl-riotboard.sdcard of=/dev/sdX bs=1M
$ sudo sync

At this point, the jumpers on the riotboard should be set to boot from the SD card.  Next, power on the riotboard with the new SD card.  If HDMI is connected,  the Das u-boot software engineering logo should appear on the display.

 bsecdist distribution 1.0 imx6dl-riotboard /dev/ttymxc1               
imx6dl-riotboard login:

Review the input specifications for the riotboard machine should be simple.  Start with the following files

 sources/meta-fsl-arm-extra/conf/machine/imx6dl-riotboard.conf  
sources/poky/meta-yocto/conf/distro/poky.conf
sources/meta-fsl-arm/recipes-kernel/linux/linux-imx.inc
sources/meta-fsl-arm/recipes-kernel/linux/linux-fslc_3.17.bb
sources/poky/meta/conf/machine/include/tune-cortexa9.inc

The input specifications for this image are raw and generic. They define software support for ALL of the on-board peripherals with the e-fuses left open.

Finally, the output image was 29 MB and is comprised of the u-boot boot loader, the Linux kernel, and the root file system.  This is a decent place to start before adding more software to the BSP.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.