Monday, July 20, 2015

Creating a custom Linux Image for the Raspberry Pi











Creating a custom Linux distribution for the Raspberry Pi is very similar to creating a custom Linux distribution for the RIoTboard.  A new meta-layer is created and customized. The Yocto project already has support for the Raspberry Pi.  There is a hardware specific BSP overlay layer in the Yocto project called meta-raspberrypi.  The layer contains machine specific tunings, compile time parameters, kernel configuration options, and boot loader parameters that are specific to the Raspberry Pi hardware.  Other items such as the GPU/CPU memory split, ARM and GPU processor frequencies, and SDRAM frequency are also set in the pre-existing bsp layer.

This guide provides simple directions for creating an operating system image (U-Boot, GNU/Linux kernel, and root file system) for the Raspberry Pi.  The operating system image will contain native ARM cross compilers, a full development environment, and kernel source code.  These directions will work for the Raspberry Pi 2, B+, B, and A+.

The operating system image will be called specialpi.

Note: The Yocto Project will be releasing version 1.9 in October at which time, several changes will be incorporated which fix the current kernel defconfig issue with the meta-raspberrypi layer. In the mean time, the best option for customizing the raspberry pi kernel is building it in the Linux tree, or out of the Yocto tree.  By default, the meta-raspberrypi layer pulls the broadcom defconfig from the applicable kernel branch and uses that for the configuration.

A 64-bit Fedora 21 GNU/Linux host will be used to compile all of the source components.  Here is what uname shows on my development host:
Fedora release 21 for x86_64 GNU/Linux kernel 4.0.7-200.fc21.x86_64 #1 SMP

This guide consists of the following steps.

1. Install required Packages for a 64-bit Fedora 21 Host development system
2. Pull the Raspberry Pi layer from the Yocto project
3. Create the specialpi layer and image.
4. Make the specialpi image useful.
5. Create layer.conf in the specialpi layer.
6. Make the specialpi layer visible.
7. Set the type of MACHINE.
8. Set up the local configuration.
9. Execute the build.
10.Burn the build to a bootable media device.
11. Validate the build.

Hardware and software prerequisites

Host Operating System


Fedora release 21 for x86_64
GNU/Linux kernel 4.0.7-200.fc21.x86_64 #1 SMP

Host Hardware


Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz
Physical Memory 12 GB
My /home partition is 414 GB and resides on a solid state hard drive.

The Yocto build requires a large amount of space so I recommend keeping a scratch area on your /home partition of at least 100 GB.  You can get away with less space but if you decide to make changes to the source and binaries within the Yocto tree later on down the line, then it is a good idea to have extra space.


1. Install required Packages for a 64-bit Fedora 21 Host development system


from the Yocto Project Mega Manual Revision 1.8

Execute the following commands on the development host.

 host]$ sudo yum install gawk make wget tar bzip2 gzip python unzip perl patch \
        diffutils diffstat git cpp gcc gcc-c++ glibc-devel texinfo chrpath \
        ccache perl-Data-Dumper perl-Text-ParseWords perl-Thread-Queue socat \
        findutils which
 host]$ sudo yum install SDL-devel xterm perl-Thread-Queue
 host]$ sudo yum install make docbook-style-dsssl docbook-style-xsl \
        docbook-dtds docbook-utils fop libxslt dblatex xmlto xsltproc
 host]$ sudo yum install autoconf automake libtool glib2-devel

2. Pull the Raspberry Pi layer from the Yocto project



Execute the following commands on the development host.

host]$ mkdir $HOME/bin
host]$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
host]$ chmod a+x $HOME/bin/repo
host]$ echo "PATH=$PATH:$HOME/bin" >> $HOME/.bashrc
host]$ source .bashrc
host]$ mkdir -p $HOME/src/rpi
host]$ cd $HOME/src/rpi
host]$ git clone git://git.yoctoproject.org/poky -b fido
host]$ cd poky
host]$ git clone git://git.yoctoproject.org/meta-raspberrypi -b fido
host]$ git clone git://git.openembedded.org/meta-openembedded -b fido
host]$ source oe-init-build-env build
host]$ export RPIHOME=$HOME/src/rpi/poky

3. Create the specialpi layer and image


Execute the following commands on the development host.

host]$ cd $RPIHOME
host]$ mkdir -p specialpi/recipes-specialpi/images
host]$ mkdir specialpi/conf
host]$ cd specialpi/recipes-specialpi/images
host]$ cp ../../../meta-raspberrypi/recipes-core/images/rpi-hwup-image.bb specialpi.bb

4. Make the specialpi image useful


Modify meta-specialpi/recipes-specialpi/images/special.bb so that it looks like the following

include recipes-core/images/core-image-minimal.bb

IMAGE_FEATURES += "tools-sdk tools-debug debug-tweaks ssh-server-openssh"

# Include modules in rootfs
IMAGE_INSTALL += " \
 packagegroup-core-buildessential \
 kernel-modules \
 kernel-devsrc \
 "

inherit core-image

IMAGE_ROOTFS_EXTRA_SPACE_append += "+ 3000000"

5. Create layer.conf in the specialpi layer.


Modify meta-specialpi/conf/layer.conf so that it looks like the following

BBPATH .= ":${LAYERDIR}"

# We have a recipes directory containing .bb and .bbappend files, add to BBFILES
BBFILES += "${LAYERDIR}/recipes*/*/*.bb \
            ${LAYERDIR}/recipes*/*/*.bbappend"

BBFILE_COLLECTIONS += "specialpi"
BBFILE_PATTERN_specialpi := "^${LAYERDIR}/"
BBFILE_PRIORITY_specialpi = "7"


6. Make the specialpi layer visible


Modify build/conf/bblayers.conf so that it looks like the following

# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
LCONF_VERSION = "6"

BBPATH = "${TOPDIR}"
BBFILES ?= ""

BBLAYERS ?= " \
  /home/ns/src/rpi/poky/meta \
  /home/ns/src/rpi/poky/meta-yocto \
  /home/ns/src/rpi/poky/meta-yocto-bsp \
  /home/ns/src/rpi/poky/meta-raspberrypi \
  /home/ns/src/rpi/poky/meta-specialpi \
  "
BBLAYERS_NON_REMOVABLE ?= " \
  /home/ns/src/rpi/poky/meta \
  /home/ns/src/rpi/poky/meta-yocto \
  "


7. Set the type of MACHINE


For Raspberry Pi Model B,set MACHINE in build/conf/local.conf above the MACHINE ?? = "qemux86" line as follows
MACHINE ?= "raspberrypi"

For Raspberry Pi 2, B+, or A+,
set MACHINE in build/conf/local.conf above the MACHINE ?? = "qemux86" line as follows

MACHINE ?= "raspberrypi2"

8. Set up the local configuration

Add the following lines to the end of build/conf/local.conf file

CONF_VERSION = "1"
INHERIT += "archiver"
ARCHIVER_MODE[src] = "original"
COPY_LIC_MANIFEST = "1"
COPY_LIC_DIRS = "1"
SOURCE_MIRROR_URL ?= "file://${TOPDIR}/source-mirror/"
INHERIT += "own-mirrors"
BB_GENERATE_MIRROR_TARBALLS = "1"

9. Execute the build


For Raspberry Pi Model B, insert an SD card into the host.

Execute the following commands on the development host.

host]$ cd $RPIHOME/build
host]$ bitbake specialpi
host]$ cd tmp/deploy/images/raspberrypi
host]$ dd if=specialpi-image-raspberrypi.rpi-sdimg off=/dev/sd<X> bs=1M
host]$ sync

For Raspberry Pi 2, B+, or A+, insert a uSD card into the host.

Execute the following commands on the development host.

host]$ cd $RPIHOME/build
host]$ bitbake specialpi
host]$ cd tmp/deploy/images/raspberrypi
host]$ dd if=rpi-specialpi-image-specialpi.rpi-sdimg of=/dev/sdb bs=1M
host]$ sync

10.Burn the build to a bootable media device


For Raspberry Pi Model B, insert an SD card into the host.
Execute the following commands on the development host.

host]$ cd build/tmp/deploy/images/raspberrypi
host]$ dd if=specialpi-raspberrypi.rpi-sdimg off=/dev/sd<X> bs=1M
host]$ sync

For Raspberry Pi 2 or Model B+, insert a uSD card into the host.

Execute the following commands on the development host.

host]$ cd build/tmp/deploy/images/raspberrypi
host]$ dd if=specialpi-raspberrypi.rpi-sdimg of=/dev/sdb bs=1M
host]$ sync


11. Validate the build


Insert the SD card or uSD card in to the Raspberry Pi and validate that the Raspberry Pi properly boots the image on the SD or uSD card.

You should get a login prompt that says
Poky (Yocto Project Reference Distro) 1.8 raspberrypi /dev/ttyAMA0

The username is root. There is no password.
Kernel sources are in /usr/src/kernel
gcc is in /usr/bin

Increase IMAGE_ROOTFS_EXTRA_SPACE_append as needed in special.bb


Saturday, July 18, 2015

Creating a custom Linux BSP (including kernel) for the Raspberry Pi with Yocto 1.8 Fido


This guide provides directions for building a custom Linux kernel, bootloader, and root filesystem for the Raspberry Pi.  This guide was created with the following purposes.
  • To utilize the Yocto project and it's native support of the Raspberry Pi for building a custom kernel and board support package for the Raspberry Pi.
  • To Provide the ability to quickly revert to different (new and old) kernel versions and apply version specific patch sets with different kernel configurations when building a BSP image for the Raspberry Pi with Yocto.
  • To store kernel configurations and kernel patches that are specific to a a version of a kernel in a single directory that has been named with the version of the kernel. i.e. linux-*_3.18.5/
  • To follow the procedures that Freescale and Boundary Devices used for integrating multiple kernels versions into the meta-fsl and meta-fsl-arm layers.
  • To build the boot loader and kernel in separate pieces for the Raspberry Pi.
  • To exclusively utilize Yocto and bitbake for building the Linux kernel and boot loader without having to copy kernel config files between directories in the build tree.
  • Image size is not an issue since this image will be used for internal development and research. The image will contain all of the compilers and dev tools.

Creating a custom Linux distribution for the Raspberry Pi is very similar to creating a custom Linux distribution for the RIoTboard.  With only a few modifications to the Yocto supported meta-raspberry pi layer, a BSP can be created for the Raspberry Pi that will allow one to easily modify the GNU/Linux kernel and U-Boot bootloader for the Pi.  Rather than making direct modifications to the meta-raspberry pi layer, modifications will be made in a cloned layer.  The cloned layer will have a new name. Kernel and and boot loader configuration and compile changes can subsequently be made in the cloned layer.


The board support package that will be built for the Raspberry Pi will consist of U-boot, a GNU/Linux kernel, and a root filesystem.  A 64-bit Fedora 21 GNU/Linux host will be used to compile all of the source components.

The Yocto project already has support for the Raspberry Pi.  There is a hardware specific BSP overlay layer in the Yocto project called meta-raspberrypi.  The layer contains machine specific tunings, compile time parameters, kernel configuration options, and boot loader parameters that are specific to the Raspberry Pi hardware.  Other items such as the GPU/CPU memory split, ARM and GPU processor frequencies, and SDRAM frequency are also set in the pre-existing bsp layer.


This guide consists of the following steps.

1. Install required Packages for a 64-bit Fedora 21 Host development system
2. Pull the Yocto Raspberry Pi sources.
3. Clone the Yocto meta-raspberrypi layer.
4. Clone the two preexisting machines in the meta-raspberrypi layer.
5. Make everything compatible with the two new machines.
6. Replace raspberrypi with the name of the new layer, slicedpi, in layer.conf.
7. Clone the RPI hardware up image.
8. Modify the new SpecialPi image.
9. Add the meta-slicedpi layer to BBLAYERS.
10. Set the MACHINE name
11. Fix the kernel recipe include file
12. Configure local.conf.
13. Create a custom kernel defconfig file for GNU/Linux kernel 3.18.5.
14. Customize busybox.
15. Check the output of the build.
16. Kick off the build and burn the image to an SD/uSD card.
17. Validate the build.
18. A few notes.

Hardware and software prerequisites

 

Host Operating System

Fedora release 21 for x86_64
GNU/Linux kernel 4.0.7-200.fc21.x86_64 #1 SMP

 

Host Hardware

Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz
Physical Memory 12 GB
My /home partition is 414 GB and resides on a solid state hard drive.



The Yocto build requires a large amount of space so I recommend keeping a scratch area on your /home partition of at least 100 GB.  You can get away with less space but if you decide to make changes to the source and binaries within the Yocto tree later on down the line, then it is a good idea to have extra space.

1. Install required Packages for a 64-bit Fedora 21 Host development system


from the Yocto Project Mega Manual Revision 1.8

Execute the following commands on the development host.

 host]$ sudo yum install gawk make wget tar bzip2 gzip python unzip perl patch \
        diffutils diffstat git cpp gcc gcc-c++ glibc-devel texinfo chrpath \
        ccache perl-Data-Dumper perl-Text-ParseWords perl-Thread-Queue socat \
        findutils which
 host]$ sudo yum install SDL-devel xterm perl-Thread-Queue
 host]$ sudo yum install make docbook-style-dsssl docbook-style-xsl \
        docbook-dtds docbook-utils fop libxslt dblatex xmlto xsltproc
 host]$ sudo yum install autoconf automake libtool glib2-devel

2. Pull the Yocto Raspberry Pi sources.

Execute the following commands on the development host.


host]$ mkdir $HOME/bin
host]$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
host]$ chmod a+x $HOME/bin/repo
host]$ echo "PATH=$PATH:$HOME/bin" >> $HOME/.bashrc
host]$ source .bashrc
host]$ mkdir -p $HOME/src/rpi
host]$ cd $HOME/src/rpi
host]$ git clone git://git.yoctoproject.org/poky -b fido
host]$ cd poky
host]$ git clone git://git.yoctoproject.org/meta-raspberrypi -b fido
host]$ git clone git://git.openembedded.org/meta-openembedded -b fido
host]$ source oe-init-build-env build
host]$ export RPIHOME=$HOME/src/rpi/poky

3. Clone the Yocto meta-raspberrypi layer.

Execute the following commands on the development host.

host]$ cd $RPIHOME
host]$ cp -R meta-raspberrypi meta-slicedpi

4. Clone the two preexisting machines in the meta-raspberrypi layer.

Execute the following commands on the development host.


host]$ cd meta-slicedpi/conf/machine/
host]$ mv raspberrypi.conf slicedpimach.conf
host]$ mv raspberrypi2.conf slicedpi2mach.conf

5. Make everything compatible with the two new machines.


It appears that COMPATIBLE_MACHINE has been set to raspberrypi in more than a handful of files. So let's fix COMPATIBLE_MACHINE by replacing the rval in the assignment expression with the names of the two new machines OR'd together.  All of the recipes need to be machine compatible with both the raspberrypi and raspberrypi2. These two machines were cloned and renamed slicedpimach and slicedpi2mach in step 4.

Execute the following commands on the development host.

host]$ find . -type f -exec sed -i \
's/COMPATIBLE_MACHINE = "raspberrypi"/COMPATIBLE_MACHINE = "(slicedpimach|slicedpi2mach)"/g' {} +

6. Replace raspberrypi with the name of the new layer, slicedpi, in layer.conf

Execute the following commands on the development host.


host]$ find . -name layer.conf -exec sed -i \
's/raspberrypi/slicedpi/g' {} +

7. Clone the RPI hardware up image.

Copy the rpi hardware up image to a new image called rpi-slicedpi-image as follows. Since this image is almost empty, having it in place means it can easily be customized later on.

Execute the following commands on the development host.

host]$ cp meta-slicedpi/recipes-core/images/rpi-hwup-image.bb \
meta-slicedpi/recipes-core/images/rpi-specialpi-image.bb

8. Modify the new specialpi Image

Modify meta-slicedpi/recipes-core/images/rpi-specialpi.bb so that rpi-specialpi-image.bb looks like the following

include recipes-core/images/core-image-minimal.bb
IMAGE_FEATURES += "dev-pkgs tools-sdk tools-debug tools-profile tools-testapps \
                   debug-tweaks ssh-server-openssh package-management"
# Include modules in rootfs
IMAGE_INSTALL += " \
    packagegroup-core-boot \
    packagegroup-core-full-cmdline \
    packagegroup-core-tools-profile \
    packagegroup-core-buildessential \
    kernel-modules \
    ${CORE_IMAGE_EXTRA_INSTALL} \
    kernel-devsrc \
    "
IMAGE_ROOTFS_EXTRA_SPACE_append += "+ 3000000"

9. Add the meta-slicedpi layer to BBLAYERS

Add the meta-slicedpi layer path to the BBLAYERS variable in build/conf/bblayers.conf so that bblayers.conf looks like the following


# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
LCONF_VERSION = "6"

BBPATH = "${TOPDIR}"
BBFILES ?= ""

BBLAYERS ?= " \
  /home/ns/src/rpi/poky/meta \
  /home/ns/src/rpi/poky/meta-yocto \
  /home/ns/src/rpi/poky/meta-yocto-bsp \
  \
  /home/ns/src/rpi/poky/meta-slicedpi \
  "
BBLAYERS_NON_REMOVABLE ?= " \
  /home/ns/src/rpi/poky/meta \
  /home/ns/src/rpi/poky/meta-yocto \
  "

10. Set the MACHINE name

For Raspberry Pi Model B,
set MACHINE in build/conf/local.conf above the MACHINE ?? = "qemux86" line as follows

MACHINE ?= "slicedpimach"

For Raspberry Pi 2 or Model B+,
set MACHINE in build/conf/local.conf above the MACHINE ?? = "qemux86" line as follows

MACHINE ?= "slicedpi2mach"

11. Fix the kernel recipe include file

Execute the following commands on the development host.

host]$ find . -name linux-raspberrypi.inc -exec sed -i \
's/KERNEL_DEFCONFIG_raspberrypi/KERNEL_DEFCONFIG_slicedpimach/g' {} +
host]$ find . -name linux-raspberrypi.inc -exec sed -i \
's/KERNEL_DEFCONFIG_raspberrypi2/KERNEL_DEFCONFIG_slicedpi2mach/g' {} +

12. Configure local.conf

A source mirror will be setup along with source licences to accompany each binary that is built, and source archives for all of the packages. Add the following lines to the end of build/conf/local.conf file

PREFERRED_PROVIDER_virtual/libgl ?= "userland"
PREFERRED_PROVIDER_virtual/libgles2 = "mesa"
PREFERRED_PROVIDER_virtual/egl = "mesa"
# CONF_VERSION is increased each time build/conf/ changes incompatibly and is used to
# track the version of this file when it was generated. This can safely be ignored if
# this doesn't mean anything to you.
CONF_VERSION = "1"
DL_DIR ?= "${TOPDIR}/downloads"
ACCEPT_FSL_EULA = ""
INHERIT += "archiver"
ARCHIVER_MODE[src] = "original"
COPY_LIC_MANIFEST = "1"
COPY_LIC_DIRS = "1"
SOURCE_MIRROR_URL ?= "file://${TOPDIR}/source-mirror/"
INHERIT += "own-mirrors"
BB_GENERATE_MIRROR_TARBALLS = "1"

13. Create a custom kernel defconfig file for GNU/Linux kernel 3.18.5

Execute the following commands on the development host

host]$ cd $RPIHOME/meta-slicedpi/recipes-kernel
host]$ mkdir linux-raspberrypi-3.18.5
host]$ touch linux-raspberrypi-3.18.5
host]$ cd linux-raspberrypi-3.18.5

If you are building for the Raspberry Pi B
execute the following commands on the development host

host]$ curl https://raw.githubusercontent.com/raspberrypi/linux/rpi-3.18.y/arch/arm/configs/bcmrpi_defconfig \
> defconfig

If you are building for the Raspberry Pi 2 or Model B+
execute the following commands on the development host

host]$ curl https://raw.githubusercontent.com/raspberrypi/linux/rpi-3.18.y/arch/arm/configs/bcm2709_defconfig \
> defconfig

Customize the kernel configuration by statically building AES XTS, AES CTS, and SHA512 support into the kernel.

host]$ sed -i -e 's/CONFIG_CRYPTO_XTS=m/CONFIG_CRYPTO_XTS=y/g' defconfig
host]$ sed -i -e 's/CONFIG_CRYPTO_CTS=m/CONFIG_CRYPTO_CTS=y/g' defconfig
host]$ sed -i -e 's/CONFIG_CRYPTO_SHA512=m/CONFIG_CRYPTO_SHA512=y/g' defconfig

Create meta-slicedpi/recipes-kernel/images/linux-raspberrypi-3.18.5.bbappend with the following contents

EXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}:"
SRC_URI += "file://defconfig"

It makes more sense to keep version specific kernel patches in a directory that is named in accordance with the kernel patch versions that are stored within it.  Thus, move the i2c kernel patch for the 3.18.5 kernel from the linux-raspberrypi directory to the linux-raspberrypi_3.18.5 directory.

host]$ cd $RPIHOME/meta-slicedpi/recipes-kernel/linux/linux-raspberrypi_3.18.5
host]$ mv ../linux-raspberrypi/*.patch .

Modify meta-slicedpi/recipes-kernel/images/linux-raspberrypi-3.18.bb with the following contents

require linux.inc

DESCRIPTION = "Linux Kernel for Raspberry Pi"
SECTION = "kernel"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7"

SRC_URI += " \
        file://defconfig \
        "
COMPATIBLE_MACHINE = "(slicedpimach|slicedpi2mach)"
PV = "${LINUX_VERSION}"

# NOTE: For now we pull in the default config from the RPi kernel GIT tree.
KERNEL_DEFCONFIG_slicedpimach ?= "bcmrpi_defconfig"
KERNEL_DEFCONFIG_slicedpi2mach ?= "bcm2708_defconfig"

# CMDLINE for raspberrypi
CMDLINE = "dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait"

UDEV_GE_141 ?= "1"

# Set programmatically some variables during recipe parsing
# See http://www.yoctoproject.org/docs/current/bitbake-user-manual/bitbake-user-manual.html#anonymous-python-functions
python __anonymous () {
    kerneltype = d.getVar('KERNEL_IMAGETYPE', True)
    kerneldt = d.getVar('KERNEL_DEVICETREE', True)

    # Add dependency to 'rpi-mkimage-native' package only if RPi bootloader is used with DT-enable kernel
    if kerneldt:
        if kerneltype != 'uImage' and len(kerneldt.strip()) > 1:
            depends = d.getVar("DEPENDS", True)
            depends = "%s rpi-mkimage-native" % depends
            d.setVar("DEPENDS", depends)
}

do_kernel_configme_prepend() {
    install -m 0644 ${S}/arch/${ARCH}/configs/${KERNEL_DEFCONFIG} ${WORKDIR}/defconfig || die "No default configuration for ${MACHINE} / ${KERNEL_DEFCONFIG} available."
}

do_install_prepend() {
    install -d ${D}/lib/firmware
}

do_deploy_append() {
    # Deploy cmdline.txt
    install -d ${DEPLOYDIR}/bcm2835-bootfiles
    echo "${CMDLINE}" > ${DEPLOYDIR}/bcm2835-bootfiles/cmdline.txt
}

do_rpiboot_mkimage() {
    if test "x${KERNEL_IMAGETYPE}" != "xuImage" ; then
        if test -n "${KERNEL_DEVICETREE}"; then
            # Add RPi bootloader trailer to kernel image to enable DeviceTree support
            ${STAGING_DIR_NATIVE}/usr/lib/rpi-mkimage/mkknlimg --dtok ${KERNEL_OUTPUT} ${KERNEL_OUTPUT}
        fi
    fi
}
addtask rpiboot_mkimage before do_install after do_compile

PREFERRED_VERSION_linux-raspberrypi ?= "3.18.%" is currently set in meta-slicedpi/conf/machine/include/rpi-default-version.inc

Additional kernel patches can be placed in meta-slicedpi/recipes-kernel/images/linux-raspberrypi and then added to SRC_URI in meta-specialpi/recipes-kernel/images/linux-raspberrypi-3.18.bb

14. Customize Busybox

Configuration fragments can be created for customizing the Busybox configuration.  To start with, copy over the example configuration fragment from the busybox directory in the meta-skeleton layer.

For now, there isn't a need to customize busybox so the bbappend file is copied in from the skeleton layer directory in case it is needed later on.  There is a configuration fragment in the busybox subdirectory for setting the norfkill configuration option in busybox.

Execute the following commands on the development host.

host]$ cd $RPIHOME/meta-slicedpi
host]$ cp -R ../meta-skeleton/recipes-skeleton/recipes-core/busybox recipes-core/
host]$ cd recipes-core/busybox


Additional configuration options can be added by creating a configuration fragment file in the busybox/ subdirectory, inserting the configuration option from the busybox .config file into the configuration fragment file, and then appending the name of the configuration fragment file to SRC_URI in busybox_%.bbappend.

15. Kick off the build and burn the image to an SD/uSD card


For Raspberry Pi Model B, insert an SD card into the host.

Execute the following commands on the development host.

host]$ cd $RPIHOME/build
host]$ bitbake rpi-specialpi-image
host]$ cd tmp/deploy/images/raspberrypi
host]$ dd if=specialpi-image-raspberrypi.rpi-sdimg off=/dev/sd<X> bs=1M
host]$ sync

For Raspberry Pi 2 or Model B+, insert a uSD card into the host.

Execute the following commands on the development host.

host]$ cd $RPIHOME/build
host]$ bitbake rpi-specialpi-image
host]$ cd tmp/deploy/images/raspberrypi
host]$ dd if=rpi-specialpi-image-slicedpimach.rpi-sdimg of=/dev/sdb bs=1M
host]$ sync

16. Check the output of the build

The build output directory should contain multiple files - a kernel uImage, a rootfs image, a manifest files, etc.

Execute the following command on the development host and validate the output of the command.  Depending on how many builds have been executed, there will be more than one type of each file in the directory. For example, there are multiple sd card images in the slicedpimach directory below because mult

host]$ ls -lR build/tmp/deploy/images/slicedpimach
total 18070236
drwxr-xr-x. 2 ns ns       4096 Jul 18 21:36 bcm2835-bootfiles
-rw-r--r--. 1 ns ns 3196059648 Jul 18 18:23 rpi-specialpi-image-slicedpimach-20150718221335.rootfs.ext3
-rw-r--r--. 1 ns ns      60339 Jul 18 18:23 rpi-specialpi-image-slicedpimach-20150718221335.rootfs.manifest
-rw-r--r--. 1 ns ns 3221225472 Jul 18 18:24 rpi-specialpi-image-slicedpimach-20150718221335.rootfs.rpi-sdimg
-rw-r--r--. 1 ns ns   21262054 Jul 18 18:23 rpi-specialpi-image-slicedpimach-20150718221335.rootfs.tar.bz2
-rw-r--r--. 1 ns ns 5125439488 Jul 18 20:38 rpi-specialpi-image-slicedpimach-20150718233110.rootfs.ext3
-rw-r--r--. 1 ns ns     153004 Jul 18 20:36 rpi-specialpi-image-slicedpimach-20150718233110.rootfs.manifest
-rw-r--r--. 1 ns ns 5150605312 Jul 18 20:43 rpi-specialpi-image-slicedpimach-20150718233110.rootfs.rpi-sdimg
-rw-r--r--. 1 ns ns  291233698 Jul 18 20:38 rpi-specialpi-image-slicedpimach-20150718233110.rootfs.tar.bz2
-rw-r--r--. 1 ns ns 5125439488 Jul 18 21:24 rpi-specialpi-image-slicedpimach-20150719021250.rootfs.ext3
-rw-r--r--. 1 ns ns     153004 Jul 18 21:22 rpi-specialpi-image-slicedpimach-20150719021250.rootfs.manifest
-rw-r--r--. 1 ns ns 5150605312 Jul 18 21:28 rpi-specialpi-image-slicedpimach-20150719021250.rootfs.rpi-sdimg
-rw-r--r--. 1 ns ns  290871927 Jul 18 21:24 rpi-specialpi-image-slicedpimach-20150719021250.rootfs.tar.bz2
lrwxrwxrwx. 1 ns ns         59 Jul 18 21:26 rpi-specialpi-image-slicedpimach.ext3 -> rpi-specialpi-image-slicedpimach-20150719021250.rootfs.ext3
lrwxrwxrwx. 1 ns ns         63 Jul 18 21:26 rpi-specialpi-image-slicedpimach.manifest -> rpi-specialpi-image-slicedpimach-20150719021250.rootfs.manifest
lrwxrwxrwx. 1 ns ns         64 Jul 18 21:29 rpi-specialpi-image-slicedpimach.rpi-sdimg -> rpi-specialpi-image-slicedpimach-20150719021250.rootfs.rpi-sdimg
lrwxrwxrwx. 1 ns ns         62 Jul 18 21:26 rpi-specialpi-image-slicedpimach.tar.bz2 -> rpi-specialpi-image-slicedpimach-20150719021250.rootfs.tar.bz2
lrwxrwxrwx. 1 ns ns         30 Jul 18 18:15 u-boot.img -> u-boot-slicedpimach-git-r0.img
-rwxr-xr-x. 2 ns ns     286128 Jul 18 18:15 u-boot-slicedpimach-git-r0.img
lrwxrwxrwx. 1 ns ns         30 Jul 18 18:15 u-boot-slicedpimach.img -> u-boot-slicedpimach-git-r0.img

./bcm2835-bootfiles:
total 6720
-rw-rw-r--. 2 ns ns       0 Jul 18 18:02 bcm2835-bootfiles-20150206.stamp
-rw-r--r--. 2 ns ns   17856 Jul 18 18:02 bootcode.bin
-rw-r--r--. 2 ns ns   32843 Jul 18 17:56 config.txt
-rw-r--r--. 2 ns ns    2345 Jul 18 18:02 fixup_cd.dat
-rw-r--r--. 2 ns ns    6133 Jul 18 18:02 fixup.dat
-rw-r--r--. 2 ns ns    9191 Jul 18 18:02 fixup_x.dat
-rw-r--r--. 2 ns ns  554008 Jul 18 18:02 start_cd.elf
-rw-r--r--. 2 ns ns 2641752 Jul 18 18:02 start.elf
-rw-r--r--. 2 ns ns 3598760 Jul 18 18:02 start_x.elf

17. Validate the build

Insert the SD card or uSD card in to the Raspberry Pi and validate that the Raspberry Pi properly boots the image on the SD or uSD card.

18.  A few notes

The modifications that were made by cloning the meta-raspberrypi layer loosen up the recipes and the ability to make changes to the raspberry pi BSP.

If you are used to building the GNU/Linux kernel the normal way, then the  environment-setup-* script can be used to set the cross compiler and arch before building the kernel from within the kernel source tree.  The same goes for u-boot. The u-boot recipe is in meta-slicedpi/recipes-bsp/u-boot.
Lastly, I intentionally did not include kernel configuration fragments for the kernel configuration piece but included an example for the busybox configuration.

meta-slicedpi layer on github.

Monday, July 13, 2015

Creating a custom Linux BSP for the RIoTboard with Yocto 1.8 Fido - Part III


In part III of this guide, we will cover the installation of the final image to the SD card. We will then boot the SD card on the target. Finally, we will test audio recording and playback.
Part III of this guide consists of the following sections.

  1. Write the GNU/Linux BSP image to an SD card.
  2. Set the physical switches on the RioTboard to boot from the uSD or SD card.
  3. Connect the target to the necessary peripherals for boot.
  4. Test audio recording, audio playback, and Internet connectivity.


1.  Write the GNU/Linux BSP image to an SD card

At this point, the build should be complete, without errors.  You should see something like this on the terminal


 real 254m28.335s
 user 737m9.307s
 sys 133m39.529s

Insert an SD card into an SD card reader, connect it to the host, and execute the following commands on the host.


 host]$ cd $HOME/src/fsl-community-bsp/build /tmp/deploy/images/imx6dl-riotboard
 host]$ sudo umount /dev/sd<X>
 host]$ sudo dd if=bsec-image-imx6dl-riotboard.sdcard of=/dev/sd<X> bs=1M
 host]$ sudo sync


2. Set the physical switches on the RioTboard to boot from the uSD or SD card.


For booting from the SD card on the bottom of the target, set the physical switches as follows.
SD (J6, bottom) 1 0 1 0 0 1 0 1

For booting from the uSD card on the top of the target, set the physical switches as follows.
uSD (J7, top) 1 0 1 0 0 1 1 0

3. Connect the target to the necessary peripherals for boot.

You have two options here. 


Option 1

Connect one end of an ethernet cable to the target. Connect the other end of the ethernet cable to a hub or DHCP server.  

Connect the board to the host computer via the J18 serial UART pins on the target.  This will require a serial to USB breakout cable.  Connect TX, RX, and GND to RX, TX, and GND on the cable. The cable must have an FTDI or similar level shifter chip. Connect the USB end of the cable to the host computer.

Connect your speakers to the light green 3.5 mm audio out jack and your microphone to the pink 3.5 mm MIC In jack.

Connect a 5V / 4 AMP DC power source to the target.

Run minicom on the host computer. You will need to configure minicom at 115200 8N1 with no hardware flow control and no software flow control. If you are using a USB to serial cable with an FTDI chip in it, then the cable should show up in /dev as ttyUSB0 in which case, set the serial device in minicom to /dev/ttyUSB0.

If you choose this option, you can drop into U-boot after power on by pressing Enter on the host keyboard with minicom open and connected.

If you don't press enter after power on, the target will boot and you will get a login prompt.

You will now see a login prompt.

Option 2

Connect one end of an ethernet cable to the target. Connect the other end of the ethernet cable to a hub or DHCP server.  

Connect a USB keyboard, USB mouse, and monitor (via an HDMI cable) to the target.

Connect your speakers to the light green 3.5 mm audio out jack and your microphone to the pink 3.5 mm MIC In jack.

Connect a 5V / 4 AMP DC power source to the target.

You will now see a login prompt.


4. Test audio recording, audio playback, and Internet connectivity


Type root to log in to the target. The root password is not set.

Execute the following commands on the target

 root@imx6dl-riotboard: alsamixer 

Press F6.
Press arrow down so that 0 imx6-riotboard-sgtl5000 is highlighted.
Press Enter.
Increase Headphone level to 79<>79.
Increase PCM level to 75<>75.
Press Tab.
Increase Mic level to 59.
Increase Capture to 80<>80.
Press Esc.

 root@imx6dl-riotboard: cd /usr/share/alsa/sounds
 root@imx6dl-riotboard: aplay *.wav 

You should hear sound played through the speakers.

 root@imx6dl-riotboard: cd /tmp
 root@imx6dl-riotboard: arecord -d 10 micintest.wav

Talk into the microphone for ten seconds.

 root@imx6dl-riotboard: aplay micintest.wav

You should hear your recording played through the speakers.

 root@imx6dl-riotboard: ping riotboard.org

You should get an ICMP reply.

Creating a custom Linux BSP for the RIoTboard with Yocto 1.8 Fido - Part II


In the second part of this guide, we will pull the source code, customize the build configuration, and execute the build.  Part II of this guide consists of the following sections.
  1. Pull the Freescale community BSP platform source code from github. 
  2. Setup the build environment using the predefined imx6dl-riotboard machine.
  3. Create a new layer for the custom Linux distribution.
  4. Customize the image in the meta-bsec layer. 
  5. Create layer.conf file in the meta-bsec layer. 
  6. Create the distribution configuration file in the meta-bsec layer. 
  7. Add the new layer to bblayers.conf.
  8. Customize the local configuration.
  9. Execute the build.

1. Pull the Freescale community BSP platform source code from github.


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

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


Execute the following commands on the host.

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

3. Create a new layer for the custom Linux distribution


Execute the following commands on the host.

 host]$ cd $HOME/src/fsl-community-bsp/sources  
 host]$ mkdir -p meta-bsec/conf/distro  
 host]$ mkdir -p meta-bsec/recipes-bsec/images  
 host]$ cd poky/meta/recipes-extended/images  
 host]$ cp core-image-full-cmdline.bb \
        ../../../../meta-bsec/recipes-bsec/images/bsec-image.bb

4. Customize the image in the meta-bsec layer.


Execute the following commands on the host.

  host]$ cd $HOME/src/fsl-community-bsp/sources/meta-bsec/recipes-bsec/images

Customize bsec-image.bb as follows.  Lines with bold text indicate lines to add to the file.

 DESCRIPTION = "A console-only image with more full-featured Linux system \
 functionality installed."

 # customize IMAGE_FEATURES as follows
 IMAGE_FEATURES += "dev-pkgs tools-sdk tools-debug tools-profile tools-testapps \
 debug-tweaks splash ssh-server-openssh package-management"

 # packagegroup-core-tools-profile will build and install tracing and profiling tools to the target image.
 # packagegroup-core-buildessential will build and install autotools, gcc, etc. to the target image.
 # kernel-modules for install of the kernel modules.
 # kernel-devsrc for building out of tree modules.
 # IMAGE_ROOTFS_EXTRA_SPACE_append for adding extra space to the target rootfs image.

 # customize IMAGE_INSTALL as follows
 IMAGE_INSTALL = "\
     packagegroup-core-boot \
     packagegroup-core-full-cmdline \
     packagegroup-core-tools-profile \
     packagegroup-core-buildessential \
     kernel-modules \
     ${CORE_IMAGE_EXTRA_INSTALL} \
     kernel-devsrc \
     "
 inherit core-image
 
 # Add extra space to the rootfs image
 IMAGE_ROOTFS_EXTRA_SPACE_append += "+ 3000000"

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


Create sources/meta-bsec/conf/layer.conf with the below contents.

BBPATH .= ":${LAYERDIR}"  
 BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \  
     ${LAYERDIR}/recipes-*/*/*.bbappend"  
 BBFILE_COLLECTIONS += "bsec"  
 BBFILE_PATTERN_bsec = "^${LAYERDIR}/"  
 BBFILE_PRIORITY_bsec = "6"  

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


Create sources/meta-bsec/conf/disro/bsecdist.conf with the below contents.

 require conf/distro/poky.conf    
 # distro name
 DISTRO = "bsecdist"    
 DISTRO_NAME = "bsecdist distribution"    
 DISTRO_VERSION = "1.0"    
 DISTRO_CODENAME = "bsc"    
 DISTRO_FEATURES_append = " alsa usbhost usbgadget keyboard bluetooth"
 SDK_VENDOR = "-bsecdistsdk"    
 SDK_VERSION := "${@'${DISTRO_VERSION}'.replace('snapshot-${DATE}','snapshot')}"    
 MAINTAINER = "bsecdist "    
 INHERIT += "buildhistory"    
 BUILDHISTORY_COMMIT = "1"

7. Add the new layer to bblayers.conf


Execute the following commands on the host.

 host]$ cd $HOME/src/fsl-community-bsp/build/conf

Customize bblayers.conf by adding the meta-bsec layer to BBLAYERS as follows.

 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/meta-bsec \
 "

8. Customize the local configuration


Customize local.conf as follows.

 MACHINE ??= 'imx6dl-riotboard'
 # set distro name
 DISTRO ?= 'bsecdist'
 PACKAGE_CLASSES ?= "package_rpm package_deb"
 EXTRA_IMAGE_FEATURES = " "
 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 = '4'
 PARALLEL_MAKE = '-j 4'
 DL_DIR ?= "${BSPDIR}/downloads/"
 ACCEPT_FSL_EULA = "1"
 # archive source code for all of the packages that will be built into the image
 INHERIT += "archiver"
 ARCHIVER_MODE[src] = "original"
 # ensure that license files accompany each binary in final image
 COPY_LIC_MANIFEST = "1"
 COPY_LIC_DIRS = "1"
 # setup source mirror
 # make sure that bitbake checks for all of the source tarballs in a local directory 
 # before going to the Internet to fetch them.
 SOURCE_MIRROR_URL ?= "file://${BSPDIR}/source-mirror/"
 INHERIT += "own-mirrors"
 # create a shareable cache of source code management backends
 BB_GENERATE_MIRROR_TARBALLS = "1"

9. Execute the build


Execute the following commands on the host.

 host]$ cd $HOME/src/fsl-community-bsp/build 
 host]$ time bitbake bsec-image 

While the image is building, please take note of the following.

The input specifications for the GNU/Linux kernel and U-boot segments of the BSP are in the below files. These specifications include such things as GNU/Linux kernel patch files for i.MX 6 processor features, kernel boot args, kernel load address, cortex specific tuning parameters, etc.

 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_4_0.bb  
 sources/poky/meta/conf/machine/include/tune-cortexa9.inc

In part III of this guide, we will boot the image on the target and then test audio recording and playback. Continue to part III of this guide.

Continue to Part III

Creating a custom Linux BSP for the RIoTboard with Yocto 1.8 Fido - Part I

This guide is an update to "Creating a custom Linux distribution for an ARM® Cortex®-A9 based SBC" and provides directions for building a GNU/Linux BSP for the RioTboard with Yocto 1.8 on a 64-bit Fedora 21 GNU/Linux host.  The latest stable version of Yocto (1.8 - Fido) has been incorporated along with build instructions for version 4.0.7 of the GNU/Linux kernel with i.MX 6 patches, U-boot, audio recording and playback support, and a full kernel and application development environment on the target.

This guide is split into three parts as follows.

I. Creating a custom Linux BSP for the RioTboard with Yocto 1.8 Fido - Part I
  1. Hardware and software prerequisites.
  2. Required Packages for a 64-bit Fedora 21 Host development system.
II. Creating a custom Linux BSP for the RioTboard with Yocto 1.8 Fido - Part II
  1. Pull the Freescale community BSP platform source code from github. 
  2. Setup the build environment using the predefined imx6dl-riotboard machine.
  3. Create a new layer for the custom Linux distribution.
  4. Customize the image in the meta-bsec layer. 
  5. Create layer.conf file in the meta-bsec layer. 
  6. Create the distribution configuration file in the meta-bsec layer. 
  7. Add the new layer to bblayers.conf.
  8. Customize the local configuration.
  9. Execute the build.
III. Creating a custom Linux BSP for the RioTboard with Yocto 1.8 Fido - Part III
  1. Write the GNU/Linux BSP image to an SD card.
  2. Set the physical switches on the RioTboard to boot from the uSD or SD card.
  3. Connect the target to the necessary peripherals for boot.
  4. Test audio recording, audio playback, and Internet connectivity.

The BSP will consist of a GNU/Linux 4.0.7 kernel, an EXT3 root filesystem, and the U-Boot bootloader.  All components will be compiled from the latest, public sources.  The GNU/Linux system will include support for audio recording and playback via the RioTboard's MIC In and Audio Out jacks.  We will also build in support for ethernet, ipv4, bluetooth, USB host and USB gadget, and an ssh server.  The final target image will also contain native ARM compilers, a full SDK, strace, GDB, package management tools, and the GNU/Linux 4.0.7 kernel source code with i.MX 6 patches already applied.

In the first guide for Yocto 1.7, a custom distribution and target image was created by extending the core-image-minimal image.  In this guide, a custom distribution and target image will be created by extending the core-image-full-cmdline image.  The resulting target image will be larger in size but will include a much richer set of features for kernel and application level development and debugging on the target.

Finally, Yocto will be configured so that all source packages are archived in their original format with accompanying license files.

To start with, please read Setting up an ARM® Cortex®-A9 based SBC which outlines the necessary components that you will need to get started.  You will also need a microphone and a set of powered speakers, both with 3.5mm connectors.  I have an Audio-Technica ATR4650 microphone and a pair of Logitech S-00134 powered speakers connected to the RioTboard.  We will need these for testing audio recording and playback.

1. Hardware and software prerequisites



Host Operating System

Fedora release 21 for x86_64
GNU/Linux kernel 4.0.7-200.fc21.x86_64 #1 SMP

Host Hardware

Intel(R) Core(TM) i7-4600U CPU @ 2.10GHz
Physical Memory 12 GB
My /home partition is 414 GB and resides on a solid state hard drive.


The Yocto build requires a large amount of space so I recommend keeping a scratch area on your /home partition of at least 100 GB.  You can get away with less space but if you decide to make changes to the source and binaries within the Yocto tree later on down the line, then it is a good idea to have extra space.

2. Required Packages for a 64-bit Fedora 21 Host development system


from the Yocto Project Mega Manual Revision 1.8

Execute the following commands on the host.

 host]$ sudo yum install gawk make wget tar bzip2 gzip python unzip perl patch \
        diffutils diffstat git cpp gcc gcc-c++ glibc-devel texinfo chrpath \
        ccache perl-Data-Dumper perl-Text-ParseWords perl-Thread-Queue socat \
        findutils which
 host]$ sudo yum install SDL-devel xterm perl-Thread-Queue
 host]$ sudo yum install make docbook-style-dsssl docbook-style-xsl \
        docbook-dtds docbook-utils fop libxslt dblatex xmlto xsltproc
 host]$ sudo yum install autoconf automake libtool glib2-devel

In Part II, we will continue by pulling the source code for the kernel, boot loader, and root file system packages.  We will then build all of these components from source and prepare the GNU/Linux BSP image for the target.

Continue to Part II