Recap: Yocto Project Developer Day - ELCE 2014

../../../_images/IMG_2950_small.JPG ../../../_images/IMG_2945_small.JPG ../../../_images/IMG_2958_small.JPG

Overview

Some days have passed since the Yocto Project Developer Day, now it’s time for a recap.

Preliminary Note

If you have not taken part in the Yocto Project Developer Day then this article should give you all the information you need to work through the Advanced Lab: IoT Development on your own and learn more about embedded Linux development with the Yocto Project.

All you need is a PC running Linux. If you want to test your code on real hardware too then you will also need some LEDs, Resitors, Buttons (parts list) and either the MinnowBoard Max, the BeagleBone Black or the WandBoard Quad.

The Yocto Project Developer Day

This Year it was my first time at the Embedded Linux Conference Europe, it was really a great time. I also took the opportunity to attend the Advanced Lab: IoT Development at the co-located Yocto Project Developer Day which will be the topic for this article.

The registration fee was $79.00 and we could choose either the MinnowBoard Max, the BeagleBone Black or the WandBoard Quad to deploy our code on and keep everything in the end.

I took the WandBoard Quad which has a Freescale i.MX6 Quad processor, 2GB of DDR3 memory, microSD slot, HDMI, USB, USB OTG, SATA, Gigabit LAN, WiFi (802.11n), Bluetooth and some other interfaces. Pretty impressive in my opinion :)

We got plenty of cool stuff, thanks to the sponsors (Yocto Project, SanDisk, Texas Instruments, Intel Corporation, Wind River Systems, ExpEmb, TechNexion)

We got plenty of cool stuff, thanks to the sponsors (Yocto Project, SanDisk, Texas Instruments, Intel Corporation, Wind River Systems, ExpEmb, TechNexion).

Advanced Lab: IoT Development

Advanced Lab: IoT Development - David Reyna, Mark Hatle, Wind River Systems

This advanced hands-on lab leads attendees through the decision process to determine the contents of an image for an IoT-focused device. The lab requires attendees to use their own laptops to connect to a virtual private cloud server, where they will perform the builds as if they were local and then see the results using their chosen board, with any needed peripherals provided. You will use the provided board and then take it home with you, and the lab will continue to be accessible after the conference. (slides (mirror))

IoT Hero

IoT Hero

The Mission

The Mission

Lab Setup

Install Repo

[chris@thinkpad ~]$ curl --create-dirs -o ~/bin/repo https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
[chris@thinkpad ~]$ chmod a+x ~/bin/repo

Initialize your working directory

[chris@thinkpad ~]$ sudo mkdir -p /scratch/yocto/sources
[chris@thinkpad ~]$ sudo chown $USER:$USER -R /scratch
[chris@thinkpad ~]$ mkdir -p /scratch/working
[chris@thinkpad ~]$ cd /scratch/yocto/sources
[chris@thinkpad sources]$ repo init -u https://github.com/MentorEmbedded/ypdd-2014.git
gpg: key 920F5C65: "Repo Maintainer <repo@android.kernel.org>" not changed
gpg: key 692B382C: public key "Conley Owens <cco3@android.com>" imported
gpg: Total number processed: 2
gpg:               imported: 1  (RSA: 1)
gpg:              unchanged: 1

Get https://gerrit.googlesource.com/git-repo
remote: Counting objects: 117, done
remote: Finding sources: 100% (117/117)
remote: Total 2958 (delta 1550), reused 2958 (delta 1550)
Receiving objects: 100% (2958/2958), 2.52 MiB | 331.00 KiB/s, done.
Resolving deltas: 100% (1550/1550), done.
From https://gerrit.googlesource.com/git-repo
 * [new branch]      maint      -> origin/maint
 * [new branch]      master     -> origin/master
...
 * [new tag]         v1.9.5     -> v1.9.5
 * [new tag]         v1.9.6     -> v1.9.6
Get https://github.com/MentorEmbedded/ypdd-2014.git
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0
curl: (22) The requested URL returned error: 404 Not Found
Server does not provide clone.bundle; ignoring.
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://github.com/MentorEmbedded/ypdd-2014
 * [new branch]      master     -> origin/master

Your identity is: Christian Jann <christian.jann@ymail.com>
If you want to change this, please re-run 'repo init' with --config-name

repo has been initialized in /mnt/data/data/Events/ELCE2014/YoctoDevDay/recap/ypdd
[chris@thinkpad sources]$ repo sync
Fetching project meta-fsl-demos
remote: Counting objects: 833, done.
remote: Total 833 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (833/833), 227.47 KiB | 161.00 KiB/s, done.
Resolving deltas: 100% (411/411), done.
From git://github.com/Freescale/meta-fsl-demos
 * [new branch]      daisy      -> Freescale/daisy
 * [new branch]      danny      -> Freescale/danny
...
 * [new tag]         1.6        -> 1.6
 * [new tag]         1.7        -> 1.7
Fetching projects:  14% (1/7)  Fetching project meta-intel
remote: Counting objects: 10442, done.
remote: Compressing objects: 100% (3290/3290), done.
remote: Total 10442 (delta 5989), reused 10303 (delta 5850)
Receiving objects: 100% (10442/10442), 2.68 MiB | 449.00 KiB/s, done.
Resolving deltas: 100% (5989/5989), done.
From git://git.yoctoproject.org/meta-intel
 * [new branch]      1.1_M1     -> yoctoproject/1.1_M1
 * [new branch]      1.1_M2     -> yoctoproject/1.1_M2
...
 * [new tag]         yocto-1.5_M5.rc2 -> yocto-1.5_M5.rc2
 * [new tag]         yocto_1.5_M5.rc8 -> yocto_1.5_M5.rc8
Fetching projects:  28% (2/7)  Fetching project poky
remote: Counting objects: 251913, done.
remote: Compressing objects: 100% (62512/62512), done.
remote: Total 251913 (delta 184482), reused 251580 (delta 184150)
Receiving objects: 100% (251913/251913), 106.71 MiB | 445.00 KiB/s, done.
Resolving deltas: 100% (184482/184482), done.
From git://git.yoctoproject.org/poky
 * [new branch]      1.1_M1     -> yoctoproject/1.1_M1
 * [new branch]      1.1_M2     -> yoctoproject/1.1_M2
...
 * [new tag]         yocto-1.7  -> yocto-1.7
 * [new tag]         yocto_1.5_M5.rc8 -> yocto_1.5_M5.rc8
Fetching projects:  42% (3/7)  Fetching project meta-fsl-arm-extra
remote: Counting objects: 1973, done.
remote: Compressing objects: 100% (44/44), done.
remote: Total 1973 (delta 21), reused 0 (delta 0)
Receiving objects: 100% (1973/1973), 1.70 MiB | 309.00 KiB/s, done.
Resolving deltas: 100% (998/998), done.
From git://github.com/Freescale/meta-fsl-arm-extra
 * [new branch]      daisy      -> Freescale/daisy
 * [new branch]      danny      -> Freescale/danny
...
 * [new tag]         1.6        -> 1.6
 * [new tag]         1.7        -> 1.7
Fetching projects:  57% (4/7)  Fetching project meta-ti
remote: Counting objects: 13894, done.
remote: Compressing objects: 100% (5287/5287), done.
remote: Total 13894 (delta 7996), reused 13842 (delta 7944)
Receiving objects: 100% (13894/13894), 7.07 MiB | 460.00 KiB/s, done.
Resolving deltas: 100% (7996/7996), done.
From git://git.yoctoproject.org/meta-ti
 * [new branch]      daisy      -> yoctoproject/daisy
 * [new branch]      danny      -> yoctoproject/danny
...
 * [new tag]         ti2014.10.00 -> ti2014.10.00
 * [new tag]         v2012.05-yocto1.2 -> v2012.05-yocto1.2
Fetching projects:  71% (5/7)  Fetching project meta-fsl-arm
remote: Counting objects: 8557, done.
remote: Compressing objects: 100% (3139/3139), done.
remote: Total 8557 (delta 5200), reused 8390 (delta 5046)
Receiving objects: 100% (8557/8557), 37.59 MiB | 309.00 KiB/s, done.
Resolving deltas: 100% (5200/5200), done.
From git://git.yoctoproject.org/meta-fsl-arm
 * [new branch]      1.4_M3     -> yoctoproject/1.4_M3
 * [new branch]      1.4_M5     -> yoctoproject/1.4_M5
...
 * [new tag]         1.6        -> 1.6
 * [new tag]         1.7        -> 1.7
Fetching projects:  85% (6/7)  Fetching project meta-openembedded
remote: Counting objects: 43452, done.
remote: Compressing objects: 100% (17277/17277), done.
remote: Total 43452 (delta 25954), reused 40704 (delta 24146)
Receiving objects: 100% (43452/43452), 21.59 MiB | 455.00 KiB/s, done.
Resolving deltas: 100% (25954/25954), done.
From git://git.openembedded.org/meta-openembedded
 * [new branch]      daisy      -> openembedded/daisy
 * [new branch]      danny      -> openembedded/danny
...
 * [new branch]      master     -> openembedded/master
 * [new branch]      master-next -> openembedded/master-next
Fetching projects: 100% (7/7), done.
Syncing work tree: 100% (7/7), done.

[chris@thinkpad sources]$ for i in meta* poky; do cd $i; git checkout -b daisy; cd ..; done
Switched to a new branch 'daisy'
Switched to a new branch 'daisy'
Switched to a new branch 'daisy'
Switched to a new branch 'daisy'
Switched to a new branch 'daisy'
Switched to a new branch 'daisy'
Switched to a new branch 'daisy'
[chris@thinkpad sources]$

Get the Yocto Project Development Day Advanced Layer

Download the zip archive (ypdd-adv-layer.tar.gz) and extract it to the sources folder:

[chris@thinkpad sources]$ wget http://www.jann.cc/_downloads/ypdd-adv-layer.tar.gz
[chris@thinkpad sources]$ tar -zxvf ypdd-adv-layer.tar.gz
ypdd-adv-layer/
ypdd-adv-layer/recipes-ypdd-adv/
ypdd-adv-layer/recipes-ypdd-adv/hello-mod/
ypdd-adv-layer/recipes-ypdd-adv/hello-mod/files/
ypdd-adv-layer/recipes-ypdd-adv/hello-mod/files/hello.c
ypdd-adv-layer/recipes-ypdd-adv/hello-mod/files/COPYING
ypdd-adv-layer/recipes-ypdd-adv/hello-mod/files/Makefile
ypdd-adv-layer/recipes-ypdd-adv/hello-mod/hello-mod_0.1.bb
ypdd-adv-layer/recipes-ypdd-adv/hello-app/
ypdd-adv-layer/recipes-ypdd-adv/hello-app/hello/
ypdd-adv-layer/recipes-ypdd-adv/hello-app/hello/hello.c
ypdd-adv-layer/recipes-ypdd-adv/hello-app/hello_1.0.bb
ypdd-adv-layer/recipes-ypdd-adv/morseapp/
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/morse_client.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/morse_gpio.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/quick_client.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/morse_app.h
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/license.txt
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/morse_client.h
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/morse_gpio.h
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/quick_server.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/morse_app.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/morse_codec.h
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/morse_server.h
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/morse_codec.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.1/morse_server.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp_2014.10.1.bb
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/morse_client.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/morse_gpio.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/quick_client.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/morse_app.h
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/license.txt
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/morse_client.h
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/morse_gpio.h
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/quick_server.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/morse_app.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/morse_codec.h
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/morse_server.h
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/morse_codec.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp-2014.10.0/morse_server.c
ypdd-adv-layer/recipes-ypdd-adv/morseapp/morseapp_2014.10.0.bb
ypdd-adv-layer/recipes-ypdd-adv/morsemod/
ypdd-adv-layer/recipes-ypdd-adv/morsemod/morsemod_2014.10.0.bb
ypdd-adv-layer/recipes-ypdd-adv/morsemod/morsemod_2014.10.1.bb
ypdd-adv-layer/recipes-ypdd-adv/morsemod/morsemod-2014.10.1/
ypdd-adv-layer/recipes-ypdd-adv/morsemod/morsemod-2014.10.1/morsemod.c
ypdd-adv-layer/recipes-ypdd-adv/morsemod/morsemod-2014.10.1/license.txt
ypdd-adv-layer/recipes-ypdd-adv/morsemod/morsemod-2014.10.1/Makefile
ypdd-adv-layer/recipes-ypdd-adv/morsemod/morsemod-2014.10.0/
ypdd-adv-layer/recipes-ypdd-adv/morsemod/morsemod-2014.10.0/morsemod.c
ypdd-adv-layer/recipes-ypdd-adv/morsemod/morsemod-2014.10.0/license.txt
ypdd-adv-layer/recipes-ypdd-adv/morsemod/morsemod-2014.10.0/Makefile
ypdd-adv-layer/conf/
ypdd-adv-layer/conf/layer.conf
ypdd-adv-layer/.git/
ypdd-adv-layer/.git/index
...
ypdd-adv-layer/.git/objects/6e/f8655e370c8c4da234df868803a77c05e67929
ypdd-adv-layer/.git/branches/
ypdd-adv-layer/.git/ORIG_HEAD
[chris@thinkpad sources]$

Build your QEMU project

bitbake core-image-base

bitbake core-image-base

Have a look at the slides from above for more detailed instructions.

Prepare your QEMU project

[chris@thinkpad sources]$ cd /scratch/working
[chris@thinkpad working]$ . /scratch/yocto/sources/poky/oe-init-build-env build-qemux86
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.

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/

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'
[chris@thinkpad build-qemux86]$ vim conf/bblayers.conf
[chris@thinkpad build-qemux86]$ cat conf/bblayers.conf
# LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
LCONF_VERSION = "6"

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

BBLAYERS ?= " \
  /scratch/yocto/sources/poky/meta \
  /scratch/yocto/sources/poky/meta-yocto \
  /scratch/yocto/sources/poky/meta-yocto-bsp \
  /scratch/yocto/sources/ypdd-adv-layer \
  "
BBLAYERS_NON_REMOVABLE ?= " \
  /scratch/yocto/sources/poky/meta \
  /scratch/yocto/sources/poky/meta-yocto \
  "
[chris@thinkpad build-qemux86]$ vim conf/local.conf
[chris@thinkpad build-qemux86]$ tail -n 7 conf/local.conf
SSTATE_DIR = "/scratch/yocto/sstate-cache"
DL_DIR = "/scratch/yocto/downloads"
IMAGE_INSTALL_append = " gdbserver morseapp morsemod"
EXRA_IMAGEDEPENDS_append = " gdb-cross"

PSERV_HOST = "localhost:0"

[chris@thinkpad build-qemux86]$ bitbake core-image-base
ERROR:  OE-core's config sanity checker detected a potential misconfiguration.
    Either fix the cause of this error or at your own risk disable the checker (see sanity.conf).
    Following is the list of potential problems / advisories:

    Please install the following missing utilities: chrpath
libsdl-native is set to be ASSUME_PROVIDED but sdl-config can't be found in PATH. Please either install it, or configure qemu not to require sdl.
ERROR: Execution of event handler 'check_sanity_eventhandler' failed
ERROR: Command execution failed: Exited with 1

Summary: There were 3 ERROR messages shown, returning a non-zero exit code.
[chris@thinkpad build-qemux86]$ sudo yum install chrpath SDL SDL-devel
[chris@thinkpad build-qemux86]$ bitbake core-image-base
Parsing recipes: 100% |##########################################| Time: 00:01:44
Parsing of 868 .bb files complete (0 cached, 868 parsed). 1227 targets, 38 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION        = "1.22.0"
BUILD_SYS         = "x86_64-linux"
NATIVELSBSTRING   = "Fedora-20"
TARGET_SYS        = "i586-poky-linux"
MACHINE           = "qemux86"
DISTRO            = "poky"
DISTRO_VERSION    = "1.6.2"
TUNE_FEATURES     = "m32 i586"
TARGET_FPU        = ""
meta
meta-yocto
meta-yocto-bsp    = "daisy:1e668ccf1a05c5d730de9747bc1c2b0446bda556"
ypdd-adv-layer    = "master:8dce36bd937a147f33c8e84430b3763ad87fac1e"

NOTE: Preparing runqueue
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
Currently 4 running tasks (43 of 2840):
0: m4-native-1.4.17-r0 do_configure (pid 13676)
1: pkgconfig-native-0.28-r0 do_fetch (pid 18679)
2: ncurses-native-5.9-r15.1 do_fetch (pid 19234)
WARNING: Failed to fetch URL ftp://ftp.debian.org/debian/pool/main/b/base-passwd/base-passwd_3.5.29.tar.gz, attempting MIRRORS if available
WARNING: Failed to fetch URL http://downloads.sourceforge.net/project/libpng/libpng16/1.6.8/libpng-1.6.8.tar.xz, attempting MIRRORS if available
NOTE: validating kernel config, see log.do_kernel_configcheck for details
WARNING: Failed to fetch URL http://0pointer.de/lennart/projects/libdaemon/libdaemon-0.14.tar.gz, attempting MIRRORS if available
WARNING: Failed to fetch URL http://0pointer.de/lennart/projects/nss-mdns/nss-mdns-0.10.tar.gz, attempting MIRRORS if available
WARNING: Failed to fetch URL ftp://ftp.debian.org/debian/pool/main/n/netbase/netbase_5.2.tar.gz, attempting MIRRORS if available
WARNING: Failed to fetch URL ftp://ftp.debian.org/debian/pool/main/d/dpkg/dpkg_1.17.4.tar.xz, attempting MIRRORS if available
WARNING: Failed to fetch URL http://ftp.de.debian.org/debian/pool/main/m/mklibs/mklibs_0.1.38.tar.gz, attempting MIRRORS if available
NOTE: Tasks Summary: Attempted 2840 tasks of which 283 didn't need to be rerun and all succeeded.

Summary: There were 7 WARNING messages shown.
[chris@thinkpad build-qemux86]$

Debugging the Kernel Module

Like already said, have a look at the slides from the lab for more detailed instructions.

You should have 4 windows open now: build (bitbake, runqemu), target console (telnet), remote GDB (i586-poky-linux-gdb) and another one to edit the source code.

Morsemod features

Morsemod features

Morsemod features (Picture taken from the slides).

Debugging with KGDB – Error inserting module

Build Window: Start the QEMU session with two serial ports

[chris@thinkpad build-qemux86]$ runqemu qemux86 nographic qemuparams="-serial telnet:localhost:2345,server -serial tcp:localhost:2346,server,nowait"
Please use simplified serial or kvm options instead

Continuing with the following parameters:
KERNEL: [/scratch/working/build-qemux86/tmp/deploy/images/qemux86/bzImage-qemux86.bin]
ROOTFS: [/scratch/working/build-qemux86/tmp/deploy/images/qemux86/core-image-base-qemux86-20141129121818.rootfs.ext3]
FSTYPE: [ext3]
Acquiring lockfile for tap0...
Using preconfigured tap device 'tap0'
If this is not intended, touch /tmp/qemu-tap-locks/tap0.skip to make runqemu skip tap0.
Running qemu-system-i386...
/scratch/working/build-qemux86/tmp/sysroots/x86_64-linux/usr/bin/qemu-system-i386 -kernel /scratch/working/build-qemux86/tmp/deploy/images/qemux86/bzImage-qemux86.bin -net nic,vlan=0 -net tap,vlan=0,ifname=tap0,script=no,downscript=no -cpu qemu32 -hda /scratch/working/build-qemux86/tmp/deploy/images/qemux86/core-image-base-qemux86-20141129121818.rootfs.ext3 -show-cursor -usb -usbdevice wacom-tablet -vga vmware -no-reboot -nographic -serial telnet:localhost:2345,server -serial tcp:localhost:2346,server,nowait -m 256 --append "vga=0 uvesafb.mode_option=640x480-32 root=/dev/hda rw mem=256M ip=192.168.7.2::192.168.7.1:255.255.255.0 oprofile.timer=1 console=ttyS0"
QEMU 1.7.0 monitor - type 'help' for more information
(qemu) QEMU waiting for connection on: telnet:127.0.0.1:2345,server

Console Window: Start a user console, insert the module, and it fails!

[chris@thinkpad build-qemux86]$ telnet localhost 2345
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Initializing cgroup subsys cpuset
Initializing cgroup subsys cpu
Initializing cgroup subsys cpuacct
Linux version 3.14.0-yocto-standard (chris@thinkpad) (gcc version 4.8.2 (GCC) ) #1 SMP PREEMPT Sat Nov 29 14:41:32 CET 2014
e820: BIOS-provided physical RAM map:
BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
...
INIT: Entering runlevel: 5
Configuring network interfaces... done.
Starting system message bus: dbus.
Starting rpcbind daemon...done.
creating NFS state directory: done
starting statd: done
Starting Distributed Compiler Daemon: distcc.
Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
starting 8 nfsd kernel threads: NFSD: Using /var/lib/nfs/v4recovery as the NFSv4 state recovery directory
NFSD: starting 90-second grace period (net c1aee080)
done
starting mountd: done
Starting syslogd/klogd: done
 * Starting Avahi mDNS/DNS-SD Daemon: avahi-daemon
   ...done.
Starting OProfileUI server
Stopping Bootlog daemon: bootlogd.

Poky (Yocto Project Reference Distro) 1.6.2 qemux86 /dev/ttyS0

qemux86 login: root
root@qemux86:~# modprobe morsemod
------------[ cut here ]------------
WARNING: CPU: 0 PID: 448 at /scratch/working/build-qemux86/tmp/work/qemux86-poky-linux/linux-yocto/3.14+gitAUTOINC+09424cee64_f9048769cc-r0/linux/fs/sysfs/dir.c:52 sysfs_warn_dup+0x7a/0x90()
sysfs: cannot create duplicate filename '/kernel/morsemod/key'
Modules linked in: morsemod(O+) nfsd uvesafb
CPU: 0 PID: 448 Comm: modprobe Tainted: G           O 3.14.0-yocto-standard #1
Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
 00000000 00000000 cf397d10 c179a677 cf397d50 cf397d40 c1043ffe c19be6e0
 cf397d6c 000001c0 c19be710 00000034 c118fbda c118fbda cf074000 cf074000
 cf082f78 cf397d58 c1044053 00000009 cf397d50 c19be6e0 cf397d6c cf397d7c
Call Trace:
 [<c179a677>] dump_stack+0x4b/0x75
 [<c1043ffe>] warn_slowpath_common+0x7e/0xa0
 [<c118fbda>] ? sysfs_warn_dup+0x7a/0x90
 [<c118fbda>] ? sysfs_warn_dup+0x7a/0x90
 [<c1044053>] warn_slowpath_fmt+0x33/0x40
 [<c118fbda>] sysfs_warn_dup+0x7a/0x90
 [<c118f964>] sysfs_add_file_mode_ns+0x164/0x170
 [<c1190340>] internal_create_group+0xd0/0x220
 [<d083e000>] ? 0xd083dfff
 [<c11904a1>] sysfs_create_group+0x11/0x20
 [<d083e057>] morsemod_init+0x57/0x80 [morsemod]
 [<c10cc38b>] ? buffer_ftrace_now+0x2b/0x50
 [<c10cc3bf>] ? ftrace_now+0xf/0x20
 [<c112b238>] ? kmem_cache_alloc_trace+0x98/0x1f0
 [<c10c2480>] ? g_next+0x50/0x50
 [<c10c24a0>] ? ftrace_cmp_ips+0x20/0x20
 [<c10c19ec>] ? tracepoint_module_notify+0xac/0x180
 [<c10004a2>] do_one_initcall+0xd2/0x120
 [<c10c1a59>] ? tracepoint_module_notify+0x119/0x180
 [<c17a3651>] ? notifier_call_chain+0x41/0x60
 [<c1065314>] ? __blocking_notifier_call_chain+0x44/0x60
 [<c10a851a>] load_module+0x166a/0x1db0
 [<c10a8d7d>] SyS_finit_module+0x6d/0x70
 [<c17a04dc>] syscall_call+0x7/0xb
---[ end trace 1124e606eada5bd7 ]---
root@qemux86:~#
BUG: unable to handle kernel paging request at d081abe0
IP: [<c104d398>] __internal_add_timer+0x68/0xa0
*pde = 0f81b067 *pte = 00000000
Oops: 0002 [#1] PREEMPT SMP
Modules linked in: nfsd uvesafb
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        W  O 3.14.0-yocto-standard #1
Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
task: c1a94900 ti: cf808000 task.ti: c1a8a000
EIP: 0060:[<c104d398>] EFLAGS: 00200002 CPU: 0
EIP is at __internal_add_timer+0x68/0xa0
EAX: d081abe0 EBX: 000001f3 ECX: c1bd314c EDX: c1bf72a0
ESI: fffcada8 EDI: c1bd27c0 EBP: cf809ea0 ESP: cf809e98
 DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
CR0: 8005003b CR2: d081abe0 CR3: 0f200000 CR4: 00000690
DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
DR6: 00000000 DR7: 00000000
Stack:
 c1bd27c0 c1bf72a0 cf809eb0 c104ee53 00000033 c1bd27c0 cf809ed4 c104fbe6
 00000000 00200282 c1bd27c0 fffcaf9b 00000033 c1a9f300 c1aab6c0 cf809f3c
 c109962d c179fd5d cf809f00 c107f14f 00000000 ffffffff ffffffff 00000000
Call Trace:
 [<c104ee53>] internal_add_timer+0x13/0x40
 [<c104fbe6>] add_timer_on+0x76/0xf0
 [<c109962d>] clocksource_watchdog+0x24d/0x2f0
 [<c179fd5d>] ? _raw_spin_unlock_irqrestore+0x1d/0x40
 [<c107f14f>] ? __wake_up+0x3f/0x50
 [<c104ed04>] call_timer_fn+0x34/0x130
 [<c10993e0>] ? sysfs_show_current_clocksources+0x50/0x50
 [<c104f42a>] run_timer_softirq+0x14a/0x230
 [<c10993e0>] ? sysfs_show_current_clocksources+0x50/0x50
 [<c10483c3>] __do_softirq+0xd3/0x280
 [<c10482f0>] ? __tasklet_hrtimer_trampoline+0x40/0x40
 <IRQ>
 [<c1048776>] ? irq_exit+0x76/0xa0
 [<c17a7818>] ? smp_apic_timer_interrupt+0x38/0x50
 [<c17a08a1>] ? apic_timer_interrupt+0x2d/0x34
 [<c10395a5>] ? native_safe_halt+0x5/0x10
 [<c10099a0>] ? default_idle+0x20/0xe0
 [<c100a1d6>] ? arch_cpu_idle+0x26/0x30
 [<c108bdba>] ? cpu_startup_entry+0x13a/0x250
 [<c17938d1>] ? rest_init+0x71/0x80
 [<c1b07a89>] ? start_kernel+0x39d/0x3a3
 [<c1b07523>] ? repair_env_string+0x51/0x51
 [<c1b07360>] ? i386_start_kernel+0x12e/0x131
Code: 0e 00 00 79 1b 89 f3 0f b6 f3 8d 4c f0 14 eb 10 8d 76 00 c1 e9 08 83 e1 3f 8d 8c c8 14 08 00 00 8b 41 04 89 51 04 89 0a 89 42 04 <89> 10 5b 5e 5d c3 66 90 0f b6 c9 8d 4c c8 14 eb e4 8d b4 26 00
EIP: [<c104d398>] __internal_add_timer+0x68/0xa0 SS:ESP 0068:cf809e98
CR2: 00000000d081abe0
---[ end trace 1124e606eada5bd8 ]---
Kernel panic - not syncing: Fatal exception in interrupt
Kernel Offset: 0x0 from 0xc1000000 (relocation range: 0xc0000000-0xd07fdfff)
general protection fault: fffa [#2] PREEMPT SMP
Modules linked in: nfsd uvesafb
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G      D W  O 3.14.0-yocto-standard #1
Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
task: c1a94900 ti: cf808000 task.ti: c1a8a000
EIP: 0060:[<c1796dd7>] EFLAGS: 00200246 CPU: 0
EIP is at panic+0x138/0x170
EAX: 00000000 EBX: 00200046 ECX: 00000006 EDX: 00000105
ESI: 00000009 EDI: 00000000 EBP: cf809d30 ESP: cf809d18
 DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
CR0: 8005003b CR2: d081abe0 CR3: 0f200000 CR4: 00000690
DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
DR6: 00000000 DR7: 00000000
Stack:
 c19a4510 c1bd2200 00000000 00200046 00000009 c1a94900 cf809d44 c17a13c7
 c1995d51 cf809e5c 00000009 cf809d70 c17968c2 c199974c d081abe0 00200046
 00000000 d081abe0 cf833ae0 00000002 c1a94900 cf809e5c cf809db0 c1796a11
Call Trace:
 [<c17a13c7>] oops_end+0x97/0xa0
 [<c17968c2>] no_context+0x199/0x1a1
 [<c1796a11>] __bad_area_nosemaphore+0x147/0x14f
 [<c10852ab>] ? cpuacct_charge+0x4b/0x60
 [<c107392d>] ? update_curr+0xfd/0x1e0
 [<c17a3520>] ? __do_page_fault+0x550/0x550
 [<c1796a30>] bad_area_nosemaphore+0x17/0x19
 [<c17a32cd>] __do_page_fault+0x2fd/0x550
 [<c106d066>] ? resched_task+0x26/0x60
 [<c1074793>] ? check_preempt_wakeup+0x173/0x220
 [<c106d852>] ? check_preempt_curr+0x72/0x90
 [<c17a3520>] ? __do_page_fault+0x550/0x550
 [<c17a353a>] do_page_fault+0x1a/0x20
 [<c17a0c1a>] error_code+0x5a/0x60
 [<c17a3520>] ? __do_page_fault+0x550/0x550
 [<c104d398>] ? __internal_add_timer+0x68/0xa0
 [<c104ee53>] internal_add_timer+0x13/0x40
 [<c104fbe6>] add_timer_on+0x76/0xf0
 [<c109962d>] clocksource_watchdog+0x24d/0x2f0
 [<c179fd5d>] ? _raw_spin_unlock_irqrestore+0x1d/0x40
 [<c107f14f>] ? __wake_up+0x3f/0x50
 [<c104ed04>] call_timer_fn+0x34/0x130
 [<c10993e0>] ? sysfs_show_current_clocksources+0x50/0x50
 [<c104f42a>] run_timer_softirq+0x14a/0x230
 [<c10993e0>] ? sysfs_show_current_clocksources+0x50/0x50
 [<c10483c3>] __do_softirq+0xd3/0x280
 [<c10482f0>] ? __tasklet_hrtimer_trampoline+0x40/0x40
 <IRQ>
 [<c1048776>] ? irq_exit+0x76/0xa0
 [<c17a7818>] ? smp_apic_timer_interrupt+0x38/0x50
 [<c17a08a1>] ? apic_timer_interrupt+0x2d/0x34
 [<c10395a5>] ? native_safe_halt+0x5/0x10
 [<c10099a0>] ? default_idle+0x20/0xe0
 [<c100a1d6>] ? arch_cpu_idle+0x26/0x30
 [<c108bdba>] ? cpu_startup_entry+0x13a/0x250
 [<c17938d1>] ? rest_init+0x71/0x80
 [<c1b07a89>] ? start_kernel+0x39d/0x3a3
 [<c1b07523>] ? repair_env_string+0x51/0x51
 [<c1b07360>] ? i386_start_kernel+0x12e/0x131
Code: 00 00 be 65 00 00 00 4e 74 0c b8 58 89 41 00 e8 70 fd bd ff eb f1 83 c3 64 eb c0 83 3d cc 21 bd c1 00 74 05 e8 0b f4 8c ff fb 90 <8d> 74 26 00 31 f6 39 fe 7c 15 83 75 f0 01 8b 45 f0 ff 15 c0 21
EIP: [<c1796dd7>] panic+0x138/0x170 SS:ESP 0068:cf809d18
---[ end trace 1124e606eada5bd9 ]---
Connection closed by foreign host.
[chris@thinkpad build-qemux86]$

What happened? First look at dmesg or scrollback!

WARNING: CPU: 0 PID: 448 at /scratch/working/build-qemux86/tmp/work/qemux86-poky-linux/linux-yocto/3.14+gitAUTOINC+09424cee64_f9048769cc-r0/linux/fs/sysfs/dir.c:52 sysfs_warn_dup+0x7a/0x90()
  sysfs: cannot create duplicate filename '/kernel/morsemod/key'
  Modules linked in: morsemod(O+) nfsd uvesafb

Note: To stop QEMU, Crtl-C in the Build Window.

Debugging the kernel module - Fix #1

Bug: We tried to create the key file twice... whoops! (trying to use the debugger on this will end up taking twice as long or worse...)

Let’s debug this!

Source Window:

[chris@thinkpad build-qemux86]$ cd ../../yocto/sources/ypdd-adv-layer/recipes-ypdd-adv/morsemod/morsemod-2014.10.0/
[chris@thinkpad morsemod-2014.10.0]$ vim morsemod.c

Look for __ATTR (the structure that holds the sysfs file info)

static struct kobj_attribute simkey_attribute =
    __ATTR(key, 0666, simkey_show, simkey_store);

...

static struct kobj_attribute led_attribute =
  __ATTR(led, 0666, b_show, b_store);
static struct kobj_attribute key_attribute =
    __ATTR(key, 0666, b_show, b_store);

Whoops, we defined key twice, top one should be simkey!

-  __ATTR(key, 0666, simkey_show, simkey_store);
+  __ATTR(simkey, 0666, simkey_show, simkey_store);

Debug the kernel module - Try again

Build Window: Boot, try it again (see above)

[chris@thinkpad build-qemux86]$ bitbake core-image-base
Loading cache: 100% |########################################| ETA:  00:00:00
Loaded 1228 entries from dependency cache.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION        = "1.22.0"
BUILD_SYS         = "x86_64-linux"
NATIVELSBSTRING   = "Fedora-20"
TARGET_SYS        = "i586-poky-linux"
MACHINE           = "qemux86"
DISTRO            = "poky"
DISTRO_VERSION    = "1.6.2"
TUNE_FEATURES     = "m32 i586"
TARGET_FPU        = ""
meta
meta-yocto
meta-yocto-bsp    = "daisy:1e668ccf1a05c5d730de9747bc1c2b0446bda556"
ypdd-adv-layer    = "master:8dce36bd937a147f33c8e84430b3763ad87fac1e"

NOTE: Preparing runqueue
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
Currently 1 running tasks (2839 of 2840):
0: core-image-base-1.0-r0 do_rootfs (pid 4111)
NOTE: Tasks Summary: Attempted 2840 tasks of which 2825 didn't need to be rerun and all succeeded.
[chris@thinkpad build-qemux86]$ runqemu qemux86 nographic qemuparams="-serial telnet:localhost:2345,server -serial tcp:localhost:2346,server,nowait"
Please use simplified serial or kvm options instead

Continuing with the following parameters:
KERNEL: [/scratch/working/build-qemux86/tmp/deploy/images/qemux86/bzImage-qemux86.bin]
ROOTFS: [/scratch/working/build-qemux86/tmp/deploy/images/qemux86/core-image-base-qemux86-20141130142621.rootfs.ext3]
FSTYPE: [ext3]
Setting up tap interface under sudo
Acquiring lockfile for tap0...
Running qemu-system-i386...
/scratch/working/build-qemux86/tmp/sysroots/x86_64-linux/usr/bin/qemu-system-i386 -kernel /scratch/working/build-qemux86/tmp/deploy/images/qemux86/bzImage-qemux86.bin -net nic,vlan=0 -net tap,vlan=0,ifname=tap0,script=no,downscript=no -cpu qemu32 -hda /scratch/working/build-qemux86/tmp/deploy/images/qemux86/core-image-base-qemux86-20141130142621.rootfs.ext3 -show-cursor -usb -usbdevice wacom-tablet -vga vmware -no-reboot -nographic -serial telnet:localhost:2345,server -serial tcp:localhost:2346,server,nowait -m 256 --append "vga=0 uvesafb.mode_option=640x480-32 root=/dev/hda rw mem=256M ip=192.168.7.2::192.168.7.1:255.255.255.0 oprofile.timer=1 console=ttyS0"
QEMU 1.7.0 monitor - type 'help' for more information
(qemu) QEMU waiting for connection on: telnet:127.0.0.1:2345,server

Console Window: load module and see if it works

[chris@thinkpad build-qemux86]$ telnet localhost 2345
...

Poky (Yocto Project Reference Distro) 1.6.2 qemux86 /dev/ttyS0

qemux86 login: root
root@qemux86:~# modprobe morsemod
root@qemux86:~# cd /sys/kernel/morsemod/
root@qemux86:/sys/kernel/morsemod# cat simkey
K=0 L=0 B=0 LP=0
root@qemux86:/sys/kernel/morsemod#

Debug the kernel module - Test loopback

Let’s see if it can remember the key and led values:

root@qemux86:/sys/kernel/morsemod# echo '1' > key
root@qemux86:/sys/kernel/morsemod# cat simkey
K=1 L=0 B=0 LP=0
root@qemux86:/sys/kernel/morsemod# echo '0' > key
root@qemux86:/sys/kernel/morsemod# cat simkey
K=0 L=0 B=0 LP=0
root@qemux86:/sys/kernel/morsemod# echo '1' > led
root@qemux86:/sys/kernel/morsemod# cat simkey
K=0 L=1 B=0 LP=0
root@qemux86:/sys/kernel/morsemod# echo '0' > led
root@qemux86:/sys/kernel/morsemod# cat simkey
K=0 L=0 B=0 LP=0
root@qemux86:/sys/kernel/morsemod#

Let’s see if we can enable loopback:

root@qemux86:/sys/kernel/morsemod# echo '[' > simkey
root@qemux86:/sys/kernel/morsemod# cat simkey
K=0 L=0 B=0 LP=1
root@qemux86:/sys/kernel/morsemod# echo '1' > key
root@qemux86:/sys/kernel/morsemod# cat simkey
K=1 L=1 B=0 LP=1
root@qemux86:/sys/kernel/morsemod# echo '0' > key
root@qemux86:/sys/kernel/morsemod# cat simkey
K=0 L=0 B=0 LP=1
root@qemux86:/sys/kernel/morsemod# echo ']' > simkey
root@qemux86:/sys/kernel/morsemod# cat simkey
K=0 L=0 B=0 LP=0
root@qemux86:/sys/kernel/morsemod#

Debug the kernel module - Bug #2 : broadcast

Let’s try enabling the demo broadcast message:

root@qemux86:/sys/kernel/morsemod# echo '<' > simkey
root@qemux86:/sys/kernel/morsemod# cat simkey
K=0 L=0 B=1 LP=0
root@qemux86:/sys/kernel/morsemod# while true ; do cat key ; sleep 1 ; done
0
0
0
0
0
0
0
^C
root@qemux86:/sys/kernel/morsemod#

It doesn’t seem to be working. Time to try to debug the module!

Production image usually lack debug capabilities (stripped symbols, no included debug sources, etc.)

In the Yocto Project, debug information is separate from the runtime in most cases. It is packaged into -dbg labeled packages.

By creating a companion debug capable filesystem, you can use remote (cross) debugging to debug a production filesystem.

Debug Window: Construct a debug-fs

  • Extract dbg packages (rpm in this example)
  • Add the production filesystem components
[chris@thinkpad build-qemux86]$ rm -rf debugfs ; mkdir debugfs ; cd debugfs
[chris@thinkpad debugfs]$ for pkg in ../tmp/deploy/rpm/*/*-dbg* ; do ../tmp/sysroots/x86_64-linux/usr/lib/rpm/rpm2cpio $pkg | cpio -i ; done
1 block
1 block
1 block
948 blocks
10689 blocks
1 block
3049 blocks
...
1 block
1753 blocks
[chris@thinkpad debugfs]$ tar xvfj ../tmp/deploy/images/qemux86/core-image-base-qemux86.tar.bz2
./
./dev/
./var/
./var/local/
./var/log
./var/volatile/
...
./opt/
./opt/broadcast_morsemod.sh
./opt/upload_morseapp.sh
./opt/upload_morsemod.sh
[chris@thinkpad debugfs]$ cd ..
[chris@thinkpad build-qemux86]$

KGDBoC - Start

Console Window: enable KGDBoC

Note

If you start QEMU again you need to load the morsemod module again and enable the demo broadcast message:

root@qemux86:~# modprobe morsemod
root@qemux86:~# cd /sys/kernel/morsemod/
root@qemux86:/sys/kernel/morsemod# echo '>' > simkey
root@qemux86:/sys/kernel/morsemod# cat simkey
K=0 L=0 B=1 LP=0
root@qemux86:/sys/kernel/morsemod#
root@qemux86:/sys/kernel/morsemod# echo ttyS1 > /sys/module/kgdboc/parameters/kgdboc
kgdb: Registered I/O driver kgdboc.
root@qemux86:/sys/kernel/morsemod# echo g > /proc/sysrq-trigger
SysRq : DEBUG

Entering kdb (current=0xcf0ecfe0, pid 447) on processor 0 due to Keyboard Entry
[0]kdb>

System stalls and drops into KDB on the ttyS1 serial port.

Debug Window: Conntct to the remote kernel (KGDBoS)

[chris@thinkpad build-qemux86]$ ./tmp/sysroots/x86_64-linux/usr/bin/i586-poky-linux/i586-poky-linux-gdb
bash: ./tmp/sysroots/x86_64-linux/usr/bin/i586-poky-linux/i586-poky-linux-gdb: No such file or directory
[chris@thinkpad build-qemux86]$ bitbake gdb-cross
Loading cache: 100% |#########################################| ETA:  00:00:00
Loaded 1228 entries from dependency cache.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION        = "1.22.0"
BUILD_SYS         = "x86_64-linux"
NATIVELSBSTRING   = "Fedora-20"
TARGET_SYS        = "i586-poky-linux"
MACHINE           = "qemux86"
DISTRO            = "poky"
DISTRO_VERSION    = "1.6.2"
TUNE_FEATURES     = "m32 i586"
TARGET_FPU        = ""
meta
meta-yocto
meta-yocto-bsp    = "daisy:1e668ccf1a05c5d730de9747bc1c2b0446bda556"
ypdd-adv-layer    = "master:8dce36bd937a147f33c8e84430b3763ad87fac1e"

NOTE: Preparing runqueue
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
Currently 1 running tasks (97 of 103):
0: gdb-cross-7.6.2-r0 do_compile (pid 25384)
NOTE: Tasks Summary: Attempted 103 tasks of which 91 didn't need to be rerun and all succeeded.
[chris@thinkpad build-qemux86]$ ./tmp/sysroots/x86_64-linux/usr/bin/i586-poky-linux/i586-poky-linux-gdb
GNU gdb (GDB) 7.6.2
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux --target=i586-poky-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) set sysroot debugfs
(gdb) set substitute-path /usr/src/debug debugfs/usr/src/debug
(gdb) file debugfs/boot/vmlinux-3.14.0-yocto-standard
Reading symbols from /scratch/working/build-qemux86/debugfs/boot/vmlinux-3.14.0-yocto-standard...done.
(gdb) target remote localhost:2346
Remote debugging using localhost:2346
kgdb_breakpoint () at /scratch/working/build-qemux86/tmp/work/qemux86-poky-linux/linux-yocto/3.14+gitAUTOINC+09424cee64_f9048769cc-r0/linux/kernel/debug/debug_core.c:1043
1043            wmb(); /* Sync point after breakpoint */
(gdb)

KGDBoC - Connect

Debug Window: Load into GDB the kernel module

(gdb) monitor lsmod
Module                  Size  modstruct     Used by
morsemod                3973  0xd081a640    0  (Live) 0xd081a000 [ ]
nfsd                  206468  0xd18f10a0   11  (Live) 0xd18c6000 [ ]
uvesafb                22894  0xd083baa0    1  (Live) 0xd0837000 [ ]
(gdb) add-symbol-file debugfs/lib/modules/3.14.0-yocto-standard/extra/morsemod.ko 0xd081a000
add symbol table from file "debugfs/lib/modules/3.14.0-yocto-standard/extra/morsemod.ko" at
        .text_addr = 0xd081a000
(y or n) y
Reading symbols from /scratch/working/build-qemux86/debugfs/lib/modules/3.14.0-yocto-standard/extra/morsemod.ko...done.
(gdb)

When broadcast mode is enabled what we’re trying to do is iterate over the message_str value using the message_index, so set the break point at the top of the: if (1 == broadcast).

Source Window:

[chris@thinkpad morsemod-2014.10.0]$ vim morsemod.c
[chris@thinkpad morsemod-2014.10.0]$ grep -n "1 == broadcast" morsemod.c
64:     if (1 == broadcast) {
[chris@thinkpad morsemod-2014.10.0]$ sed -n 64,78p morsemod.c
        if (1 == broadcast) {

                /* printk(KERN_INFO "  TOCK: B=%d, I=%d, Key=%c\n",broadcast,message_index,message_str[message_index]); */

                if ('1' == message_str[message_index])
                        key = 1;
                else
                        key = 0;

                message_index++;
                if (message_index <= strlen(message_str)) {
                        message_index=0;
                }
        }

[chris@thinkpad morsemod-2014.10.0]$

Debug Window:

(gdb) break morsemod.c:68
Breakpoint 1 at 0xd081a0d8: file /scratch/working/build-qemux86/tmp/work/qemux86-poky-linux/morsemod/2014.10.0-r0/morsemod.c, line 68.
(gdb) c
Continuing.

Breakpoint 1, morsemod_timer (dev_addr=dev_addr@entry=0) at /scratch/working/build-qemux86/tmp/work/qemux86-poky-linux/morsemod/2014.10.0-r0/morsemod.c:68
68                      if ('1' == message_str[message_index])
(gdb)

Shortly after pressing c we should hit a breakpoint because the morsemod_timer is enabled.

Now use n to walk through the code flow.

(gdb) n
73                      message_index++;
(gdb) print message_index
Cannot access memory at address 0x49c
(gdb) p &message_index
$1 = (int *) 0x49c <message_index>
(gdb) p (int *) 0x49c
$2 = (int *) 0x49c <message_index>
(gdb) p * (int *) 0x49c
Cannot access memory at address 0x49c
(gdb)

You likely can’t inspect variables (might be a bug in gdb?). But if you disassemble you’ll see something like:

(gdb) disassemble /m
Dump of assembler code for function morsemod_timer:
61      {
   0xd081a090 <+0>:     push   %ebp
   0xd081a091 <+1>:     mov    %esp,%ebp
   0xd081a093 <+3>:     push   %ebx
   0xd081a094 <+4>:     lea    %ds:0x0(%esi,%eiz,1),%esi

62              /* printk(KERN_INFO "TICK: B=%d, I=%d\n",broadcast,message_index); */
63
64              if (1 == broadcast) {
   0xd081a099 <+9>:     cmpl   $0x1,0xd081a7c4
   0xd081a0a0 <+16>:    je     0xd081a0d8 <morsemod_timer+72>

65
66                      /* printk(KERN_INFO "  TOCK: B=%d, I=%d, Key=%c\n",broadcast,message_index,message_str[message_index]); */
67
68                      if ('1' == message_str[message_index])
   0xd081a0d8 <+72>:    mov    0xd081a7dc,%ebx

69                              key = 1;
   0xd081a0de <+78>:    xor    %eax,%eax
   0xd081a0e0 <+80>:    cmpb   $0x31,-0x2f7e5820(%ebx)
   0xd081a0e7 <+87>:    sete   %al
   0xd081a0ed <+93>:    mov    %eax,0xd081a7d4

70                      else
---Type <return> to continue, or q <return> to quit---
71                              key = 0;
72
73                      message_index++;
=> 0xd081a0ea <+90>:    add    $0x1,%ebx
   0xd081a0f7 <+103>:   mov    %ebx,0xd081a7dc

74                      if (message_index <= strlen(message_str)) {
   0xd081a0f2 <+98>:    mov    $0xd081a7e0,%eax
   0xd081a0fd <+109>:   call   0xc1377de0 <strlen>
   0xd081a102 <+114>:   cmp    %eax,%ebx
   0xd081a104 <+116>:   ja     0xd081a0a2 <morsemod_timer+18>

75                              message_index=0;
   0xd081a106 <+118>:   movl   $0x0,0xd081a7dc
   0xd081a110 <+128>:   jmp    0xd081a0a2 <morsemod_timer+18>
   0xd081a112:  lea    0x0(%esi,%eiz,1),%esi
   0xd081a119:  lea    0x0(%edi,%eiz,1),%edi

76                      }
77              }
78
79
80              /* let's do this again */
81              morsemod_timer_struct.expires = future_in_ms(morsemod_timeout);
   0xd081a0a2 <+18>:    imul   $0x3e8,0xd081a638,%eax
   0xd081a0ac <+28>:    mov    $0x10624dd3,%edx
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb)

Have a look at:

73                      message_index++;
  => 0xd081a0ea <+90>:    add    $0x1,%ebx
     0xd081a0f7 <+103>:   mov    %ebx,0xd081a7dc

The new value of message_index gets moved to 0xd081a7dc. Maybe we can print the value at that address directly:

(gdb) p *(int*) 0xd081a7dc
$3 = 0
(gdb)

OK, it looks like message_index is 0.

(gdb) c
Continuing.
[New Thread 4294967294]
[Switching to Thread 4294967294]

Breakpoint 1, morsemod_timer (dev_addr=0) at /scratch/working/build-qemux86/tmp/work/qemux86-poky-linux/morsemod/2014.10.0-r0/morsemod.c:68
68                      if ('1' == message_str[message_index])
(gdb) p *(int*) 0xd081a7dc
$4 = 0
(gdb)

OK, message_index is still 0.

Have a look at the code:

static void morsemod_timer(unsigned long dev_addr)
{
    /* printk(KERN_INFO "TICK: B=%d, I=%d\n",broadcast,message_index); */

    if (1 == broadcast) {

        /* printk(KERN_INFO "  TOCK: B=%d, I=%d, Key=%c\n",broadcast,message_index,message_str[message_index]); */

        if ('1' == message_str[message_index])
            key = 1;
        else
            key = 0;

        message_index++;
        if (message_index <= strlen(message_str)) {
            message_index=0;
        }
    }

OK, message_index gets increased (message_index++;) but after that it gets set to 0 if message_index <= strlen(message_str) which makes no sense. We should be checking if it overflows, not underflows!

KGDBoC - Fix bug #2

Change the code to be:

if (message_index >= strlen(message_str)) {

Rebuild and restart (and do not forget to regenerate the debugfs).

Build Window:

[chris@thinkpad build-qemux86]$ bitbake core-image-base
[chris@thinkpad build-qemux86]$ runqemu qemux86 nographic qemuparams="-serial telnet:localhost:2345,server -serial tcp:localhost:2346,server,nowait"

Debug Window:

[chris@thinkpad build-qemux86]$ rm -rf debugfs ; mkdir debugfs ; cd debugfs
[chris@thinkpad debugfs]$ for pkg in ../tmp/deploy/rpm/*/*-dbg* ; do ../tmp/sysroots/x86_64-linux/usr/lib/rpm/rpm2cpio $pkg | cpio -i ; done
[chris@thinkpad debugfs]$ tar xvfj ../tmp/deploy/images/qemux86/core-image-base-qemux86.tar.bz2
[chris@thinkpad debugfs]$ cd ..
[chris@thinkpad build-qemux86]$

Console Window: Does it work?

[chris@thinkpad build-qemux86]$ telnet localhost 2345
...
qemux86 login: root
root@qemux86:~# modprobe morsemod
root@qemux86:~# cd /sys/kernel/morsemod/
root@qemux86:/sys/kernel/morsemod# cat simkey
K=0 L=0 B=0 LP=0
root@qemux86:/sys/kernel/morsemod# echo '<' > simkey
root@qemux86:/sys/kernel/morsemod# cat simkey
K=1 L=0 B=1 LP=0
root@qemux86:/sys/kernel/morsemod# while true ; do cat key ; sleep 1; done
0
1
0
0
1
0
0
0
0
0
1
0
^C
root@qemux86:/sys/kernel/morsemod#

Great, it works! Now turn it off...

root@qemux86:/sys/kernel/morsemod# echo '>' > simkey
root@qemux86:/sys/kernel/morsemod# cat simkey
K=1 L=0 B=1 LP=0
root@qemux86:/sys/kernel/morsemod# echo '>' > simkey
root@qemux86:/sys/kernel/morsemod# cat simkey
K=1 L=0 B=1 LP=0
root@qemux86:/sys/kernel/morsemod#

Cannot turn it off, new bug...

KGDBoC - Reconnect

OK, this bug is easy to spot, just have a look at the code...

static ssize_t simkey_store(struct kobject *kobj, struct kobj_attribute *attr,
                         const char *buf, size_t count)
{
    int var;

    if        ('<' == buf[0]) broadcast=1;
      else if ('>' == buf[0]) broadcast=1;

But let’s see how to debug this if the bug is not that easy to spot.

Console Window: Setup kgdb/gdb again...

root@qemux86:/sys/kernel/morsemod# cd
root@qemux86:~# echo ttyS1 > /sys/module/kgdboc/parameters/kgdboc
kgdb: Registered I/O driver kgdboc.
root@qemux86:~# echo g > /proc/sysrq-trigger
SysRq : DEBUG

Entering kdb (current=0xcf0f6a80, pid 446) on processor 0 due to Keyboard Entry
[0]kdb>

Debug Window:

[chris@thinkpad build-qemux86]$ ./tmp/sysroots/x86_64-linux/usr/bin/i586-poky-linux/i586-poky-linux-gdb
(gdb) set sysroot debugfs
(gdb) set substitute-path /usr/src/debug debugfs/usr/src/debug
(gdb) file debugfs/boot/vmlinux-3.14.0-yocto-standard
Reading symbols from /scratch/working/build-qemux86/debugfs/boot/vmlinux-3.14.0-yocto-standard...done.
(gdb) target remote localhost:2346
Remote debugging using localhost:2346
kgdb_breakpoint ()
    at /scratch/working/build-qemux86/tmp/work/qemux86-poky-linux/linux-yocto/3.14+gitAUTOINC+09424cee64_f9048769cc-r0/linux/kernel/debug/debug_core.c:1043
1043            wmb(); /* Sync point after breakpoint */
(gdb) monitor lsmod
Module                  Size  modstruct     Used by
morsemod                3973  0xd081a640    0  (Live) 0xd081a000 [ ]
nfsd                  206468  0xd18f90a0   11  (Live) 0xd18ce000 [ ]
uvesafb                22894  0xd083baa0    1  (Live) 0xd0837000 [ ]
(gdb) add-symbol-file debugfs/lib/modules/3.14.0-yocto-standard/extra/morsemod.ko 0xd081a000
add symbol table from file "debugfs/lib/modules/3.14.0-yocto-standard/extra/morsemod.ko" at
        .text_addr = 0xd081a000
(y or n) y
Reading symbols from /scratch/working/build-qemux86/debugfs/lib/modules/3.14.0-yocto-standard/extra/morsemod.ko...done.
(gdb)

KGDBoC - Break in simkey_store

We know the bug is likely in simkey_store because that is the routine that is called when the user attempt to write to the simkey file to control behaviors.

(gdb) break simkey_store
Breakpoint 1 at 0xd081a000: file /scratch/working/build-qemux86/tmp/work/qemux86-poky-linux/morsemod/2014.10.0-r0/morsemod.c, line 193.
(gdb) c
Continuing.

KGDBoC - Stepping to bug

Does it work yet... Console Window:

[0]kdb> root@qemux86:/sys/kernel/morsemod# echo '>' > simkey

Debug Window: Verify that the input was processed correctly

...
Continuing.

Breakpoint 1, simkey_store (kobj=0xc0058880, attr=0xd081a628, buf=0xc00102f0 ">\n", count=count@entry=2)
    at /scratch/working/build-qemux86/tmp/work/qemux86-poky-linux/morsemod/2014.10.0-r0/morsemod.c:193
193     {
(gdb) list
188             return sprintf(buf, "K=%d L=%d B=%d LP=%d \n", key, led, broadcast, loopback);
189     }
190
191     static ssize_t simkey_store(struct kobject *kobj, struct kobj_attribute *attr,
192                              const char *buf, size_t count)
193     {
194             int var;
195
196             if        ('<' == buf[0]) broadcast=1;
197               else if ('>' == buf[0]) broadcast=1;
(gdb) print buf[0]
$1 = 62 '>'
(gdb)

Now step through the code to where > is processed.

Observe that due to optimization it skips over that line! Something must be wrong here!

(gdb) n
196             if        ('<' == buf[0]) broadcast=1;
(gdb) n
196             if        ('<' == buf[0]) broadcast=1;
(gdb) n
204     }
(gdb)

KGDBoC - Disassembly

If you disassemble the code, you’ll see that both < and > are setting 1.

(gdb) disassemble /m
Dump of assembler code for function simkey_store:
193     {
   0xd081a000 <+0>:     push   %ebp
   0xd081a001 <+1>:     mov    %esp,%ebp
   0xd081a003 <+3>:     lea    %ds:0x0(%esi,%eiz,1),%esi

194             int var;
195
196             if        ('<' == buf[0]) broadcast=1;
   0xd081a008 <+8>:     movzbl (%ecx),%eax
   0xd081a00b <+11>:    mov    %eax,%edx
   0xd081a00d <+13>:    and    $0xfffffffd,%edx
   0xd081a010 <+16>:    cmp    $0x3c,%dl
   0xd081a013 <+19>:    je     0xd081a040 <simkey_store+64>
   0xd081a043 <+67>:    movl   $0x1,0xd081a7c4

197               else if ('>' == buf[0]) broadcast=1;
198               else if ('[' == buf[0]) loopback=1;
   0xd081a015 <+21>:    cmp    $0x5b,%al
   0xd081a017 <+23>:    je     0xd081a060 <simkey_store+96>
   0xd081a063 <+99>:    movl   $0x1,0xd081a7c8

199               else if (']' == buf[0]) loopback=0;
   0xd081a019 <+25>:    cmp    $0x5d,%al
   0xd081a01b <+27>:    je     0xd081a050 <simkey_store+80>
   0xd081a053 <+83>:    movl   $0x0,0xd081a7c8
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) print *(int*) 0xd081a7c4
$2 = 1
(gdb)

KGDBoC - Manually changing variables

We can manually clear the value (note that this has to be done after the code sets it to 0)

(gdb) n
kobj_attr_store (kobj=<optimized out>, attr=<optimized out>, buf=<optimized out>, count=2)
    at /scratch/working/build-qemux86/tmp/work/qemux86-poky-linux/linux-yocto/3.14+gitAUTOINC+09424cee64_f9048769cc-r0/linux/lib/kobject.c:776
776     }
(gdb) set *(int*) 0xd081a7c4 = 0
(gdb) print *(int*) 0xd081a7c4
$3 = 0
(gdb) c
Continuing.

Console Window:

root@qemux86:/sys/kernel/morsemod# cat simkey
K=0 L=0 B=0 LP=0
root@qemux86:/sys/kernel/morsemod#

OK we found the bug, go fix the code:

-  else if ('>' == buf[0]) broadcast=1;
+  else if ('>' == buf[0]) broadcast=0;

Retest the code, observe that it now passes all of the tests!

KGDBoC - Bugs fixed

qemux86 login: root
root@qemux86:~# modprobe morsemod
root@qemux86:~# cd /sys/kernel/morsemod/
root@qemux86:/sys/kernel/morsemod# cat simkey
K=0 L=0 B=0 LP=0
root@qemux86:/sys/kernel/morsemod# echo '<' > simkey
root@qemux86:/sys/kernel/morsemod# cat simkey
K=1 L=0 B=1 LP=0
root@qemux86:/sys/kernel/morsemod# echo '>' > simkey
root@qemux86:/sys/kernel/morsemod# cat simkey
K=1 L=0 B=0 LP=0
root@qemux86:/sys/kernel/morsemod#

Preparing the Application

Exercising the morseapp Application

Exercising the morseapp Application (Picture taken from the slides).

Run the morseapp Application

Console Window: Start morseapp first time

root@qemux86:~# /usr/bin/morseapp
Welcome to morseapp!



Commands  bb:
  1. Configure
  2. Loopback
  3. Talk Morse
  4. Talk Text
  5. Talk to local Server
---------------------------
  6. Talk to Network Server
  7. Be  the Network Server
  8. Talk to Network Peer
---------------------------
  s. Test Server
  c. Test client
---------------------------
  q. Quit
Cmnd:

Or re-fetch and start morseapp after a rebuild:

root@qemux86:~# cat /opt/upload_morseapp.sh
scp chris@:/scratch/working/build-qemux86/tmp/work/i586-poky-linux/morseapp/2014.10.1-r0/image/usr/bin/morseapp .
root@qemux86:~# /opt/upload_morseapp.sh
/opt/upload_morseapp.sh: line 1: scp: command not found
root@qemux86:~#

Build Window: Add openssh to the image

[chris@thinkpad build-qemux86]$ vim conf/local.conf
[chris@thinkpad build-qemux86]$ grep openssh conf/local.conf
IMAGE_INSTALL_append = " openssh gdbserver morseapp morsemod"
[chris@thinkpad build-qemux86]$ bitbake core-image-base
[chris@thinkpad build-qemux86]$ runqemu qemux86 nographic qemuparams="-serial telnet:localhost:2345,server -serial tcp:localhost:2346,server,nowait"

Console Window: Try it again

[chris@thinkpad build-qemux86]$ telnet localhost 2345
qemux86 login: root
root@qemux86:~# /opt/upload_morseapp.sh
ssh: Could not resolve hostname : Name or service not known
root@qemux86:~# cat /opt/upload_morseapp.sh
scp chris@:/scratch/working/build-qemux86/tmp/work/i586-poky-linux/morseapp/2014.10.1-r0/image/usr/bin/morseapp .
root@qemux86:~#

OK, we have to edit the bb file:.

Source Window:

[chris@thinkpad morsemod-2014.10.0]$ cd ..
[chris@thinkpad morsemod]$ ls
morsemod-2014.10.0  morsemod_2014.10.0.bb  morsemod-2014.10.1  morsemod_2014.10.1.bb
[chris@thinkpad morsemod]$ cd ../morseapp/
[chris@thinkpad morseapp]$ ls
morseapp-2014.10.0  morseapp_2014.10.0.bb  morseapp-2014.10.1  morseapp_2014.10.1.bb
[chris@thinkpad morseapp]$ vim morseapp_2014.10.0.bb
[chris@thinkpad morseapp]$ cat morseapp_2014.10.0.bb
DESCRIPTION = "This package contains the simple morse code program."
LICENSE = "BSD-2-Clause"
LIC_FILES_CHKSUM = "file://license.txt;md5=47bc60f9825756218080dbd5e11c78a7"

SECTION = "sample"

SRC_URI = "file://license.txt \
           file://morse_app.c \
           file://morse_app.h \
           file://morse_codec.c \
           file://morse_codec.h \
           file://morse_gpio.c \
           file://morse_gpio.h \
           file://morse_client.c \
           file://morse_client.h \
           file://morse_server.c \
           file://morse_server.h \
              "

S = "${WORKDIR}"

do_compile() {
        ${CC} ${CFLAGS} ${CINCLUDES} -c -o morse_codec.o  morse_codec.c
        ${CC} ${CFLAGS} ${CINCLUDES} -c -o morse_gpio.o   morse_gpio.c
        ${CC} ${CFLAGS} ${CINCLUDES} -c -o morse_client.o morse_client.c
        ${CC} ${CFLAGS} ${CINCLUDES} -c -o morse_server.o morse_server.c
        ${CC} ${CFLAGS} ${CINCLUDES} -c -o morse_app.o    morse_app.c
        ${CC} ${LFLAGS} ${LINCLUDES} -o morseapp morse_app.o morse_codec.o morse_gpio.o morse_client.o morse_server.o
}

# tell bitbake to include all files, even outside of default dirs
FILES_${PN} = "/*"

do_install() {
  install -d ${D}${bindir}
  install -m 0755 morseapp ${D}${bindir}

  # shameless hacking: add helper upload scripts
  mkdir -p ${D}/opt
  export ipaddr=`ifconfig eth0 | grep "inet addr" | sed -e "s/.*inet addr://" -e "s/ .*//"`
  echo "scp $USER@$ipaddr:${D}/usr/bin/morseapp ." > ${D}/opt/upload_morseapp.sh
  echo "scp $USER@$ipaddr:`ls ${TOPDIR}/tmp/work/*/morsemod/0.1-r0/morsemod.ko` ." > ${D}/opt/upload_morsemod.sh
  echo "insmod morsemod.ko; echo 8 > /sys/kernel/morsemod/simkey" > ${D}/opt/broadcast_morsemod.sh
  chmod +x ${D}/opt/upload_morseapp.sh
  chmod +x ${D}/opt/upload_morsemod.sh
  chmod +x ${D}/opt/broadcast_morsemod.sh
  # ... and make a tarball for full bootstrapping to new target
  mkdir -p ${TOPDIR}/morseapp
  if [ -f "`ls ${TOPDIR}/tmp/work/*/morsemod/0.1-r0/morsemod.ko`" ] ; then
      cp   `ls ${TOPDIR}/tmp/work/*/morsemod/0.1-r0/morsemod.ko` ${TOPDIR}/morseapp
  fi
  cp ${D}/usr/bin/morseapp                                 ${TOPDIR}/morseapp
  cp -r ${D}/opt                                           ${TOPDIR}/morseapp
  cd ${TOPDIR}/morseapp
  tar -cf ${TOPDIR}/morseapp.tar *
}

Assuming your ifconfig looks similar like below and you are connected to enp0s29u1u2:

[chris@thinkpad ~]$ ifconfig
em1: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether d1:de:d0:70:34:a1  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 20  memory 0xf1500000-f1520000

enp0s29u1u2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.100  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::5a2c:80ff:fe13:9263  prefixlen 64  scopeid 0x20<link>
        ether 58:2c:80:13:92:63  txqueuelen 1000  (Ethernet)
        RX packets 13775  bytes 10514505 (10.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 15322  bytes 1322417 (1.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 0  (Local Loopback)
        RX packets 121067  bytes 15000397 (14.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 121067  bytes 15000397 (14.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

tap0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.7.1  netmask 255.255.255.255  broadcast 192.168.7.255
        inet6 fe80::dc5c:61ff:feb9:f6f0  prefixlen 64  scopeid 0x20<link>
        ether en:12:d3:b9:06:00  txqueuelen 500  (Ethernet)
        RX packets 376  bytes 57548 (56.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 30  bytes 3086 (3.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlp3s0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether 10:00:b0:90:00:04  txqueuelen 1000  (Ethernet)
        RX packets 55554  bytes 25369145 (24.1 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 69754  bytes 71215540 (67.9 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[chris@thinkpad ~]$ export ipaddr=`ifconfig enp0s29u1u2 | grep 'inet' | cut -d: -f2 | awk '{ print $2}'`
[chris@thinkpad ~]$ echo $ipaddr
192.168.1.100
[chris@thinkpad ~]$ ip route get 8.8.8.8 | awk 'NR==1 {print $NF}'
192.168.1.100
[chris@thinkpad ~]$

Then change do_install() as follows:

-  export ipaddr=`ifconfig eth0 | grep "inet addr" | sed -e "s/.*inet addr://" -e "s/ .*//"`
+  export ipaddr=$(ip route get 8.8.8.8 | awk 'NR==1 {print $NF}')

Also make sure you have an ssh server running on your local machine and that password authentication is enabled:

[chris@thinkpad ~]$ sudo grep PasswordAuthentication /etc/ssh/sshd_config
#PasswordAuthentication yes
PasswordAuthentication no
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication, then enable this but set PasswordAuthentication
[chris@thinkpad ~]$ sudo vim /etc/ssh/sshd_config
[chris@thinkpad ~]$ sudo grep PasswordAuthentication /etc/ssh/sshd_config
#PasswordAuthentication yes
PasswordAuthentication yes
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication, then enable this but set PasswordAuthentication
[chris@thinkpad ~]$ sudo systemctl restart sshd.service
[chris@thinkpad ~]$

Now rebuild the image and try it again.

Build Window:

[chris@thinkpad build-qemux86]$ time bitbake core-image-base
...
NOTE: Tasks Summary: Attempted 2852 tasks of which 2844 didn't need to be rerun and all succeeded.

real    1m32.028s
user    1m25.886s
sys     0m18.624s
[chris@thinkpad build-qemux86]$ runqemu qemux86 nographic qemuparams="-serial telnet:localhost:2345,server -serial tcp:localhost:2346,server,nowait"

Console Window:

[chris@thinkpad build-qemux86]$ telnet localhost 2345
qemux86 login: root
root@qemux86:~# /opt/upload_morseapp.sh
The authenticity of host '192.168.1.100 (192.168.1.100)' can't be established.
ECDSA key fingerprint is 7d:17:44:30:56:3f:6c:87:6d:ec:4b:94:8c:6f:b7:06.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.1.100' (ECDSA) to the list of known hosts.
chris@192.168.1.100's password:
tput: No value for $TERM and no -T specified
tput: No value for $TERM and no -T specified
tput: No value for $TERM and no -T specified
tput: No value for $TERM and no -T specified
tput: No value for $TERM and no -T specified
tput: No value for $TERM and no -T specified
tput: No value for $TERM and no -T specified
tput: No value for $TERM and no -T specified
morseapp                                      100%   75KB  74.5KB/s   00:00
root@qemux86:~#

OK, this works, now you can update your application without restarting QEMU and later you don’t need to copy a new image to your SD card every time you change something in the code while developing your application.

Step by Step: The morseapp Application (1)

  • Set the input device as the simulator with the commands 1 > 5 > m.

    root@qemux86:~# modprobe morsemod
    root@qemux86:~# /usr/bin/morseapp
    Welcome to morseapp!
    
    
    
    Commands  bb:
      1. Configure
      2. Loopback
      3. Talk Morse
      4. Talk Text
      5. Talk to local Server
    ---------------------------
      6. Talk to Network Server
      7. Be  the Network Server
      8. Talk to Network Peer
    ---------------------------
      s. Test Server
      c. Test client
    ---------------------------
      q. Quit
    Cmnd: 1
    Hardware Device:
     > 1. No device
       2. Beaglebone Black
       3. Minnowboard Max
       4. Wandboard Quad
    Simulated Device:
       5. Simulated device  (morsemod)
       6. Morsemod instance (0)
    Remote Server:
       7. IP Address (localhost)
       m. Main Menu
    Cmnd: 5
    Hardware Device:
       1. No device
       2. Beaglebone Black
       3. Minnowboard Max
       4. Wandboard Quad
    Simulated Device:
     > 5. Simulated device  (morsemod)
       6. Morsemod instance (0)
    Remote Server:
       7. IP Address (localhost)
       m. Main Menu
    Cmnd: m
    
    
    Commands  bb:
      1. Configure
      2. Loopback
      3. Talk Morse
      4. Talk Text
      5. Talk to local Server
    ---------------------------
      6. Talk to Network Server
      7. Be  the Network Server
      8. Talk to Network Peer
    ---------------------------
      s. Test Server
      c. Test client
    ---------------------------
      q. Quit
    Cmnd:
    

    If you see the error ERROR  : fd_key=-1, fd_led=-1 then you need to load the morsemod module first.

  • The loopback mode will echo changed values from the morsemod device.

    Cmnd: 2
    
    
    [ Loopback : device keys are echoed back to the device LED ]
    
    Type '#' to quit
    
    Device Key: [ ]
    
  • The talk morse code mode will support conversation between the app and the device, with backdoor keys for morsemod.

    Cmnd: 3
    
    
    [ Talk Morse code ]
    
    Type the '.' period key to toggle your 'key'
      * a 'dit' is about 1/2 seconds
      * a 'dah' is about 1 1/2 seconds (three 'dits')
      * a letter space is about 1/2 seconds
      * a word   space is about 1 1/2 seconds
    Type these keys for the simulated device
      '/' : toggle the device's key
      '<' : broadcast mode on
      '>' : broadcast mode off
    Type '#' to quit
    
    UserKey: [*] | DeviceKey: [*] || SIM: KEY LED
    

Step by Step: The morseapp Application (2)

  • The talk text mode will support a text-over-morse conversation between the app and the device.

    Cmnd: 4
    
    
    [ Talk Text (ASCII) ]
    
    Type your text message:'
      * use the letters a-z, 0-9 (case is ignored)
      * use a space for word separation
    Type these keys for the simulated device
      '<' : broadcast mode on
      '>' : broadcast mode off
      '\' : force clear the out buffer
    Type '#' to quit
    
    In:[  hhseh_____________] (***  ) | Out: [____________________] ()
    
  • Hit the < to remotely start the broadcast mode

  • Observe that there are dits but no dashes coming in and that cannot be right - time to bring out the debugger!

  • Quit the application with # and q and stop QEMU with Crtl-c

Using GDB - Setup

Let’s step into the program and see how to configure the debugging.

Console Window:

root@qemux86:~# gdbserver /dev/ttyS1 morseapp
Process morseapp created; pid = 536
Remote debugging using /dev/ttyS1

Debug Window (do not forget to regenerate the debugfs after changing something):

[chris@thinkpad build-qemux86]$ rm -rf debugfs ; mkdir debugfs ; cd debugfs
[chris@thinkpad debugfs]$ for pkg in ../tmp/deploy/rpm/*/*-dbg* ; do ../tmp/sysroots/x86_64-linux/usr/lib/rpm/rpm2cpio $pkg | cpio -i ; done
[chris@thinkpad debugfs]$ tar xvfj ../tmp/deploy/images/qemux86/core-image-base-qemux86.tar.bz2
[chris@thinkpad debugfs]$ cd ..
[chris@thinkpad build-qemux86]$ ./tmp/sysroots/x86_64-linux/usr/bin/i586-poky-linux/i586-poky-linux-gdb
(gdb) set sysroot debugfs
(gdb) set substitute-path /usr/src/debug debugfs/usr/src/debug
(gdb) file debugfs/usr/bin/morseapp
Reading symbols from /scratch/working/build-qemux86/debugfs/usr/bin/morseapp...Reading symbols from /scratch/working/build-qemux86/debugfs/usr/bin/.debug/morseapp...done.
done.
(gdb) target remote localhost:2346
Remote debugging using localhost:2346
Reading symbols from debugfs/lib/ld-linux.so.2...Reading symbols from /scratch/working/build-qemux86/debugfs/lib/.debug/ld-2.19.so...done.
done.
Loaded symbols for debugfs/lib/ld-linux.so.2
0x440e6d00 in _start () from debugfs/lib/ld-linux.so.2
(gdb)

Using GDB - Running

The application was started in the halted position, so let’s let it run.

Debug Window:

(gdb) c
Continuing.
warning: Could not load shared library symbols for linux-gate.so.1.
Do you need "set solib-search-path" or "set sysroot"?

Note: If you see references or failed to load messages for linux-gate.so.1, that’s a virtual library that the kernel sets up for syscalls - there is nothing to load.

Console Window: Follow the steps to enable Talk Text with Broadcast, use Crtl-c to signal the application and debugger with a SIGINT

Welcome to morseapp!



Commands  bb:
  1. Configure
  2. Loopback
  3. Talk Morse
  4. Talk Text
  5. Talk to local Server
---------------------------
  6. Talk to Network Server
  7. Be  the Network Server
  8. Talk to Network Peer
---------------------------
  s. Test Server
  c. Test client
---------------------------
  q. Quit
Cmnd: 1
Hardware Device:
 > 1. No device
   2. Beaglebone Black
   3. Minnowboard Max
   4. Wandboard Quad
Simulated Device:
   5. Simulated device  (morsemod)
   6. Morsemod instance (0)
Remote Server:
   7. IP Address (localhost)
   m. Main Menu
Cmnd: 5
Hardware Device:
   1. No device
   2. Beaglebone Black
   3. Minnowboard Max
   4. Wandboard Quad
Simulated Device:
 > 5. Simulated device  (morsemod)
   6. Morsemod instance (0)
Remote Server:
   7. IP Address (localhost)
   m. Main Menu
Cmnd: m


Commands  bb:
  1. Configure
  2. Loopback
  3. Talk Morse
  4. Talk Text
  5. Talk to local Server
---------------------------
  6. Talk to Network Server
  7. Be  the Network Server
  8. Talk to Network Peer
---------------------------
  s. Test Server
  c. Test client
---------------------------
  q. Quit
Cmnd: 4


[ Talk Text (ASCII) ]

Type your text message:'
  * use the letters a-z, 0-9 (case is ignored)
  * use a space for word separation
Type these keys for the simulated device
  '<' : broadcast mode on
  '>' : broadcast mode off
  '\' : force clear the out buffer
Type '#' to quit

In:[  hhse______________] (***  ) | Out: [____________________] ()

Debug Window:

Program received signal SIGINT, Interrupt.
0x441ac1fb in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81
81      T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
(gdb) bt
#0  0x441ac1fb in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81
#1  0x441dc273 in usleep (useconds=useconds@entry=50000) at ../sysdeps/unix/sysv/linux/usleep.c:32
#2  0x080494ec in talk_text () at morse_app.c:266
#3  0x08049de9 in parent (p=p@entry=0xbffffd18, child_pid=521) at morse_app.c:527
#4  0x08048d68 in main () at morse_app.c:460
(gdb)

Using GDB - Stepping with finishing

Lets take a look at talk_text (use finish to complete the current function and return to the caller).

(gdb) finish
Run till exit from #0  0x441ac1fb in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81
usleep (useconds=useconds@entry=50000) at ../sysdeps/unix/sysv/linux/usleep.c:33
33      }
(gdb) finish
Run till exit from #0  usleep (useconds=useconds@entry=50000) at ../sysdeps/unix/sysv/linux/usleep.c:33
0x080494ec in talk_text () at morse_app.c:266
266                     usleep(50000);
Value returned is $1 = 0
(gdb)

Using GDB - Stepping with next

We can step the program with next.

Note: Since the code is optimized stepping is out of order!

We can also use until to step until the next line of code.

(gdb) n
224                     if (9 < strlen(outTextStr)) {
(gdb) until
230                             strcpy(disp_outTextStr,outTextStr);
(gdb) bt
#0  talk_text () at morse_app.c:230
#1  0x08049de9 in parent (p=p@entry=0xbffffd18, child_pid=364) at morse_app.c:527
#2  0x08048d68 in main () at morse_app.c:460
(gdb)

Lets set a break point on scan_morse_in()

(gdb) break scan_morse_in
Breakpoint 1 at 0x8049f90: file morse_codec.c, line 145.
(gdb)

Using GDB - Continuing to the bug

Continue execution until we hit that function

(gdb) c
Continuing.

Breakpoint 1, scan_morse_in () at morse_codec.c:145
145     char scan_morse_in(void) {
(gdb) list
140             inTextPtr = (inTextPtr+1) % TEXTBUF_MAX;
141
142             return c;
143     }
144
145     char scan_morse_in(void) {
146             char key;
147             char ret_key='\0';
148
149             /* read the device key port */
(gdb)
150             key = get_device_key();
151             if (1 == key)
152                     highcnt++;
153             else
154                     lowcnt++;
155
156             /* parse the 1->0 transition */
157             if ((1 == lastkey) && (0 == key)) {
158                     if (highcnt <= dit_max_cnt)
159                             strcat(inMorseBuf,"*");
(gdb)
160                     else
161                             strcat(inMorseBuf,"*");
162                     highcnt=0;
163             }
164
165             /* parse the 0->1 transition */
166             if ((0 == lastkey) && (1 == key)) {
167                     lowcnt=0;
168             }
169
(gdb)

You can see around 159 and 161 where the * and - are put into the buffer... lets break on the *.

(gdb) break 159
Breakpoint 2 at 0x8049fde: file morse_codec.c, line 159.
(gdb) clear scan_morse_in
Deleted breakpoint 1
(gdb) c
Continuing.

Breakpoint 2, scan_morse_in () at morse_codec.c:159
159                             strcat(inMorseBuf,"*");
(gdb) list
154                     lowcnt++;
155
156             /* parse the 1->0 transition */
157             if ((1 == lastkey) && (0 == key)) {
158                     if (highcnt <= dit_max_cnt)
159                             strcat(inMorseBuf,"*");
160                     else
161                             strcat(inMorseBuf,"*");
162                     highcnt=0;
163             }
(gdb)

Using GDB - Finding the bug

OK, the problem is that we are returning dits for both short and long signals, and the fix is simple:

  157             if ((1 == lastkey) && (0 == key)) {
  158                     if (highcnt <= dit_max_cnt)
  159                             strcat(inMorseBuf,"*");
  160                     else
- 161                             strcat(inMorseBuf,"*");
+ 161                             strcat(inMorseBuf,"-");
  162                     highcnt=0;
  163             }

You can fix now and rebuild.

In:[  ypdevday elce ____] (**-- ) | Out: [____________________] ()

Using GDB - Extra credit

BTW, we can inspect variables...

(gdb) print lastkey
$1 = 1 '\001'
(gdb) print key
$2 = 0
(gdb) print highcnt
$3 = 9
(gdb)

Note: If you are ever looking at a file and are not sure where the source is, use info source:

(gdb) info source
Current source file is morse_app.c
Compilation directory is /usr/src/debug/morseapp/2014.10.0-r0
Located in /scratch/working/build-qemux86/debugfs/usr/src/debug/morseapp/2014.10.0-r0/morse_app.c
Contains 553 lines.
Source language is c.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
(gdb)

You can do the same debugging process as above, but instead of using a serial console, use TCP/IP if your device supports it.

Simply replace the /dev/ttyS1 with the address and port of the GDB client.

Console Window:

qemux86 login: root
root@qemux86:~# modprobe morsemod
root@qemux86:~# ifconfig
eth0      Link encap:Ethernet  HWaddr 52:54:00:12:34:56
          inet addr:192.168.7.2  Bcast:192.168.7.255  Mask:255.255.255.0
          inet6 addr: fe80::5054:ff:fe12:3456/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:42 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:6397 (6.2 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:34 errors:0 dropped:0 overruns:0 frame:0
          TX packets:34 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:2380 (2.3 KiB)  TX bytes:2380 (2.3 KiB)

root@qemux86:~# gdbserver 192.168.7.1:2345 morseapp
Process morseapp created; pid = 358
Listening on port 2345

Debug Window:

[chris@thinkpad build-qemux86]$ ./tmp/sysroots/x86_64-linux/usr/bin/i586-poky-linux/i586-poky-linux-gdb
(gdb) set sysroot debugfs
(gdb) set substitute-path /usr/src/debug debugfs/usr/src/debug
(gdb) file debugfs/usr/bin/morseapp
Reading symbols from /scratch/working/build-qemux86/debugfs/usr/bin/morseapp...Reading symbols from /scratch/working/build-qemux86/debugfs/usr/bin/.debug/morseapp...done.
done.
(gdb) target remote 192.168.7.2:2345
Remote debugging using 192.168.7.2:2345
Reading symbols from debugfs/lib/ld-linux.so.2...Reading symbols from /scratch/working/build-qemux86/debugfs/lib/.debug/ld-2.19.so...done.
done.
Loaded symbols for debugfs/lib/ld-linux.so.2
0x4712ed00 in _start () from debugfs/lib/ld-linux.so.2
(gdb) c
Continuing.

Step by Step: The morseapp Application (3)

  • The working talk text mode will support a text-over-morse conversation between the app and the device.

    Cmnd: 4
    
    
    [ Talk Text (ASCII) ]
    
    Type your text message:'
      * use the letters a-z, 0-9 (case is ignored)
      * use a space for word separation
    Type these keys for the simulated device
      '<' : broadcast mode on
      '>' : broadcast mode off
      '\' : force clear the out buffer
    Type '#' to quit
    
    In:[?devd_____________] (     ) | Out: [hello world_______] (-** *-** +27)
    
  • The talk local server mode will support simple morse code queries to a local server

    Cmnd: 5
    
    
    [ Client to Local Server Mode : respond to device queries ]
    
    Server commands are:
      'e' ('*')   : echo an 'e' ('*')
      'd' ('-**') : echo the day of the week ('mon' .. 'sun')
      't' ('-')   : echo the time ('hhmmss')
      'f' ('**-*'): echo a fortune place
      * use a space for word separation
    Type these keys for the simulated device:
      '/' : toggle the device's key
      '\' : force clear the out buffer
    Server prompt at device is 's' ('---')
    Type '#' to quit
    
    In:[?4 _______________] (     ) | Out: [__________________] ()
     Local server:e => 'e'
    In:[?4 yp_____________] (-    ) | Out: [e s_______________] ()
     Local server:d => 'Wed'
    In:[?4 yp_____________] (-**  ) | Out: [e swed s__________] (-- * -** +6)
     Local server:d => 'Wed'
    In:[?4 ypd____________] (*    ) | Out: [e swed swed s_____] (- * -**  +21)
     Local server:e => 'e'
    In:[?4 ypde___________] (***  ) | Out: [e swed swed se s__] (* -**   *+27)
    

Step by Step: The morseapp Application (4)

Step by Step: the morseapp application

Step by Step: the morseapp application (Picture taken from the slides).

Preparing the Target

Build the project for your board

WandBoard Quad
[chris@thinkpad ~]$ cd /scratch/working/
[chris@thinkpad working]$ . /scratch/yocto/sources/poky/oe-init-build-env build-wbquad
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.

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/

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'
[chris@thinkpad build-wbquad]$ echo "DL_DIR = \"/scratch/yocto/downloads\"" >> conf/local.conf
[chris@thinkpad build-wbquad]$ echo "SSTATE_DIR = \"/scratch/yocto/sstate-cache\"" >> conf/local.conf
[chris@thinkpad build-wbquad]$ echo "MACHINE = \"wandboard-quad\"" >> conf/local.conf
[chris@thinkpad build-wbquad]$ echo "IMAGE_INSTALL_append = \" openssh\"" >> conf/local.conf
[chris@thinkpad build-wbquad]$ cat conf/bblayers.conf | sed -e 's|/scratch/yocto/sources/poky/meta-yocto-bsp \\|/scratch/yocto/sources/poky/meta-yocto-bsp \\\n  /scratch/yocto/sources/meta-fsl-arm \\\n  /scratch/yocto/sources/meta-fsl-arm-extra \\\n  /scratch/yocto/sources/meta-fsl-demos \\|g' >j
[chris@thinkpad build-wbquad]$ mv j conf/bblayers.conf
[chris@thinkpad build-wbquad]$ echo "ACCEPT_FSL_EULA = \"1\"" >>conf/local.conf
[chris@thinkpad build-wbquad]$ bitbake core-image-base
Parsing recipes: 100% |#######################################| Time: 00:01:35
Parsing of 946 .bb files complete (0 cached, 946 parsed). 1311 targets, 90 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION        = "1.22.0"
BUILD_SYS         = "x86_64-linux"
NATIVELSBSTRING   = "Fedora-20"
TARGET_SYS        = "arm-poky-linux-gnueabi"
MACHINE           = "wandboard-quad"
DISTRO            = "poky"
DISTRO_VERSION    = "1.6.2"
TUNE_FEATURES     = "armv7a vfp neon callconvention-hard cortexa9"
TARGET_FPU        = "vfp-neon"
meta
meta-yocto
meta-yocto-bsp    = "daisy:1e668ccf1a05c5d730de9747bc1c2b0446bda556"
meta-fsl-arm      = "daisy:9bc540eec9a7e280af13371ea70650fcc47ea627"
meta-fsl-arm-extra = "daisy:e1085deb3d915d2a95a65cceadc77c6de0dadfb6"
meta-fsl-demos    = "daisy:f141c7d1158b8addbd6f1ed047a1b47c2ed85f8f"

NOTE: Preparing runqueue
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
Currently 4 running tasks (338 of 2305):
0: xz-native-5.1.3alpha-r0 do_configure (pid 28732)
1: gmp-native-5.1.1-r0 do_configure (pid 28888)
2: pkgconfig-native-0.28-r0 do_configure (pid 28949)
3: ncurses-native-5.9-r15.1 do_configure (pid 29016)
WARNING: Failed to fetch URL ftp://ftp.uni-erlangen.de/pub/Linux/LOCAL/dosfstools/dosfstools-2.11.src.tar.gz, attempting MIRRORS if available
WARNING: linux-firmware: NOT adding alternative provide /lib/firmware/brcm/brcmfmac-sdio.bin: /lib/firmware/brcm/brcmfmac4329.bin does not exist
WARNING: linux-firmware: NOT adding alternative provide /lib/firmware/brcm/brcmfmac-sdio.bin: /lib/firmware/brcm/brcmfmac4330.bin does not exist
NOTE: Tasks Summary: Attempted 2305 tasks of which 301 didn't need to be rerun and all succeeded.

Summary: There were 3 WARNING messages shown.

[chris@thinkpad build-wbquad]$
MinnowBoard Max
[chris@thinkpad ~]$ cd /scratch/working/
[chris@thinkpad working]$ . /scratch/yocto/sources/poky/oe-init-build-env build-minnowmx
[chris@thinkpad build-minnowmx]$ echo "DL_DIR = \"/scratch/yocto/downloads\"" >> conf/local.conf
[chris@thinkpad build-minnowmx]$ echo "SSTATE_DIR = \"/scratch/yocto/sstate-cache\"" >> conf/local.conf
[chris@thinkpad build-minnowmx]$ echo "MACHINE = \"intel-corei7-64\"" >> conf/local.conf
[chris@thinkpad build-minnowmx]$ echo "IMAGE_INSTALL_append = \" openssh\"" >> conf/local.conf
[chris@thinkpad build-minnowmx]$ cat conf/bblayers.conf | sed -e 's|/scratch/yocto/sources/poky/meta-yocto-bsp \\|/scratch/yocto/sources/poky/meta-yocto-bsp \\\n  /scratch/yocto/sources/meta-intel \\|g' >j
[chris@thinkpad build-minnowmx]$ mv j conf/bblayers.conf
[chris@thinkpad build-minnowmx]$ bitbake core-image-base
Parsing recipes: 100% |#######################################| Time: 00:01:31
Parsing of 885 .bb files complete (0 cached, 885 parsed). 1244 targets, 46 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION        = "1.22.0"
BUILD_SYS         = "x86_64-linux"
NATIVELSBSTRING   = "Fedora-20"
TARGET_SYS        = "x86_64-poky-linux"
MACHINE           = "intel-corei7-64"
DISTRO            = "poky"
DISTRO_VERSION    = "1.6.2"
TUNE_FEATURES     = "m64 corei7"
TARGET_FPU        = ""
meta
meta-yocto
meta-yocto-bsp    = "daisy:1e668ccf1a05c5d730de9747bc1c2b0446bda556"
meta-intel        = "daisy:39cdd2fa13bc387388bcf5f07b8ee4c45f3f2135"

NOTE: Preparing runqueue
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
WARNING: Failed to fetch URL http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc-7.2d.tar.gz, attempting MIRRORS if available
NOTE: validating kernel config, see log.do_kernel_configcheck for details
WARNING: Failed to fetch URL ftp://ftp.berlios.de/pub/cdrecord/alpha/cdrtools-3.01a20.tar.bz2, attempting MIRRORS if available
NOTE: Tasks Summary: Attempted 2571 tasks of which 327 didn't need to be rerun and all succeeded.

Summary: There were 2 WARNING messages shown.
[chris@thinkpad build-minnowmx]$
BeagleBone Black
[chris@thinkpad ~]$ cd /scratch/working/
[chris@thinkpad working]$ . /scratch/yocto/sources/poky/oe-init-build-env build-beaglebone
[chris@thinkpad build-beaglebone]$ echo "DL_DIR = \"/scratch/yocto/downloads\"" >> conf/local.conf
[chris@thinkpad build-beaglebone]$ echo "SSTATE_DIR = \"/scratch/yocto/sstate-cache\"" >> conf/local.conf
[chris@thinkpad build-beaglebone]$ echo "MACHINE = \"beaglebone\"" >> conf/local.conf
[chris@thinkpad build-beaglebone]$ echo "IMAGE_INSTALL_append = \" openssh\"" >> conf/local.conf
[chris@thinkpad build-beaglebone]$ bitbake core-image-base
Parsing recipes: 100% |#######################################| Time: 00:01:48
Parsing of 862 .bb files complete (0 cached, 862 parsed). 1221 targets, 61 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
BB_VERSION        = "1.22.0"
BUILD_SYS         = "x86_64-linux"
NATIVELSBSTRING   = "Fedora-20"
TARGET_SYS        = "arm-poky-linux-gnueabi"
MACHINE           = "beaglebone"
DISTRO            = "poky"
DISTRO_VERSION    = "1.6.2"
TUNE_FEATURES     = "armv7a vfp neon callconvention-hard cortexa8"
TARGET_FPU        = "vfp-neon"
meta
meta-yocto
meta-yocto-bsp    = "daisy:1e668ccf1a05c5d730de9747bc1c2b0446bda556"

NOTE: Preparing runqueue
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
NOTE: validating kernel config, see log.do_kernel_configcheck for details
NOTE: Tasks Summary: Attempted 2208 tasks of which 301 didn't need to be rerun and all succeeded.
[chris@thinkpad build-beaglebone]$

Create a bootable SD card for your board

Use the instructions in the Intro to Yocto Project quide (mirror) (Exercise 4) to create a bootable SD card.

Insert your SD card into your PC and determine the correct device by using dmesg |tail:

[chris@thinkpad ~]$ dmesg |tail
[128744.573527] sd 16:0:0:0: [sdc] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
[128744.575143] sd 16:0:0:1: [sdd] Attached SCSI removable disk
[128744.576483] sd 16:0:0:3: [sdf] Attached SCSI removable disk
[128744.578081] sd 16:0:0:2: [sde] Attached SCSI removable disk
[128744.588393]  sdc: sdc1
[128744.592394] sd 16:0:0:0: [sdc] Attached SCSI removable disk
[128748.583422] SELinux: initialized (dev sdc1, type vfat), uses genfs_contexts
[129112.625579] sdc: detected capacity change from 3904897024 to 0
[129185.309028] sd 16:0:0:0: [sdc] 7626752 512-byte logical blocks: (3.90 GB/3.63 GiB)
[129185.327990]  sdc: sdc1
[chris@thinkpad ~]$

I’m using /dev/sdc.

WandBoard Quad
[chris@thinkpad build-wbquad]$ sudo dd if=tmp/deploy/images/wandboard-quad/core-image-base-wandboard-quad-20141203212653.rootfs.sdcard of=/dev/sdc
163840+0 records in
163840+0 records out
83886080 bytes (84 MB) copied, 50.7747 s, 1.7 MB/s
[chris@thinkpad build-wbquad]$
MinnowBoard Max

Have a look at the slides.

BeagleBone Black

Have a look at the slides.

Open the console port and boot your board

Now put the SD card into your board, connect the serial cable to your PC and use minicom to open the serial port.

Use dmesg |tail to find out the correct serial port, I have to use /dev/ttyUSB0:

[chris@thinkpad build-wbquad]$ dmesg |tail
[129847.365608] usb 2-1.1.2: USB disconnect, device number 25
[129847.366337] pl2303 ttyUSB0: pl2303 converter now disconnected from ttyUSB0
[129847.366374] pl2303 2-1.1.2:1.0: device disconnected
[129849.579853] usb 2-1.1.2: new full-speed USB device number 30 using ehci-pci
[129849.655044] usb 2-1.1.2: New USB device found, idVendor=067b, idProduct=2303
[129849.655056] usb 2-1.1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[129849.655062] usb 2-1.1.2: Product: USB-Serial Controller D
[129849.655066] usb 2-1.1.2: Manufacturer: Prolific Technology Inc.
[129849.656266] pl2303 2-1.1.2:1.0: pl2303 converter detected
[129849.658102] usb 2-1.1.2: pl2303 converter now attached to ttyUSB0
[chris@thinkpad build-wbquad]$

First you need to create a new minicom configuration, I will name it yocto:

[chris@thinkpad ~]$ sudo minicom -s yocto

Go to Serial port setup, press a and set the serial port to /dev/ttyUSB0. Then press Enter, after that press f to set Hardware Flow Control to No and finally press ESC, select Save setup as yocto, save the configuration with Enter and then exit.

Depending on your Linux distributions configuration (groups, udev, file permissions) you can open the serial port with minicom yocto or have to use sudo minicom yocto (Note: It’s easy to change the configuration so that you don’t have to use sudo.):

[chris@thinkpad ~]$ minicom yocto

Now power your board on and you will see the bootlog:

[chris@thinkpad ~]$ minicom yocto

Welcome to minicom 2.6.2

OPTIONS: I18n
Compiled on Aug  7 2013, 13:32:48.
Port /dev/ttyUSB0, 14:51:04

Press CTRL-A Z for help on special keys



U-Boot 2014.01 (Dec 03 2014 - 20:27:55)

CPU:   Freescale i.MX6Q rev1.2 at 792 MHz
Reset cause: POR
Board: Wandboard
I2C:   ready
DRAM:  2 GiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
*** Warning - bad CRC, using default environment

No panel detected: default to HDMI
Display: HDMI (1024x768)
In:    serial
Out:   serial
Err:   serial
Net:   FEC [PRIME]
Hit any key to stop autoboot:  0
mmc0 is current device
reading boot.scr
** Unable to read file boot.scr **
reading zImage
5419552 bytes read in 255 ms (20.3 MiB/s)
Booting from mmc ...
- no HDMI monitor
Setting bus to 1
Valid chip addresses:
- no FWBADAPT-7WVGA-LCD-F07A-0102 display
reading imx6q-wandboard.dtb
43370 bytes read in 20 ms (2.1 MiB/s)
Kernel image @ 0x12000000 [ 0x000000 - 0x52b220 ]
## Flattened Device Tree blob at 18000000
   Booting using the fdt blob at 0x18000000
   Using Device Tree in place at 18000000, end 1800d969

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 3.10.17-1.0.1-wandboard+ga6e7fc5 (chris@thinkpad) (gcc version 4.8.2 (GCC) ) #1 SMP PREEMPT Wed4
CPU: ARMv7 Processor [412fc09a] revision 10 (ARMv7), cr=10c53c7d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine: Freescale i.MX6 Quad/DualLite (Device Tree), model: Wandboard Quad based on Freescale i.MX6 Quad
Truncating RAM at 10000000-8fffffff to -7f7fffff (vmalloc region overlap).
cma: CMA: reserved 256 MiB at 6e000000
Memory policy: ECC disabled, Data cache writealloc
PERCPU: Embedded 8 pages/cpu @81b53000 s8832 r8192 d15744 u32768
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 453136
Kernel command line: console=ttymxc0,115200 root=/dev/mmcblk0p2 rootwait rw
PID hash table entries: 4096 (order: 2, 16384 bytes)
Dentry cache hash table entries: 262144 (order: 8, 1048576 bytes)
Inode-cache hash table entries: 131072 (order: 7, 524288 bytes)
Memory: 1784MB = 1784MB total
Memory: 1534436k/1534436k available, 292380k reserved, 0K highmem
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    vmalloc : 0xf0000000 - 0xff000000   ( 240 MB)
    lowmem  : 0x80000000 - 0xef800000   (1784 MB)
    modules : 0x7f000000 - 0x80000000   (  16 MB)
      .text : 0x80008000 - 0x80c3d4e0   (12502 kB)
      .init : 0x80c3e000 - 0x80c83280   ( 277 kB)
      .data : 0x80c84000 - 0x80cd5700   ( 326 kB)
       .bss : 0x80cd5700 - 0x80d3a8b8   ( 405 kB)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
Preemptible hierarchical RCU implementation.
NR_IRQS:16 nr_irqs:16 16
L310 cache controller enabled
l2x0: 16 ways, CACHE_ID 0x410000c7, AUX_CTRL 0x32070000, Cache size: 1048576 B
sched_clock: 32 bits at 3000kHz, resolution 333ns, wraps every 1431655ms
CPU identified as i.MX6Q, silicon rev 1.2
Console: colour dummy device 80x30
Calibrating delay loop... 1581.05 BogoMIPS (lpj=7905280)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
CPU0: thread -1, cpu 0, socket 0, mpidr 80000000
Setting up static identity map for 0x8065f650 - 0x8065f6a8
CPU1: Booted secondary processor
CPU1: thread -1, cpu 1, socket 0, mpidr 80000001
CPU2: Booted secondary processor
CPU2: thread -1, cpu 2, socket 0, mpidr 80000002
CPU3: Booted secondary processor
CPU3: thread -1, cpu 3, socket 0, mpidr 80000003
Brought up 4 CPUs
SMP: Total of 4 processors activated (6324.22 BogoMIPS).
CPU: All CPU(s) started in SVC mode.
devtmpfs: initialized
pinctrl core: initialized pinctrl subsystem
regulator-dummy: no parameters
NET: Registered protocol family 16
DMA: preallocated 256 KiB pool for atomic coherent allocations
Use WDOG1 as reset source
syscon 20c8000.anatop: regmap [mem 0x020c8000-0x020c8fff] registered
vdd1p1: 800 <--> 1375 mV at 1125 mV
vdd3p0: 2800 <--> 3150 mV at 3000 mV
vdd2p5: 2000 <--> 2750 mV at 2425 mV
cpu: 725 <--> 1450 mV at 1150 mV
vddpu: 725 <--> 1450 mV at 1150 mV
vddsoc: 725 <--> 1450 mV at 1175 mV
syscon 20e0000.iomuxc-gpr: regmap [mem 0x020e0000-0x020e0037] registered
syscon 21bc000.ocotp-ctrl: regmap [mem 0x021bc000-0x021bffff] registered
hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 watchpoint registers.
hw-breakpoint: maximum watchpoint size is 4 bytes.
imx6q-pinctrl 20e0000.iomuxc: initialized IMX pinctrl driver
bio: create slab <bio-0> at 0
mxs-dma 110000.dma-apbh: initialized
1P8V: 1800 mV
2P5V: 2500 mV
3P3V: 3300 mV
usb_otg_vbus: 5000 mV
i2c-core: driver [max17135] using legacy suspend method
i2c-core: driver [max17135] using legacy resume method
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
i2c i2c-0: IMX I2C adapter registered
i2c i2c-1: IMX I2C adapter registered
i2c i2c-2: IMX I2C adapter registered
Linux video capture interface: v2.00
pps_core: LinuxPPS API ver. 1 registered
pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
PTP clock support registered
imx-ipuv3 2400000.ipu: IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7)
imx-ipuv3 2800000.ipu: IPU DMFC NORMAL mode: 1(0~1), 5B(4,5), 5F(6,7)
mxc_mipi_csi2 21dc000.mipi_csi: i.MX MIPI CSI2 driver probed
mxc_mipi_csi2 21dc000.mipi_csi: i.MX MIPI CSI2 dphy version is 0x3130302a
MIPI CSI2 driver module loaded
Advanced Linux Sound Architecture Driver Initialized.
Bluetooth: Core ver 2.16
NET: Registered protocol family 31
Bluetooth: HCI device and connection manager initialized
Bluetooth: HCI socket layer initialized
Bluetooth: L2CAP socket layer initialized
Bluetooth: SCO socket layer initialized
cfg80211: Calling CRDA to update world regulatory domain
Switching to clocksource mxc_timer1
NET: Registered protocol family 2
TCP established hash table entries: 16384 (order: 5, 131072 bytes)
TCP bind hash table entries: 16384 (order: 5, 131072 bytes)
TCP: Hash tables configured (established 16384 bind 16384)
TCP: reno registered
UDP hash table entries: 1024 (order: 3, 32768 bytes)
UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
hw perfevents: enabled with ARMv7 Cortex-A9 PMU driver, 7 counters available
pureg-dummy: no parameters
imx6_busfreq busfreq.15: DDR medium rate not supported.
Bus freq driver module loaded
wandboard-rfkill rfkill.25: Wandboard rfkill initialization
wandboard-rfkill rfkill.25: initialized Wandboard revision check gpio (60)
wandboard-rfkill rfkill.25: wandboard is rev C1
wandboard-rfkill rfkill.25: initialize wifi chip
wandboard-rfkill rfkill.25: wifi-rfkill registered.
wandboard-rfkill rfkill.25: initialize bluetooth chip
wandboard-rfkill rfkill.25: bluetooth-rfkill registered.
VFS: Disk quotas dquot_6.5.2
Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
NFS: Registering the id_resolver key type
Key type id_resolver registered
Key type id_legacy registered
jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
fuse init (API version 7.22)
msgmni has been set to 3508
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
imx-weim 21b8000.weim: WEIM driver registered.
MIPI DSI driver module loaded
mxc_sdc_fb fb.26: register mxc display driver hdmi
mxc_hdmi 20e0000.hdmi_video: Detected HDMI controller 0x13:0xa:0xa0:0xc1
fbcvt: 1920x1080@60: CVT Name - 2.073M9
mxc_sdc_fb fb.26: 1920x1080 h_sync,r,l: 44,88,148  v_sync,l,u: 5,4,36 pixclock=148500000 Hz
imx-ipuv3 2400000.ipu: IPU DMFC DP HIGH RESOLUTION: 1(0,1), 5B(2~5), 5F(6,7)
mxc_sdc_fb fb.26: 1920x1080 h_sync,r,l: 44,88,148  v_sync,l,u: 5,4,36 pixclock=148500000 Hz
Console: switching to colour frame buffer device 240x67
imx-sdma 20ec000.sdma: no iram assigned, using external mem
imx-sdma 20ec000.sdma: loaded firmware 1.1
imx-sdma 20ec000.sdma: initialized
Serial: IMX driver
2020000.serial: ttymxc0 at MMIO 0x2020000 (irq = 58) is a IMX
console [ttymxc0] enabled
21ec000.serial: ttymxc2 at MMIO 0x21ec000 (irq = 60) is a IMX
serial: Freescale lpuart driver
[drm] Initialized drm 1.1.0 20060810
[drm] Initialized vivante 1.0.0 20120216 on minor 0
brd: module loaded
loop: module loaded
Wait for CR ACK error!
sata phy RX_PLL is stable!
ahci: SSS flag set, parallel bus scan disabled
ahci ahci: AHCI 0001.0300 32 slots 1 ports 3 Gbps 0x1 impl platform mode
ahci ahci: flags: ncq sntf stag pm led clo only pmp pio slum part ccc apst
scsi0 : ahci_platform
ata1: SATA max UDMA/133 mmio [mem 0x02200000-0x02203fff] port 0x100 irq 71
CAN device driver interface
libphy: fec_enet_mii_bus: probed
fec 2188000.ethernet eth0: registered PHC device 0
hso: drivers/net/usb/hso.c: Option Wireless
usbcore: registered new interface driver hso
ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
usbcore: registered new interface driver usb-storage
usbcore: registered new interface driver usbserial
usbcore: registered new interface driver keyspan_pda
usbserial: USB Serial support registered for Keyspan PDA
usbserial: USB Serial support registered for Keyspan PDA - (prerenumeration)
ci_hdrc ci_hdrc.1: doesn't support gadget
ci_hdrc ci_hdrc.1: EHCI Host Controller
ci_hdrc ci_hdrc.1: new USB bus registered, assigned bus number 1
ci_hdrc ci_hdrc.1: USB 2.0 started, EHCI 1.00
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 1 port detected
mousedev: PS/2 mouse device common for all mice
i2c-core: driver [isl29023] using legacy suspend method
i2c-core: driver [isl29023] using legacy resume method
snvs_rtc 20cc034.snvs-rtc-lp: rtc core: registered 20cc034.snvs-rtc-lp as rtc0
i2c /dev entries driver
mxc_v4l2_output v4l2_out.31: V4L2 device registered as video16
mxc_v4l2_output v4l2_out.31: V4L2 device registered as video17
i2c-core: driver [mag3110] using legacy suspend method
i2c-core: driver [mag3110] using legacy resume method
imx2-wdt 20bc000.wdog: IMX2+ Watchdog Timer enabled. timeout=60s (nowayout=0)
cpuidle: using governor ladder
cpuidle: using governor menu
sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
sdhci-pltfm: SDHCI platform and OF driver helper
sdhci-esdhc-imx 2190000.usdhc: could not get ultra high speed state, work on normal mode
mmc0: no vqmmc regulator found
mmc0: SDHCI controller on 2190000.usdhc [2190000.usdhc] using ADMA
sdhci-esdhc-imx 2194000.usdhc: could not get ultra high speed state, work on normal mode
mmc1: no vqmmc regulator found
mmc1: SDHCI controller on 2194000.usdhc [2194000.usdhc] using ADMA
sdhci-esdhc-imx 2198000.usdhc: could not get ultra high speed state, work on normal mode
mmc2: no vqmmc regulator found
ata1: SATA link down (SStatus 0 SControl 300)
mmc1: queuing unknown CIS tuple 0x80 (2 bytes)
mmc1: queuing unknown CIS tuple 0x80 (3 bytes)
mmc1: queuing unknown CIS tuple 0x80 (3 bytes)
mmc1: queuing unknown CIS tuple 0x80 (7 bytes)
mmc1: queuing unknown CIS tuple 0x80 (11 bytes)
mmc2: SDHCI controller on 2198000.usdhc [2198000.usdhc] using ADMA
mmc1: new high speed SDIO card at address 0001
mmc2: host does not support reading read-only switch. assuming write-enable.
mmc2: new high speed SDHC card at address 1234
mmcblk0: mmc2:1234 SA04G 3.63 GiB
 mmcblk0: p1 p2
Galcore version 4.6.9.9754
mxc_vdoa 21e4000.vdoa: i.MX Video Data Order Adapter(VDOA) driver probed
mxc_asrc 2034000.asrc: mxc_asrc registered
mxc_vpu 2040000.vpu: VPU initialized
caam 2100000.caam: device ID = 0x0a16010000000000 (Era -524)
caam 2100000.caam: job rings = 2, qi = 0
caam 2100000.caam: authenc-hmac-md5-cbc-aes-caam
caam 2100000.caam: authencesn-hmac-md5-cbc-aes-caam
caam 2100000.caam: authenc-hmac-sha1-cbc-aes-caam
caam 2100000.caam: authencesn-hmac-sha1-cbc-aes-caam
caam 2100000.caam: authenc-hmac-sha224-cbc-aes-caam
caam 2100000.caam: authencesn-hmac-sha224-cbc-aes-caam
caam 2100000.caam: authenc-hmac-sha256-cbc-aes-caam
caam 2100000.caam: authencesn-hmac-sha256-cbc-aes-caam
caam 2100000.caam: authenc-hmac-md5-cbc-des3_ede-caam
caam 2100000.caam: authencesn-hmac-md5-cbc-des3_ede-caam
caam 2100000.caam: authenc-hmac-sha1-cbc-des3_ede-caam
caam 2100000.caam: authencesn-hmac-sha1-cbc-des3_ede-caam
caam 2100000.caam: authenc-hmac-sha224-cbc-des3_ede-caam
caam 2100000.caam: authencesn-hmac-sha224-cbc-des3_ede-caam
caam 2100000.caam: authenc-hmac-sha256-cbc-des3_ede-caam
caam 2100000.caam: authencesn-hmac-sha256-cbc-des3_ede-caam
caam 2100000.caam: authenc-hmac-md5-cbc-des-caam
caam 2100000.caam: authencesn-hmac-md5-cbc-des-caam
caam 2100000.caam: authenc-hmac-sha1-cbc-des-caam
caam 2100000.caam: authencesn-hmac-sha1-cbc-des-caam
caam 2100000.caam: authenc-hmac-sha224-cbc-des-caam
caam 2100000.caam: authencesn-hmac-sha224-cbc-des-caam
caam 2100000.caam: authenc-hmac-sha256-cbc-des-caam
caam 2100000.caam: authencesn-hmac-sha256-cbc-des-caam
caam 2100000.caam: ecb-des-caam
caam 2100000.caam: ecb-arc4-caam
caam 2100000.caam: ecb-aes-caam
caam 2100000.caam: ctr-aes-caam
caam 2100000.caam: cbc-aes-caam
caam 2100000.caam: ecb-des3-caam
caam 2100000.caam: cbc-3des-caam
caam 2100000.caam: cbc-des-caam
caam 2100000.caam: fsl,sec-v4.0 algorithms registered in /proc/crypto
platform 2101000.jr0: registering rng-caam
platform caam_sm: caam_sm_test: 8-byte key test match OK
platform caam_sm: caam_sm_test: 16-byte key test match OK
platform caam_sm: caam_sm_test: 32-byte key test match OK
platform caam_secvio.32: security violation service handlers armed
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
i2c-core: driver [cs42888] using legacy suspend method
i2c-core: driver [cs42888] using legacy resume method
sgtl5000 1-000a: sgtl5000 revision 0x11
sgtl5000 1-000a: Failed to get supply 'VDDD': -19
1-000a: 1200 mV normal
sgtl5000 1-000a: Using internal LDO instead of VDDD
imx-sgtl5000 sound.22:  sgtl5000 <-> 2028000.ssi mapping ok
imx-spdif sound-spdif.23:  dit-hifi <-> 2004000.spdif mapping ok
imx-audio-hdmi sound-hdmi.24:  hdmi-hifi <-> hdmi_audio.16 mapping ok
TCP: cubic registered
NET: Registered protocol family 10
sit: IPv6 over IPv4 tunneling driver
NET: Registered protocol family 17
can: controller area network core (rev 20120528 abi 9)
NET: Registered protocol family 29
can: raw protocol (rev 20120528)
can: broadcast manager protocol (rev 20120528 t)
can: netlink gateway (rev 20130117) max_hops=1
8021q: 802.1Q VLAN Support v1.8
Key type dns_resolver registered
VFP support v0.3: implementor 41 architecture 3 part 30 variant 9 rev 4
snvs_rtc 20cc034.snvs-rtc-lp: setting system clock to 1970-01-01 00:00:01 UTC (1)
ALSA device list:
  #0: imx6-wandboard-sgtl5000
  #1: imx-spdif
  #2: imx-hdmi-soc
kjournald starting.  Commit interval 5 seconds
EXT3-fs (mmcblk0p2): using internal journal
EXT3-fs (mmcblk0p2): mounted filesystem with ordered data mode
VFS: Mounted root (ext3 filesystem) on device 179:2.
devtmpfs: mounted
Freeing unused kernel memory: 276K (80c3e000 - 80c83000)
INIT: version 2.88 booting
Starting udev
udevd[177]: starting version 182
fusion 1-0010: Failed to read firmware version
fusion: probe of 1-0010 failed with error -5
ov5640_read_reg:write reg error:reg=300a
camera ov5640_mipi is not found
ERROR: v4l2 capture: slave not found!
brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0: Oct 25 2011 19:34:12 version 5.90.125.104
brcmfmac: brcmf_fws_init: enabled bdcv2 tlv signaling [1]
Starting Bootlog daemon: bootlogd: cannot allocate pseudo tty: No such file or directory
bootlogd.
Populating dev cache
ALSA: Restoring mixer settings...
No state is present for card imx6wandboardsg
Found hardware: "imx6-wandboard-" "" "" "" ""
Hardware is initialized using a generic method
No state is present for card imx6wandboardsg
No state is present for card imxspdif
Found hardware: "imx-spdif" "" "" "" ""
INIT: Entering runlevel: 5
Configuring network interfaces... fec 2188000.ethernet eth0: Freescale FEC PHY driver [Generic PHY] (mii_bus:)
IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
udhcpc (v1.22.1) started
Sending discover...
Sending discover...
Sending discover...
No lease, failing
Starting system message bus: dbus.
Starting rpcbind daemon...done.
Starting advanced power management daemon: No APM support in kernel
(failed.)
Starting syslogd/klogd: done
 * Starting Avahi mDNS/DNS-SD Daemon: avahi-daemon
   ...done.
Starting Telephony daemon
Starting Linux NFC daemon
Stopping Bootlog daemon: bootlogd.
mxc_sdc_fb fb.26: 1920x1080 h_sync,r,l: 44,88,148  v_sync,l,u: 5,4,36 pixclock=148500000 Hz

Poky (Yocto Project Reference Distro) 1.6.2 wandboard-quad /dev/ttymxc0

wandboard-quad login: root
root@wandboard-quad:~#
libphy: 2188000.ethernet:01 - Link is Up - 1000/Full
IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready

root@wandboard-quad:~# ping google.de
ping: bad address 'google.de'
root@wandboard-quad:~# udhcpc eth0
udhcpc (v1.22.1) started
Sending discover...
Sending select for 10.42.0.91...
Lease of 10.42.0.91 obtained, lease time 3600
/etc/udhcpc.d/50default: Adding DNS 10.42.0.1
root@wandboard-quad:~# ping google.de
PING google.de (173.194.116.120): 56 data bytes
64 bytes from 173.194.116.120: seq=0 ttl=50 time=77.448 ms
64 bytes from 173.194.116.120: seq=1 ttl=50 time=77.190 ms
64 bytes from 173.194.116.120: seq=2 ttl=50 time=76.952 ms
^C
--- google.de ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 76.952/77.196/77.448 ms
root@wandboard-quad:~# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                62.0M     51.2M      7.6M  87% /
devtmpfs                749.2M      4.0K    749.2M   0% /dev
tmpfs                   877.4M    184.0K    877.2M   0% /run
tmpfs                   877.4M     56.0K    877.3M   0% /var/volatile
/dev/mmcblk0p1            8.0M      5.2M      2.8M  65% /media/mmcblk0p1
root@wandboard-quad:~#

Transfer in the MorseApp

Add the advanced layer to the project’s bblayers.conf:

[chris@thinkpad build-wbquad]$ vim conf/bblayers.conf
  # LAYER_CONF_VERSION is increased each time build/conf/bblayers.conf
  # changes incompatibly
  LCONF_VERSION = "6"

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

  BBLAYERS ?= " \
    /scratch/yocto/sources/poky/meta \
    /scratch/yocto/sources/poky/meta-yocto \
    /scratch/yocto/sources/poky/meta-yocto-bsp \
    /scratch/yocto/sources/meta-fsl-arm \
    /scratch/yocto/sources/meta-fsl-arm-extra \
    /scratch/yocto/sources/meta-fsl-demos \
+   /scratch/yocto/sources/ypdd-adv-layer \
    "
  BBLAYERS_NON_REMOVABLE ?= " \
    /scratch/yocto/sources/poky/meta \
    /scratch/yocto/sources/poky/meta-yocto \
    "

Build just the morseapp

[chris@thinkpad build-wbquad]$ bitbake morseapp

Open your target’s console, and scp the morseapp tarball to the target, and untar it.

root@wandboard-quad:~# ping thinkpad.local
PING thinkpad.local (10.42.0.1): 56 data bytes
64 bytes from 10.42.0.1: seq=0 ttl=64 time=0.412 ms
64 bytes from 10.42.0.1: seq=1 ttl=64 time=0.315 ms
64 bytes from 10.42.0.1: seq=2 ttl=64 time=0.373 ms
^C
--- thinkpad.local ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.315/0.366/0.412 ms
root@wandboard-quad:~# scp chris@thinkpad.local:/scratch/working/wbquad/build-wbquad/morseapp.tar .
The authenticity of host 'thinkpad.local (10.42.0.1)' can't be established.
ECDSA key fingerprint is 7d:17:44:30:56:3f:6c:87:6d:ec:4b:94:8c:6f:b7:06.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'thinkpad.local,10.42.0.1' (ECDSA) to the list of known hosts.
chris@thinkpad.local's password:
morseapp.tar                                  100%   80KB  80.0KB/s   00:00
root@wandboard-quad:~# tar -xf morseapp.tar
root@wandboard-quad:~#

Note

If you see the error -sh: scp: not found then you forgot to add openssh to the image...

Preparing your IoT Device

Again, have a look at the slides (especially for the MinnowBoard Max and BeagleBone Black).

Lab setup: MinnowBoard Max, BeagleBone Black and WandBoard Quad

Lab setup: MinnowBoard Max, BeagleBone Black and WandBoard Quad

Parts list

Parts list

Parts list (not complete, have a look at the schematic) (Picture taken from the slides).

Parts

Parts

WandBoard: GPIO Layout

WandBoard: GPIO Layout

WandBoard: GPIO Layout (Picture taken from the slides).

Schematic: WandBoard Quad

Schematic: WandBoard Quad

Schematic: WandBoard Quad (Picture taken from the slides).

Device to Server and Back

Putting it all together

Using the sysfs interface

Use the sysfs interface to test your device’s GPIO port access.

Try to turn the LED on and off:

root@wandboard-quad:~# echo 91 > /sys/class/gpio/export
root@wandboard-quad:~# echo out > /sys/class/gpio/gpio91/direction
root@wandboard-quad:~# echo 0 > /sys/class/gpio/gpio91/value
root@wandboard-quad:~# echo 1 > /sys/class/gpio/gpio91/value
root@wandboard-quad:~# echo 1 > /sys/class/gpio/gpio91/value
root@wandboard-quad:~#

Read the button status:

root@wandboard-quad:~# echo 24 > /sys/class/gpio/export
root@wandboard-quad:~# echo in > /sys/class/gpio/gpio24/direction
root@wandboard-quad:~# cat /sys/class/gpio/gpio24/value
1
root@wandboard-quad:~# cat /sys/class/gpio/gpio24/value
0
root@wandboard-quad:~# cat /sys/class/gpio/gpio24/value
1
root@wandboard-quad:~#
Testing the device’s interface

Run the morseapp application to test the device’s interface:

root@wandboard-quad:~# ./morseapp
Welcome to morseapp!



Commands  bb:
  1. Configure
  2. Loopback
  3. Talk Morse
  4. Talk Text
  5. Talk to local Server
---------------------------
  6. Talk to Network Server
  7. Be  the Network Server
  8. Talk to Network Peer
---------------------------
  s. Test Server
  c. Test client
---------------------------
  q. Quit
Cmnd: 1
Hardware Device:
 > 1. No device
   2. Beaglebone Black
   3. Minnowboard Max
   4. Wandboard Quad
Simulated Device:
   5. Simulated device  (morsemod)
   6. Morsemod instance (0)
Remote Server:
   7. IP Address (localhost)
   m. Main Menu
Cmnd: 4
Hardware Device:
   1. No device
   2. Beaglebone Black
   3. Minnowboard Max
 > 4. Wandboard Quad
Simulated Device:
   5. Simulated device  (morsemod)
   6. Morsemod instance (0)
Remote Server:
   7. IP Address (localhost)
   m. Main Menu
Cmnd: m


Commands  bb:
  1. Configure
  2. Loopback
  3. Talk Morse
  4. Talk Text
  5. Talk to local Server
---------------------------
  6. Talk to Network Server
  7. Be  the Network Server
  8. Talk to Network Peer
---------------------------
  s. Test Server
  c. Test client
---------------------------
  q. Quit
Cmnd: 3


[ Talk Morse code ]

Type the '.' period key to toggle your 'key'
  * a 'dit' is about 1/2 seconds
  * a 'dah' is about 1 1/2 seconds (three 'dits')
  * a letter space is about 1/2 seconds
  * a word   space is about 1 1/2 seconds
Type '#' to quit

User: [ ] | Device: [*]

If you press the button on the breadboard you should see Device: [*] and and if you press . on your keyboard (User: [*]) the LED on the breadboard should light up.

../../../_images/IMG_3478_small.JPG ../../../_images/IMG_3479_small.JPG
Connect the morseapp to the server

Connect the morseapp to the server, send queries from your keypad, and observe the replies on your LED.

First start QEMU on the PC:

[chris@thinkpad build-qemux86]$ runqemu qemux86 nographic qemuparams="-serial telnet:localhost:2345,server -serial tcp:localhost:2346,server,nowait"

Connect to the console and start the morseapp server:

[chris@thinkpad build-qemux86]$ telnet localhost 2345
...
qemux86 login: root
root@qemux86:~# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 52:54:00:12:34:56
          inet addr:192.168.7.2  Bcast:192.168.7.255  Mask:255.255.255.0
          inet6 addr: fe80::5054:ff:fe12:3456/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:40 errors:0 dropped:0 overruns:0 frame:0
          TX packets:88 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:6029 (5.8 KiB)  TX bytes:14012 (13.6 KiB)

root@qemux86:~# modprobe morsemod
root@qemux86:~# morseapp
Welcome to morseapp!



Commands  bb:
  1. Configure
  2. Loopback
  3. Talk Morse
  4. Talk Text
  5. Talk to local Server
---------------------------
  6. Talk to Network Server
  7. Be  the Network Server
  8. Talk to Network Peer
---------------------------
  s. Test Server
  c. Test client
---------------------------
  q. Quit
Cmnd: 7


[ Server Mode Morse : Return Morse Server Strings to Client ]

Click '#' to exit

server: got connection from 192.168.7.1
  Client message ' ' =>
server: got connection from 192.168.7.1
  Client message ' ' =>
server: got connection from 192.168.7.1
  Client message 'e' => e
server: got connection from 192.168.7.1
  Client message ' ' =>
server: got connection from 192.168.7.1
  Client message 'd' => Thu
server: got connection from 192.168.7.1
  Client message ' ' =>
server: got connection from 192.168.7.1
  Client message 'f' => Altbeers
server: got connection from 192.168.7.1
  Client message ' ' =>

On your board try to ping the QEMU machine:

root@wandboard-quad:~# ping 192.168.7.2
PING 192.168.7.2 (192.168.7.2): 56 data bytes
64 bytes from 192.168.7.2: seq=0 ttl=63 time=9.974 ms
64 bytes from 192.168.7.2: seq=1 ttl=63 time=1.052 ms
64 bytes from 192.168.7.2: seq=2 ttl=63 time=1.126 ms
^C
--- 192.168.7.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.052/4.050/9.974 ms
root@wandboard-quad:~#  ifconfig
eth0      Link encap:Ethernet  HWaddr 00:10:00:00:00:33
          inet addr:10.42.0.91  Bcast:10.42.0.255  Mask:255.255.255.0
          inet6 addr: fe80::21f:7bff:feb4:1633/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:23 errors:0 dropped:0 overruns:0 frame:0
          TX packets:35 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:2860 (2.7 KiB)  TX bytes:6577 (6.4 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

root@wandboard-quad:~#

If it is not possible to ping the QEMU machine from your board then you have to change your network configuration.

Now connect to the morseapp server:

root@wandboard-quad:~# ./morseapp
Welcome to morseapp!



Commands  bb:
  1. Configure
  2. Loopback
  3. Talk Morse
  4. Talk Text
  5. Talk to local Server
---------------------------
  6. Talk to Network Server
  7. Be  the Network Server
  8. Talk to Network Peer
---------------------------
  s. Test Server
  c. Test client
---------------------------
  q. Quit
Cmnd: 1
Hardware Device:
 > 1. No device
   2. Beaglebone Black
   3. Minnowboard Max
   4. Wandboard Quad
Simulated Device:
   5. Simulated device  (morsemod)
   6. Morsemod instance (0)
Remote Server:
   7. IP Address (localhost)
   m. Main Menu
Cmnd: 4
Hardware Device:
   1. No device
   2. Beaglebone Black
   3. Minnowboard Max
 > 4. Wandboard Quad
Simulated Device:
   5. Simulated device  (morsemod)
   6. Morsemod instance (0)
Remote Server:
   7. IP Address (localhost)
   m. Main Menu
Cmnd: 7


[Click CR to accept, ESC to cancel]
Remote Server IP Address: 192.168.7.2

Hardware Device:
   1. No device
   2. Beaglebone Black
   3. Minnowboard Max
 > 4. Wandboard Quad
Simulated Device:
   5. Simulated device  (morsemod)
   6. Morsemod instance (0)
Remote Server:
   7. IP Address (192.168.7.2)
   m. Main Menu
Cmnd: m


Commands  bb:
  1. Configure
  2. Loopback
  3. Talk Morse
  4. Talk Text
  5. Talk to local Server
---------------------------
  6. Talk to Network Server
  7. Be  the Network Server
  8. Talk to Network Peer
---------------------------
  s. Test Server
  c. Test client
---------------------------
  q. Quit
Cmnd: 6


[ Client to Remote Server Mode : respond to device queries ]

Server commands are:
  'e' ('*')   : echo an 'e' ('*')
  'd' ('-**') : echo the day of the week ('mon' .. 'sun')
  't' ('-')   : echo the time ('hhmmss')
  'f' ('**-*'): echo a fortune place
  * use a space for word separation
Server prompt at device is 's' ('---')
Type '#' to quit

In:[  __________________] (     ) | Out: [____________________] ()

Now type morsecode queries with the button on the breadboard and you can observe the server replies on your LED.

In:[  e ________________] (-**  ) | Out: [e s_________________] ()
 Server 192.168.7.2:d => 'Thu'
In:[  e d ______________] (**-* ) | Out: [e sthu s____________] ()
 Server 192.168.7.2:f => 'Altbeers'
In:[  e d f ____________] (     ) | Out: [e sthu saltbeers s__] ( * *-* **+8)
Final Notes

Warning

Currently an OpenSSH server is running inside QEMU and on your board without the need to enter a password to login.

root@wandboard-quad:~# ssh 192.168.7.2
The authenticity of host '192.168.7.2 (192.168.7.2)' can't be established.
ECDSA key fingerprint is 71:d9:a4:49:ed:21:c1:70:3d:a0:f5:5a:71:4a:d7:20.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.7.2' (ECDSA) to the list of known hosts.
Last login: Thu Dec  4 18:02:25 2014 from 127.0.0.1
root@qemux86:~#

Probably you want to change this on a production system :D

Extra Exercises

Extra Credit Exercises 1

Extra Credit Exercises 1 (Picture taken from the slides).

Extra Credit Exercises 2

Extra Credit Exercises 2 (Picture taken from the slides).

Extra Credit Exercises 3

Extra Credit Exercises 3 (Picture taken from the slides).