GNU-Linux Rapid Embedded Programming
上QQ阅读APP看书,第一时间看更新

Yocto

As stated on the Yocto home site:

The Yocto Project is an open source collaboration project that provides templates, tools and methods to help you create custom Linux-based systems for embedded products regardless of the hardware architecture.

The Yocto Project is more than a distribution. It's intended to be a workgroup having the goal to produce tools and processes that will enable the creation of Linux distributions for embedded devices that are independent of the underlying architecture. The Yocto Project was announced by the Linux Foundation in 2010, and in the upcoming years, it aligned itself with OpenEmbedded, an existing framework with similar goals, with the result being The OpenEmbedded-Core Project.

Yocto's main components are the Linux kernel, the glibc C library, BusyBox, and matchbox (for the windowing system). This distribution is used as base distribution by the most important System-on-Chip manufactures. The distribution has its building system based on bitbake tool that automates the building process, thanks to a set of recipes and patches.

Note

More information on the Yocto Project can be retrieved from the project's homepage at:  https://www.yoctoproject.org .

In the upcoming sections, we will build a minimal image from scratch, and then, we'll show you how you can add the QT graphic libraries and how to add a new (simple) package in order to expand the distribution.

Using the default recipe

To install the base system for our SAMA5D3 Xplained board, we can use the Yocto default recipe we're going to show here. However, as the first step, we need to download the sources. This can be done with the git command:

$ git clone git://git.yoctoproject.org/poky -b jethro

Then, we have to add the meta-openembedded git repository:

$ git clone git://git.openembedded.org/meta-openembedded -b jethro

Then, add the meta-qt5 git repository to support the QT libraries (we're not using them in this first step, but we're going to use them soon, so let's do this step too):

$ git clone git://github.com/meta-qt5/meta-qt5.git -b jethro

And, as the last repository, we need meta-atmel to support our SAMA5D3 Xplained board:

$ git clone git://github.com/linux4sam/meta-atmel.git -b jethro
Note

For all repositories, we've selected the jethro branch but you can use the one which fits your needs.

OK, now, everything is in place, so let's move into the poky directory and initialize the Yocto build environment as shown here, where the oe-init-build-env file holds the environment settings needed to execute the compilation tools and build-atmel is the name of the directory where we wish to build our code:

$ cd poky
$ source oe-init-build-env build-atmel
You had no conf/local.conf file. This configuration file has therefore been
created for you with some default values. You may wish to edit it to use a
different MACHINE (target hardware) or enable parallel build options to take
advantage of multiple cores for example. See the file for more information as
common configuration options are commented.
You had no conf/bblayers.conf file. The configuration file has been created for
you with some default values. To add additional metadata layers into your
configuration please add entries to this file.
The Yocto Project has extensive documentation about OE including a reference
manual which can be found at:
http://yoctoproject.org/documentation
For more information about OpenEmbedded see their website:
http://www.openembedded.org/
### Shell environment set up for builds. ###
You can now run 'bitbake <target>'
Common targets are:
core-image-minimal
core-image-sato
meta-toolchain
adt-installer
meta-ide-support
You can also run generated qemu images with a command like 'runqemu qemux86'

As you can see, the system is telling us that we need two valid local configuration files, so we have to modify the existing conf/local.conf file as shown in the patch here:

--- ./conf/local.conf.orig  2016-06-15 14:27:11.081528459 +0200
+++ ./conf/local.conf  2016-06-15 14:27:56.653819242 +0200
@@ -34,7 +34,7 @@
 #MACHINE ?= "edgerouter"
 #
 # This sets the default machine to be qemux86 if no other machine is 
 # selected:
-MACHINE ??= "qemux86"
+MACHINE ??= "sama5d3-xplained"
 #
 # Where to place downloads
@@ -47,7 +47,7 @@
 #
 # The default is a downloads directory under TOPDIR which is the 
 # build directory.
-#DL_DIR ?= "${TOPDIR}/downloads"
+DL_DIR ?= "${TOPDIR}/downloads"

 # Where to place shared-state files
@@ -85,7 +85,7 @@
 # Ultimately when creating custom policy, people will likely end up 
 # subclassing these defaults.
 #
-DISTRO ?= "poky"
+DISTRO ?= "poky-atmel"
 # As an example of a subclass there is a "bleeding" edge policy 
 # configuration where many versions are set to the absolute latest 
 # code from the upstream source control systems. This is just 
 # mentioned here as an example, its not
@@ -104,7 +104,7 @@
 #  - 'package_rpm' for rpm style packages
 # E.g.: PACKAGE_CLASSES ?= "package_rpm package_deb package_ipk"
 # We default to rpm:
-PACKAGE_CLASSES ?= "package_rpm"
+PACKAGE_CLASSES ?= "package_ipk"
    
 #
 # SDK/ADT target architecture
@@ -137,7 +137,7 @@
 # There are other application targets that can be used here too, see
 # meta/classes/image.bbclass and meta/classes/core-image.bbclass for 
 # more details. We default to enabling the debugging tweaks.
-EXTRA_IMAGE_FEATURES = "debug-tweaks"
+EXTRA_IMAGE_FEATURES = "debug-tweaks ssh-server-openssh package-manag
ement"
    
 #
 # Additional image features

In this manner, we set the SAMA5D3 Xplained board and other minor settings regarding:

  • where to store the downloaded files with the DL_DIR define.
  • which is the distribution version to use with the DISTRO define (in our example, it's set to poky-atmel, which is the official Atmel distribution based on Yocto).
  • the software packages formats by setting the PACKAGE_CLASSES define to package_ipk in order to support the opkg format as OpenWrt.

Also note that we add the SSH server support and the IPK management system by adding the ssh-server-openssh and package-management settings to the EXTRA_IMAGE_FEATURES variable. Then, we have to replace (or modify) the conf/bblayers.conf file to add all the needed layers we downloaded earlier as shown here:

# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf 
# changes incompatibly 
LCONF_VERSION = "6" 
 
BBPATH = "${TOPDIR}" 
BBFILES ?= "" 
 
BSPDIR := "${@os.path.abspath(os.path.dirname(d.getVar('FILE', True)) + '/../../..')}" 
 
BBLAYERS ?= "  
  ${BSPDIR}/meta-atmel  
  ${BSPDIR}/meta-qt5  
  ${BSPDIR}/poky/meta  
  ${BSPDIR}/poky/meta-yocto  
  ${BSPDIR}/poky/meta-yocto-bsp  
  ${BSPDIR}/meta-openembedded/meta-oe  
  ${BSPDIR}/meta-openembedded/meta-networking  
  ${BSPDIR}/meta-openembedded/meta-python  
  ${BSPDIR}/meta-openembedded/meta-ruby  
  ${BSPDIR}/meta-openembedded/meta-multimedia  
  " 
BBLAYERS_NON_REMOVABLE ?= "  
  ${BSPDIR}/poky/meta  
  ${BSPDIR}/poky/meta-yocto  
  " 

Apart from the first settings, the real important part here is BBLAYERS and BBLAYERS_NON_REMOVABLE that define the layers that the bitbake program should traverse in order to find the recipes to build the whole distribution. Each layer holds a specific part of the distribution, and it is usually based on other layers in such a way to have a well modular and stratified system.

Note

For further information on the layer concept and related information, you can take a look at the Yocto Project Development Manual at: http://www.yoctoproject.org/docs/2.1/dev-manual/dev-manual.html.

Now, if we re-execute the source command, we should get no errors:

$ source oe-init-build-env build-atmel
### Shell environment set up for builds. ###
You can now run 'bitbake <target>'
Common targets are:
core-image-minimal
core-image-sato
meta-toolchain
adt-installer
meta-ide-support
You can also run generated qemu images with a command like 'runqemu qemux86'

Great! Now, our first target is core-image-minimal, and to get it compiled, we have to execute the following command as suggested from the preceding message:

$ bitbake core-image-minimal
WARNING: Unable to get checksum for linux-at91 SRC_URI entry defconfig : file could not be found
Parsing recipes: 3% |# | ETA: 00:04:52
Tip

It may happen that we get the following error:


 $ bitbake core-image-minimal

 ERROR: OE-core's config sanity checker detected a 


 potential misconfiguration.

 Either fix the cause of this error or at your o

 wn risk disable the checker (see sanity.conf).

 Following is the list of potential problems / a
 dvisories:

 Please install the following missing utilities:


 makeinfo,chrpath


 Summary: There was 1 ERROR message shown, returning


 a non-zero exit code.

In this case, as for OpenWrt, some dependency package is missing. In the preceding example, we can fix the error by installing the packages texinfo e chrpath using the usual aptitude or apt-get command.

If everything goes well, after the parsing stage, we should get something like this:

Parsing of 1924 .bb files complete (0 cached, 1924 parsed). 2470 targe ts, 377 skipped, 0 masked, 0 errors. NOTE: Resolving any missing task queue dependencies Build Configuration: BB_VERSION = "1.28.0" BUILD_SYS = "x86_64-linux" NATIVELSBSTRING = "Ubuntu-15.10" TARGET_SYS = "arm-poky-linux-gnueabi" MACHINE = "sama5d3-xplained" DISTRO = "poky-atmel" DISTRO_VERSION = "2.0.2" TUNE_FEATURES = "arm armv7a vfp thumb callconvention-hard cortexa5 " TARGET_FPU = "vfp" meta-atmel = "jethro:4765d7064e4916784c15095347eda21cc10aabb4" meta-qt5 = "jethro:ea37a0bc987aa9484937ad68f762b4657c198617" meta meta-yocto meta-yocto-bsp = "jethro:ddbc13155f4db5d98976dc93b586c0be4fc740d1" meta-oe meta-networking meta-python meta-ruby meta-multimedia = "jethro:cb7e68f2a39fa6f24add48fc7b8d38fb7291bb44"

Then, the compilation will start using one thread per available CPU:

NOTE: Preparing RunQueue
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
Currently 2 running tasks (42 of 1634):
0: xz-native-5.2.1-r0 do_fetch (pid 19217)
1: m4-native-1.4.17-r0 do_configure (pid 19305)
...
Note

The compilation is very time consuming, so you should consider to take time to have your preferred coffee!

When the compilation is finished, we should get the compilation result in the tmp/deploy/images/sama5d3-xplained/ directory as shown here:

$ ls tmp/deploy/images/sama5d3-xplained/
at91bootstrap.bin
at91bootstrap-sama5d3_xplained.bin
BOOT.BIN
core-image-minimal-sama5d3-xplained-20160618162845.rootfs.manifest
core-image-minimal-sama5d3-xplained-20160618162845.rootfs.tar.gz
core-image-minimal-sama5d3-xplained-20160618162845.rootfs.ubi
core-image-minimal-sama5d3-xplained-20160618162845.rootfs.ubifs
core-image-minimal-sama5d3-xplained.manifest
core-image-minimal-sama5d3-xplained.tar.gz
core-image-minimal-sama5d3-xplained.ubi
modules--4.1+git0+6546e3c770-r0-sama5d3-xplained-20160618162845.tgz
modules-sama5d3-xplained.tgz
README_-_DO_NOT_DELETE_FILES_IN_THIS_DIRECTORY.txt
sama5d3_xplained-nandflashboot-uboot-3.8.4.bin
ubinize.cfg
u-boot.bin
u-boot-sama5d3-xplained.bin
u-boot-sama5d3-xplained-v2015.01-at91-r0.bin
zImage
zImage--4.1+git0+6546e3c770-r0-at91-sama5d3_xplained-20160618162845.dt
b
zImage--4.1+git0+6546e3c770-r0-at91-sama5d3_xplained_pda4-201606181628
45.dtb
zImage--4.1+git0+6546e3c770-r0-at91-sama5d3_xplained_pda7-201606181628
45.dtb
zImage--4.1+git0+6546e3c770-r0-at91-sama5d3_xplained_pda7b-20160618162
845.dtb
zImage--4.1+git0+6546e3c770-r0-sama5d3-xplained-20160618162845.bin
zImage-at91-sama5d3_xplained.dtb
zImage-at91-sama5d3_xplained_pda4.dtb
zImage-at91-sama5d3_xplained_pda7b.dtb
zImage-at91-sama5d3_xplained_pda7.dtb
zImage-sama5d3-xplained.bin

They seem a lot of files, but in reality, most of them are just symbolic links to real image files that are only the following ones:

$ find . -type f
./zImage--4.1+git0+6546e3c770-r0-sama5d3-xplained-20160618162845.bin
./zImage--4.1+git0+6546e3c770-r0-at91-sama5d3_xplained-20160618162845.
dtb
./zImage--4.1+git0+6546e3c770-r0-at91-sama5d3_xplained_pda4-2016061816
2845.dtb
./ubinize.cfg
./zImage--4.1+git0+6546e3c770-r0-at91-sama5d3_xplained_pda7b-201606181
62845.dtb
./core-image-minimal-sama5d3-xplained-20160618162845.rootfs.ubifs
./modules--4.1+git0+6546e3c770-r0-sama5d3-xplained-20160618162845.tgz
./README_-_DO_NOT_DELETE_FILES_IN_THIS_DIRECTORY.txt
./zImage--4.1+git0+6546e3c770-r0-at91-sama5d3_xplained_pda7-2016061816
2845.dtb
./u-boot-sama5d3-xplained-v2015.01-at91-r0.bin
./core-image-minimal-sama5d3-xplained-20160618162845.rootfs.tar.gz
./sama5d3_xplained-nandflashboot-uboot-3.8.4.bin
./core-image-minimal-sama5d3-xplained-20160618162845.rootfs.ubi
./core-image-minimal-sama5d3-xplained-20160618162845.rootfs.manifest

For our purposes, the needed files are:

  • sama5d3_xplained-nandflashboot-uboot-3.8.4.bin - that is the prebootloader, that is the boot.bin file we used into Chapter 1, Installing the Developing System, U-Boot (with boot.bin).
  • u-boot-sama5d3-xplained-v2015.01-at91-r0.bin - that is the U-Boot image.
  • zImage-at91-sama5d3_xplained.dtb - the DTB file.
  • zImage-sama5d3-xplained.bin - the kernel image.
  • core-image-minimal-sama5d3-xplained.ubi - that is the rootfs of our Yocto distribution (in the UBIFS format).
Tip

This time, the embedded distribution has compiled the bootloaders also.

OK, now, as done before for OpenWrt, we only have to move these files into our SAMA5D3 Xplained running the Debian OS (that is, we only have to reinsert the microSD and then restart the system) and then re-flash the NAND memory partitions again. So, let's start by copying the images on the SAMA5D3 Xplained board:

$ scp sama5d3_xplained-nandflashboot-uboot-3.8.4.bin 
u-boot-sama5d3-xplained-v2015.01-at91-r0.bin 
zImage-at91-sama5d3_xplained.dtb 
zImage-sama5d3-xplained.bin 
core-image-minimal-sama5d3-xplained.ubi root@192.168.8.2:nand/

Then, on the SAMA5D3 Xplained, we have to erase and then reprogram the flash as done earlier, but using the Yocto files:

root@a5d3:~# flash_erase -q /dev/mtd0 0 0 root@a5d3:~# flash_erase -q /dev/mtd1 0 0 root@a5d3:~# flash_erase -q /dev/mtd2 0 0 root@a5d3:~# flash_erase -q /dev/mtd3 0 0 root@a5d3:~# flash_erase -q /dev/mtd4 0 0 root@a5d3:~# flash_erase -q /dev/mtd5 0 0 root@a5d3:~# nandwrite -q -m -p /dev/mtd0 nand/sama5d3_xplained-nandfl
ashboot-uboot-3.8.4.bin
root@a5d3:~# nandwrite -q -m -p /dev/mtd1 nand/u-boot-sama5d3-xplained
-v2015.01-at91-r0.bin
root@a5d3:~# nandwrite -q -m -p /dev/mtd3 nand/zImage-at91-sama5d3_xpl
ained.dtb
root@a5d3:~# nandwrite -q -m -p /dev/mtd4 nand/zImage-sama5d3-xplained
.bin
root@a5d3:~# nandwrite -q -m -p /dev/mtd5 nand/core-image-minimal-sama
5d3-xplained.ubi

When finished, we have to redo the steps we did for OpwnWRT, that is, stopping the system and then resetting it and rebooting without the microSD.

Tip

For some unknown reasons, it may happen that when we reboot the system, it will refuse to boot showing the usual RomBOOT message. In this case, the prebootloader image is corrupted, but we can recover it using the one we used for OpenWrt to successfully boot Yocto. We just need to re-erase the first partition and then put into it the OpenWrt's prebootloader image that should already be into the current nand directory:


 root@a5d3:~/nand# flash_erase -q /dev/mtd0 0 0


 root@a5d3:~/nand# nandwrite -q -m -p /dev/mtd0 boo


 t.bin

If everything works well after the reset, we should get the following output:

U-Boot SPL 2016.03-dirty (Jun 15 2016 - 16:19:44)
Trying to boot from NAND
U-Boot 2015.01-linux4sam_5.2-00004-g0bb0194 (Jun 18 2016 - 17:53:07)
CPU: SAMA5D36
Crystal frequency: 12 MHz
CPU clock : 528 MHz
Master clock : 132 MHz
I2C: ready
DRAM: 256 MiB
NAND: 256 MiB
MMC: mci: 0
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Read from EEPROM @ 0x58 failed
Read from EEPROM @ 0x59 failed
Net: gmac0
Error: gmac0 address not set.
, macb0
Error: macb0 address not set.
Hit any key to stop autoboot: 0
NAND read: device 0 offset 0x180000, size 0x80000
 524288 bytes read: OK
NAND read: device 0 offset 0x200000, size 0x600000
 6291456 bytes read: OK
Kernel image @ 0x22000000 [ 0x000000 - 0x363c18 ]
## Flattened Device Tree blob at 21000000
 Booting using the fdt blob at 0x21000000
 Loading Device Tree to 2fb32000, end 2fb3d83f ... OK
Starting kernel ...
Booting Linux on physical CPU 0x0
Linux version 4.1.0-linux4sam_5.3-00050-g6546e3c (giometti@ubuntu1510)
 (gcc vers
ion 5.2.0 (GCC) ) #1 Sat Jun 18 18:40:31 CEST 2016
CPU: ARMv7 Processor [410fc051] revision 1 (ARMv7), cr=10c53c7d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cac
he
Machine model: SAMA5D3 Xplained
...

Great, as we can see Yocto has a kernel release 4.1 instead of the 3.18 of the OpenWrt.

Then we can verify that the flash has a compatible partitioning compared with the Debian's one:

...
8 cmdlinepart partitions found on MTD device atmel_nand
Creating 8 MTD partitions on "atmel_nand":
0x000000000000-0x000000040000 : "bootstrap"
0x000000040000-0x0000000c0000 : "uboot"
0x0000000c0000-0x000000100000 : "env"
0x000000100000-0x000000140000 : "env_redundent"
0x000000140000-0x000000180000 : "spare"
0x000000180000-0x000000200000 : "dtb"
0x000000200000-0x000000800000 : "kernel"
0x000000800000-0x000010000000 : "rootfs"
...

Yes, it's perfectly compatible since all the main partitions (kernel, DTB, and rootfs) are into their correct positions. In fact, here, we can see that the UBIFS is correctly mounted:

ubi0: attaching mtd7
ubi0: scanning is finished
gluebi (pid 1): gluebi_resized: got update notification for unknown UB
I device 0 volume 0
ubi0: volume 0 ("rootfs") re-sized from 38 to 1940 LEBs
ubi0: attached mtd7 (name "rootfs", size 248 MiB)
ubi0: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes
ubi0: min./max. I/O unit sizes: 2048/2048, sub-page size 2048
ubi0: VID header offset: 2048 (aligned 2048), data offset: 4096
ubi0: good PEBs: 1978, bad PEBs: 6, corrupted PEBs: 0
ubi0: user volume: 1, internal volumes: 1, max. volumes count: 128
ubi0: max/mean erase counter: 1/0, WL threshold: 4096, image sequence 
number: 607988663
ubi0: available PEBs: 0, total reserved PEBs: 1978, PEBs reserved for 
bad PEB handling: 34
ubi0: background thread "ubi_bgt0d" started, PID 645
...
UBIFS (ubi0:0): UBIFS: mounted UBI device 0, volume 0, name "rootfs", 
R/O mode
UBIFS (ubi0:0): LEB size: 126976 bytes (124 KiB), min./max. I/O unit s
izes: 2048 bytes/2048 bytes
UBIFS (ubi0:0): FS size: 244936704 bytes (233 MiB, 1929 LEBs), journal
 size 9023488 bytes (8 MiB, 72 LEBs)
UBIFS (ubi0:0): reserved for root: 0 bytes (0 KiB)
UBIFS (ubi0:0): media format: w4/r0 (latest is w4/r0), UUID 4F641563-5
796-4C7F-A57B-5D78E29FE530, small LPT model
VFS: Mounted root (ubifs filesystem) readonly on device 0:13.
devtmpfs: mounted
Freeing unused kernel memory: 188K (c068b000 - c06ba000)
random: nonblocking pool is initialized
INIT: version 2.88 booting
Starting udev
udevd[677]: starting version 182
...

Then, at the end of the boot stage, we finally get the login prompt:

...
INIT: Entering runlevel: 5
Configuring network interfaces... udhcpc (v1.23.2) started
Sending discover...
macb f0028000.ethernet eth0: link up (100/Full)
Sending discover...
Sending select for 192.168.32.57...
Lease of 192.168.32.57 obtained, lease time 268435455
/etc/udhcpc.d/50default: Adding DNS 192.168.32.8
done.
Starting OpenBSD Secure Shell server: sshd
generating ssh RSA key...
generating ssh ECDSA key...
generating ssh DSA key...
generating ssh ED25519 key...
done.
Starting syslogd/klogd: done
Poky (Yocto Project Reference Distro) 2.0.2 sama5d3-xplained /dev/ttyS0
sama5d3-xplained login:

Here, we just need to enter the root user, and we'll get the prompt without entering any password:

sama5d3-xplained login: root
root@sama5d3-xplained:~# 

Now, we can take a look at the flash storage occupation as we did for OpenWrt:

root@sama5d3-xplained:~# df -h
Filesystem Size Used Available Use% Mounted on
ubi0:rootfs 215.4M 2.9M 212.5M 1% /
devtmpfs 91.2M 0 91.2M 0% /dev
tmpfs 123.3M 96.0K 123.2M 0% /run
tmpfs 123.3M 92.0K 123.2M 0% /var/volatile

Again, the footprint is very minimal, less than 3MB!

Now, before continuing, let's verify the networking support, so just plug an Ethernet cable and then execute the ifconfig command:

root@sama5d3-xplained:~# ifconfig
eth0 Link encap:Ethernet HWaddr BA:A0:13:9E:7A:99 
 inet addr:192.168.32.57 Bcast:192.168.32.255 Mask:255.255. 255.0
 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
 RX packets:190 errors:0 dropped:0 overruns:0 frame:0
 TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:1000
 RX bytes:46940 (45.8 KiB) TX bytes:684 (684.0 B)
 Interrupt:51 Base address:0x8000

OK! The networking settings are set to DHCP. At this point, we can keep the current settings or we can modify them by modifying the /etc/network/interfaces file and the restarting the networking system with this command:

root@sama5d3-xplained:~# /etc/init.d/networking restart

Here is reported a snapped of the default version of the /etc/network/interfaces file where you can see the DHCP settings and the static IP ones:

# Wired or wireless interfaces 
auto eth0 
iface eth0 inet dhcp 
iface eth1 inet dhcp 
 
# Ethernet/RNDIS gadget (g_ether) 
# ... or on host side, usbnet and random hwaddr 
iface usb0 inet static 
    address 192.168.7.2 
    netmask 255.255.255.0 
    network 192.168.7.0 
    gateway 192.168.7.1 

Adding the graphic support

One of the main advantages in using the Yocto distribution is that it natively supports the QT graphic library, and we can add a very impressive Graphic User Interface (GUI) in a quick and easy manner.

Tip

For more information on the QT graphic library, you can go to the project homesite at:  https://www.qt.io .

In this section, we will see how we can add this graphic support to our SAMA5D3 Xplained using the same Yocto code we just downloaded earlier. The only thing we have to do more is just add the following settings to the conf/local.conf file in order to avoid the compilation of non Software Libre into our image. It's quite obvious that we need an LCD to be connected to our board to run this demo, but you can buy it where they brought the SAMA5D3 Xplained.

OK, the modification for the conf/local.conf file is as follows:

--- conf/local.conf.orig 2016-06-05 19:04:17.788202448 +0200
+++ conf/local.conf 2016-06-19 10:36:50.574587468 +0200
@@ -237,3 +237,6 @@
# 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"
+
+LICENSE_FLAGS_WHITELIST += "commercial"
+SYSVINIT_ENABLED_GETTYS = ""
Note

Refer to Atmel in order to have more information on the licenses involved in this demo. I am programmer, not a lawyer!

Once the modification is in place, we just need to re-execute bitbake with the atmel-qt5-demo-image target in order to start the QT compilation:

$ bitbake atmel-qt5-demo-image
Note

If the previous Yocto image compilation was time consuming, this one is even more time consuming! So, consider to have more coffees.

When finished, the results are still in the tmp/deploy/images/sama5d3-xplained/ directory, but this time, the rootfs image files have been named with the atmel-qt5-demo-image-sama5d3-xplained prefix as shown here:

$ cd tmp/deploy/images/sama5d3-xplained/
$ ls atmel-qt5-demo-image-sama5d3-xplained*
atmel-qt5-demo-image-sama5d3-xplained-20160619195155.rootfs.manifest
atmel-qt5-demo-image-sama5d3-xplained-20160619195155.rootfs.tar.gz
atmel-qt5-demo-image-sama5d3-xplained-20160619195155.rootfs.ubi
atmel-qt5-demo-image-sama5d3-xplained-20160619195155.rootfs.ubifs
atmel-qt5-demo-image-sama5d3-xplained.manifest
atmel-qt5-demo-image-sama5d3-xplained.tar.gz
atmel-qt5-demo-image-sama5d3-xplained.ubi

Now, we have to flash a new DTB file, kernel image, and rootfs, so the scp command to transfer the new images on the SAMA5D3 Xplained is here:

$ scp zImage-at91-sama5d3_xplained_pda7.dtb 
zImage-sama5d3-xplained.bin 
atmel-qt5-demo-image-sama5d3-xplained.ubi root@192.168.8.2:nand/
Note

We have several DTB files. You must select the right one in order to fit your LCD hardware.

Then, on the SAMA5D3 Xplained, we have to execute these commands:

root@a5d3:~# flash_erase -q /dev/mtd3 0 0 root@a5d3:~# flash_erase -q /dev/mtd4 0 0 root@a5d3:~# flash_erase -q /dev/mtd5 0 0 root@a5d3:~# nandwrite -q -m -p /dev/mtd3 nand/zImage-at91-sama5d3_xpl
ained_pda7.dtb
root@a5d3:~# nandwrite -q -m -p /dev/mtd4 nand/zImage-sama5d3-xplained
.bin
root@a5d3:~# nandwrite -q -m -p /dev/mtd5 nand/atmel-qt5-demo-image-sa
ma5d3-xplained.ubi
Note

The last command is quite slow due to the fact that the new image is bigger than before. The graphic libraries take a lot of space.

If everything goes well, at the new reboot on the LCD, we should see something similar to the following image:

Just to show the differences between having or not having a graphical support below if the NAND usage on my system:

root@sama5d3-xplained:~# df -h
Filesystem Size Used Avail Use% Mounted on
ubi0:rootfs 216M 176M 40M 82% /
devtmpfs 92M 0 92M 0% /dev
tmpfs 124M 124K 124M 1% /run
tmpfs 124M 160K 124M 1% /var/volatile

As we can see, if we can largely stay below 16MB before, now, the NAND usage is more that 170MB!

Note

We can avoid compiling this demo and then get it already done to be flashed on the Atmel Linux4SAM demo archives page at http://www.at91.com/linux4sam/bin/view/Linux4SAM/Sama5d3XplainedMainPage#Demo_archives .Note also that at that link, we can find information regarding the LCDs available on the boards and the relative DTB files names.

Adding a custom recipe

Now, as the last step we'd like to add a custom program to our new Yocto distribution, so we can do the same as for OpenWrt by adding the classic Hello World example. However, this time, doing it is really easy since Yocto gives us a powerful tool to add a new layer that already holds the Hello World program!

As already stated earlier, Yocto has been composed of several layers, and in order to add our custom applications, it's preferred that we do it by creating a new layer. To do so, we can use the yocto-layer script that drastically simplifies the developer's job, so here is a snippet of the help message of its create command (the help message has been generated using the command line ./scripts/yocto-layer help create).

OK, so let's go to the poky directory where we downloaded all Yocto's repositories and then execute the script as shown here:

$ cd ..
$ ./poky/scripts/yocto-layer create applications
Please enter the layer priority you'd like to use for the layer: [defa
ult: 6]
Would you like to have an example recipe created? (y/n) [default: n] y
Please enter the name you'd like to use for your example recipe: [defa
ult: example] helloworld
Would you like to have an example bbappend file created? (y/n) [defaul
t: n] y
Please enter the name you'd like to use for your bbappend file: [defau
lt: example] helloworld
Please enter the version number you'd like to use for your bbappend fi
le (this should match the recipe you're appending to): [default: 0.1]
New layer created in meta-applications.
Don't forget to add it to your BBLAYERS (for details see meta-applicat
ions\README).

In the preceding output, the highlighted text are the answers we gave to the command. Notice that we forced both the names of the example recipe and the bbappend file to helloworld.

Well, now, we have a new meta-applications directory where a new recipe tree has been created, as shown here:

$ ls
meta-applications/ meta-atmel/ meta-openembedded/ meta-qt5/ poky/
$ tree meta-applications/
meta-applications/
+-- conf
|   \-- layer.conf
+-- COPYING.MIT
+-- README
+-- recipes-example
|   +-- example
|       +-- helloworld-0.1
|       |   +-- example.patch
|       |   \-- helloworld.c
|       \-- helloworld_0.1.bb
\-- recipes-example-bbappend
    \-- example-bbappend
        +-- helloworld-0.1
        |   \-- example.patch
        \-- helloworld_0.1.bbappend
    
7 directories, 8 files

Now, we can take a look at the new files and, in particular, the helloworld_0.1.bb file, which holds the recipe that defines the new package's compilation steps, which are reported here:

# 
# This file was derived from the 'Hello World!' example recipe in the 
# Yocto Project Development Manual. 
# 
 
SUMMARY = "Simple helloworld application" 
SECTION = "examples" 
LICENSE = "MIT" 
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0b
cf8506ecda2f7b4f302" 
 
SRC_URI = "file://helloworld.c" 
 
S = "${WORKDIR}" 
 
do_compile() { 
    ${CC} helloworld.c -o helloworld 
} 
 
do_install() { 
    install -d ${D}${bindir} 
    install -m 0755 helloworld ${D}${bindir} 
} 

You should notice that even in this case, the recipe files have a similar structure like the OpenWrt's makefiles. We have several default actions (download, compile, install, and so on) that can be redefined according to our needs.

Tip

For more information on how to write a new recipe (or whatever we wish to add), we can take a look at:  http://www.yoctoproject.org/docs/2.1/dev-manual/dev-manual.html#new-recipe-writing-a-new-recipe .

Now, we only have to add our new meta directory to the conf/bblayers.conf file as shown here:

--- conf/bblayers.conf.orig  2016-06-19 19:13:52.380757585 +0200
+++ conf/bblayers.conf  2016-06-19 19:14:07.476705872 +0200
@@ -18,6 +18,7 @@
   ${BSPDIR}/meta-openembedded/meta-python 
   ${BSPDIR}/meta-openembedded/meta-ruby 
   ${BSPDIR}/meta-openembedded/meta-multimedia 
+  ${BSPDIR}/meta-applications 
   "
    
 BBLAYERS_NON_REMOVABLE ?= " 

OK, everything is in place, and we can compile our new package by executing the bitbake command as follows:

$ bitbake helloworld
Loading cache: 100% |###########################################| ETA:
 00:00:00
Loaded 2464 entries from dependency cache.
Parsing recipes: 100% |#########################################| Time
: 00:00:02
Parsing of 1925 .bb files complete (1917 cached, 8 parsed). 2471 targe
ts, 353 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
Build Configuration:
BB_VERSION = "1.28.0"
BUILD_SYS = "x86_64-linux"
NATIVELSBSTRING = "Ubuntu-15.10"
TARGET_SYS = "arm-poky-linux-gnueabi"
MACHINE = "sama5d3-xplained"
DISTRO = "poky-atmel"
DISTRO_VERSION = "2.0.2"
TUNE_FEATURES = "arm armv7a vfp thumb callconvention-hard cortexa5
"
TARGET_FPU = "vfp"
meta-atmel = "jethro:4765d7064e4916784c15095347eda21cc10aabb4"
meta-qt5 = "jethro:ea37a0bc987aa9484937ad68f762b4657c198617"
meta 
meta-yocto 
meta-yocto-bsp = "<unknown>:<unknown>"
meta-oe 
meta-networking 
meta-python 
meta-ruby 
meta-multimedia = "jethro:cb7e68f2a39fa6f24add48fc7b8d38fb7291bb44"
meta-applications = "<unknown>:<unknown>"
NOTE: Preparing RunQueue
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
NOTE: Tasks Summary: Attempted 378 tasks of which 365 didn't need to b
e rerun and all succeeded.
Note

Note that bitbake now sees our new layers!

When the compilation has been finished, the new package is ready to be installed in the tmp/deploy/ipk/ directory:

$ ls tmp/deploy/ipk/cortexa5hf-vfp/helloworld*.ipk
tmp/deploy/ipk/cortexa5hf-vfp/helloworld_0.1-r0_cortexa5hf-vfp.ipk
tmp/deploy/ipk/cortexa5hf-vfp/helloworld-dbg_0.1-r0_cortexa5hf-vfp.ipk
tmp/deploy/ipk/cortexa5hf-vfp/helloworld-dev_0.1-r0_cortexa5hf-vfp.ipk

So, let's copy it into Yocto using the scp command:

$ scp tmp/deploy/ipk/cortexa5hf-vfp/helloworld_0.1-r0_cortexa5hf-vfp.i pk 
root@192.168.32.57:/tmp/

Then, on the SAMA5D3 Xplained, we have to install the package with the usual opkg command, and then, we can execute it as shown here:

root@sama5d3-xplained:~# opkg install /tmp/helloworld_0.1-r0_cortexa5h
f-vfp.ipk
Installing helloworld (0.1-r0) on root.
Configuring helloworld.
root@sama5d3-xplained:~# helloworld
Hello World!