Mind Chasers Inc.
Mind Chasers Inc.

Install Embedded Linux Built with Yocto Project

Summary of steps used to install and boot an embedded Linux image on a T1040RDB. Image was built with Yocto Project 2.7 using mainline Linux 5.0 kernel and our custom layer.

Overview

Provided below are the steps we use to install / update a Yocto-built image on an embedded Linux system. This particular system is a Freescale / NXP T1040RDB that we use with an SSD to run & test the Linux mainline kernel with the latest Yocto / Poky master branch. We also use our own custom layer & image that includes our miscellaneous daemons, scripts, and customized packages targeted at securing & monitoring a local network.

This is an older system, but it has great network performance and several Gigabit Ethernet ports since it's one of NXP's PowerPC-based network processors (QorIQ family). Also, we have a hardware debugger for it and can use NXP's Codewarrior debugger on it, so we love having it in our lab.

We typically build and test the latest release candidate (rc) of the Linux kernel independently before updating our Yocto recipe for the kernel. We're fortunate that this system and the T1040's PowerPC64 E5500 processor are supported without patching in the 5.0 Linux kernel. This is a big plus and a good reason to use older hardware for development and testing since all the drivers have already been reviewed and upstreamed.

Note that the Poky meta-freescale repo no longer carries a machine conf file for the T1040RDB, but it's easy enough to create one from a similar system, and we maintain t1040rdb-64b.conf and defconfig files in our own custom layer. Also, corenet64_fmanv3l_smp_defconfig provided our starting point for our defconfig.

The steps shown below assume that the embedded system can be booted with at least a minimal Linux image with NFS support to mount a drive from the build machine that produced the Yocto rootfs image.

Partitioning our SSD

We're using a 64G Micron M550 SSD on the T1040RDB. We divide our development disk into 4 partitions as shown below.

# fdisk -l /dev/sda
...

Device     Boot    Start       End  Sectors  Size Id Type
/dev/sda1           2048   4196351  4194304    2G 83 Linux
/dev/sda2        4196352  41945087 37748736   18G 83 Linux
/dev/sda3       41945088  79693823 37748736   18G 83 Linux
/dev/sda4       79693824 125045423 45351600 21.6G 83 Linux

We alternate between /dev/sda2 and /dev/sda3 as our current root filesystem, so we always have a known good backup. We mount /dev/sda4 as /build for building applications natively and storing databases that need to be persistent between updates of our root filesystem. We keep /dev/sda1 reserved for other images (i.e., NXP's SDK-built image). /build is mounted automatically each time by a custom init script that we add to our rootfs by appending the initscripts recipe:

initscripts_1.%.bbappend:
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

SRC_URI += "file://mntbuild.sh"

do_install_append() {
    install -m 0755    ${WORKDIR}/mntbuild.sh       ${D}${sysconfdir}/init.d
    update-rc.d -r ${D} mntbuild.sh start 70 2 3 4 5 .
}
mntbuild.sh:
#!/bin/sh

mkdir -p /build
mount /dev/sda4 /build

Yes, we're still using sysvinit for this system / image. Yocto supports both sysvinit and systemd.

Make the disk

Determine which partitions are already mounted:

# mount
/dev/sda3 on / type ext3 (rw,relatime)
devtmpfs on /dev type devtmpfs (rw,relatime,size=1998340k,nr_inodes=499585,mode=755)
proc on /proc type proc (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
tmpfs on /var/volatile type tmpfs (rw,relatime)
/dev/sda4 on /run/media/sda4 type ext2 (rw,relatime,errors=continue)
/dev/sda1 on /run/media/sda1 type ext2 (rw,relatime,errors=continue)
/dev/sda2 on /run/media/sda2 type ext3 (rw,relatime)
...

We can see that our rootfs is currently located on /dev/sda3, so we'll use /dev/sda2 for our new rootfs. Unmount the /dev/sda2 partition and create a new file system (with journalling) on the partition.

# umount /dev/sda2

# mke2fs -j /dev/sda2

Mount the new partition to /mnt/disk so we can copy our rootfs onto it.

# mkdir -p /mnt/disk

# mount /dev/sda2 /mnt/disk

# ls -l /mnt/disk
total 16
drwx------ 2 root root 16384 Mar  9 13:00 lost+found

Copy Yocto-built file system (rootfs) to drive:

We utilize NFS from our T1040RDB Linux system to mount our build machine's folder where our Yocto-built rootfs resides. Provided below is an excerpt of our mount script that mounts the /build directory to our embedded system's /mnt/build path. In the script, $1 is the build machine's (PC) host name

mnt_build_machine.sh
#!/bin/sh
...

if ! echo `mount` | grep "/mnt/build" >> /dev/null; then
        mkdir -p /mnt/build
        mount -o vers=3 -o nolock $1:/build /mnt/build
fi

From the T1040RDB's shell, cd to the PC image's rootfs folder and copy the rootfs. BTW, we configure our embedded system's prompt as export PS1='\u@:\W\$ '. Also note below that we leave a token using touch in our rootfs to help us later match up the target disk with where and when it was built.

# cd /mnt/build/<bsp location/image/release/>rootfs

rootfs# ls

bin  boot  dev  etc  home  lib  media  mnt  proc  run  sbin  sys  tmp  usr  var

rootfs# touch t1040rdb_<date>

rootfs# cp -r * /mnt/disk/

rootfs# cd /mnt/disk

disk# ls

bin  boot  dev  etc  home  lib  lost+found  media  mnt  t1040_030919  proc  run  sbin  sys  tmp  usr  var

Create u-boot boot script and launch system

Returning to our build machine, we create / update our u-boot script that is used to boot our system from the u-boot shell. Copy both the generated Linux uImage file and dtb file to our tftp server location:

$ cp /build/<path>/tmp-glibc/deploy/images/t1040rdb-64b/uImage /build/tftp/t1040/
$ cp /build/<path>/tmp-glibc/deploy/images/t1040rdb-64b/t1040rdb.dtb /build/tftp/t1040/

Create the u-boot script: "boot.txt"

setenv bootargs root=/dev/sda2 rw console=ttyS0,115200 loglevel=8
tftp 0x2000000 t1040/uImage-5.0
tftp 0x1000000 t1040/t1040rdb.dtb
bootm 0x2000000 - 0x1000000

Make the u-boot image:

$ mkimage -T script -C none -n "uboot script" -d boot.txt boot.img

The last steps are to reboot our embedded system, download the u-boot script, and then source it.

# reboot
....

=> tftp t1040/boot.img
Load address: 0x1000000
Loading: #
	 38.1 KiB/s
done
Bytes transferred = 239 (ef hex)
=> source 0x1000000


....

OpenEmbedded nodistro.0 t1040rdb-64b ttyS0

t1040rdb-64b login: root
root@:~# uname -a
Linux t1040rdb-64b 5.0.0-yocto-standard #21 SMP Sat Mar 9 12:05:54 EST 2019 ppc64 ppc64 ppc64 GNU/Linux

# python3 --version
Python 3.7.2

# nft -v
nftables v0.9.0 (Fearless Fosdick)
T1040RDB
T1040RDB

Didn't find an answer to your question? Post your issue below or in our new FORUM, and we'll try our best to help you find a solution.

And please note that we update our site daily with new content related to our open source approach to network security and system design. If you would like to be notified about these changes, then please follow us on Twitter and join our mailing list.

Related articles on this site:

share
subscribe to mailing list:

Please help us improve this article by adding your comment or question:

your email address will be kept private
authenticate with a 3rd party for enhanced features, such as image upload
previous month
next month
Su
Mo
Tu
Wd
Th
Fr
Sa
loading