Building a real-time kernel for the Nvidia Jetson TK1

NVIDIA Jetson TK1 development kit

NVIDIA Jetson TK1 development kit

Patching the kernel L4T kernel

Get the kernel source

[chris@thinkpad Tegra]$ wget
[chris@thinkpad Tegra]$ tar -xf kernel_src.tbz2
[chris@thinkpad Tegra]$ head kernel/Makefile

# To see a list of typical targets execute "make help"
# More info can be located in ./README
# Comments in this file are targeted only to the developer, do not
[chris@thinkpad Tegra]$

Get the PREEMPT_RT patch

[chris@thinkpad Tegra]$ wget
[chris@thinkpad Tegra]$ wget
[chris@thinkpad Tegra]$

Commit everything to git

[chris@thinkpad Tegra]$ gunzip patch-3.10.*
[chris@thinkpad Tegra]$ cd kernel
[chris@thinkpad kernel]$ git init
[chris@thinkpad kernel]$ git add .
[chris@thinkpad kernel]$ git commit -m "Added 3.10.40 L4T kernel source"
[chris@thinkpad kernel]$ cp ../patch-3.10.* .
[chris@thinkpad kernel]$ git add -f patch-3.10.*
[chris@thinkpad kernel]$ git commit -m"Added RT patch files"
[chris@thinkpad kernel]$

Apply the patch

With the stock kernel from it’s quite easy to build a real time kernel, the patch will apply cleanly and normally you won’t encounter any build errors or stability issues. But the L4T kernel source has quite some modifications:

[chris@thinkpad TK1]$ wget
[chris@thinkpad TK1]$ tar -xf linux-3.10.40.tar.xz
[chris@thinkpad TK1]$ tar -xf kernel_src.tbz2
[chris@thinkpad TK1]$ git diff --dirstat linux-3.10.40 kernel
   3.2% kernel/arch/arm/boot/dts/tegra124-platforms/
  15.4% kernel/arch/arm/mach-tegra/
   3.1% kernel/arch/
   3.5% kernel/drivers/gpu/nvgpu/gk20a/
   3.9% kernel/drivers/input/
   4.4% kernel/drivers/media/platform/tegra/
   3.1% kernel/drivers/misc/
   3.7% kernel/drivers/net/wireless/bcmdhd/include/
   6.4% kernel/drivers/net/wireless/bcmdhd/
   6.7% kernel/drivers/net/wireless/sd8897/mlan/
   5.2% kernel/drivers/net/wireless/sd8897/mlinux/
   3.2% kernel/drivers/video/tegra/dc/
   3.2% kernel/drivers/video/
  18.8% kernel/drivers/
   4.0% kernel/include/
   4.3% kernel/sound/soc/codecs/
   3.1% kernel/sound/soc/
   3.6% kernel/
[chris@thinkpad TK1]$

So it won’t be that easy and we will have some more work.


Debugging the Linux kernel via JTAG on the NVIDIA Jetson TK1 / Jetson Pro DevKit

NVIDIA Jetson TK1 development kit

NVIDIA Jetson TK1 development kit

While it might not be possible to debug the Tegra K1 SOC in those development kits using cheaper debugging hardware or OpenOCD, it is possible using a TRACE32-ICD (In-Circuit Debugger) and the TRACE32-PowerView software from Lauterbach.

The Hardeware

I’m using a LA-7708 DEBUG-USB2 along with a LA-7843 JTAG CORTEX-A/R adapter connected to either the Jetson TK1 or Jetson Pro development kit.

LA-7708 DEBUG-USB2 connected to Jetson TK1

LA-7708 DEBUG-USB2 connected to Jetson TK1


Building the Yocto GENIVI Baseline

Yocto GENIVI Baseline inside QEMU

Yocto GENIVI Baseline inside QEMU

About the Yocto GENIVI Baseline

Yocto Project:

The Yocto Project is a Linux Foundation workgroup whose goal is to produce tools and processes that will enable the creation of Linux distributions for embedded software.


GENIVI Alliance:

The GENIVI Alliance is a non-profit automotive industry alliance committed to driving the broad adoption of an In-Vehicle Infotainment (IVI) open-source development platform. The GENIVI Alliance was founded on March 2, 2009 by BMW Group, Delphi, GM, Intel, Magneti-Marelli, PSA Peugeot Citroen, Visteon, and Wind River Systems.


The Yocto GENIVI Baseline is a GENIVI compliant reference system based on the Yocto Project.

Build a QEMU image that contains GENIVI components

Note: This will need around 27 GB of free hard disk space.


Recap: Yocto Project Developer Day - ELCE 2014

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


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


Getting started with the Papilio Pro and Xilinx ISE on Linux

Papilio Pro with LEDs and OV2640 camera module

Papilio Pro with LEDs and OV2640 camera module

My Papilio Pro arrived some days (weeks...) ago, let’s get started^^

First have a look at the Papilio Quick Start Guide:

Check that the Hardware is OK

If I get new hardware the first thing I always do is to check if its working properly. Sometimes you have to flash a basic Hello World example yourself but the Papilio Pro should have been flashed with a bitstream file already that:

  • Toggles all of the even numbered pins
  • Configures all of the odd number pins as inputs. When a odd number pin is asserted it will cause the even pin next to it to stop blinking and stay at 3.3V.
  • Sends the ASCII table at 9600 8N1 over the serial port in a continuous loop.

Lets check that, connect the Papilio via USB to your PC and use screen to open the serial port:

[chris@thinkpad ~]$ sudo screen /dev/ttyUSB1 9600
ASCII Table ~ Character Map
!, dec: 33, hex: 21, oct: 41, bin: 100001
", dec: 34, hex: 22, oct: 42, bin: 100010
#, dec: 35, hex: 23, oct: 43, bin: 100011
$, dec: 36, hex: 24, oct: 44, bin: 100100
%, dec: 37, hex: 25, oct: 45, bin: 100101
&, dec: 38, hex: 26, oct: 46, bin: 100110
', dec: 39, hex: 27, oct: 47, bin: 100111
(, dec: 40, hex: 28, oct: 50, bin: 101000
), dec: 41, hex: 29, oct: 51, bin: 101001
*, dec: 42, hex: 2A, oct: 52, bin: 101010
+, dec: 43, hex: 2B, oct: 53, bin: 101011
,, dec: 44, hex: 2C, oct: 54, bin: 101100
-, dec: 45, hex: 2D, oct: 55, bin: 101101
., dec: 46, hex: 2E, oct: 56, bin: 101110
/, dec: 47, hex: 2F, oct: 57, bin: 101111
0, dec: 48, hex: 30, oct: 60, bin: 110000
1, dec: 49, hex: 31, oct: 61, bin: 110001
2, dec: 50, hex: 32, oct: 62, bin: 110010
3, dec: 51, hex: 33, oct: 63, bin: 110011
4, dec: 52, hex: 34, oct: 64, bin: 110100
5, dec: 53, hex: 35, oct: 65, bin: 110101
6, dec: 54, hex: 36, oct: 66, bin: 110110
7, dec: 55, hex: 37, oct: 67, bin: 110111
8, dec: 56, hex: 38, oct: 70, bin: 111000
9, dec: 57, hex: 39, oct: 71, bin: 111001
:, dec: 58, hex: 3A, oct: 72, bin: 111010
;, dec: 59, hex: 3B, oct: 73, bin: 111011
<, dec: 60, hex: 3C, oct: 74, bin: 111100
=, dec: 61, hex: 3D, oct: 75, bin: 111101
>, dec: 62, hex: 3E, oct: 76, bin: 111110
?, dec: 63, hex: 3F, oct: 77, bin: 111111
@, dec: 64, hex: 40, oct: 100, bin: 1000000
A, dec: 65, hex: 41, oct: 101, bin: 1000001
B, dec: 66, hex: 42, oct: 102, bin: 1000010
C, dec: 67, hex: 43, oct: 103, bin: 1000011
Really kill this window [y/n]
[screen is terminating]
[chris@thinkpad ~]$

So this looks good, now the pins, you can easily check this if you connect an LED with a series resistor to 5V and PIN14 like seen in the tittle image. Then the LED should blink. Yippee!


Installing Xilinx ISE inside a Docker Container

Installing Xilinx ISE WebPACK inside a Docker Container

Installing Xilinx ISE WebPACK inside a Docker Container

Xilinx ISE WebPACK is a proprietary IDE that can be used for synthesis and analysis of VHDL designs.

This is a follow-up post from Sandboxing proprietary applications with Docker, so you might want to read this first.


ISE WebPACK can be downloaded at no charge from the URL below after you have signed up on the Xilinx website.

I have chosen to download ISE Design Suite - 14.7 Full Product Installation, Full Installer for Linux (TAR/GZIP - 6.09 GB). It’s quite a huge file so its a good idea to use some download manager like wget.


Instead of installing it directly on your host system we will install it into a Docker container that we have already prepared in the previous post.

To launch it just use the dockapp script with the -u option to make sure that the container has no network access:

[chris@thinkpad ~]$ dockapp run -u
[chris@thinkpad ~]$ dockapp view
Docker container without network access

Docker container without network access

The dockapp script will mount /home/$USER/share/docker/ automatically as /share inside the docker container so that we can easily access the installation tarball Xilinx_ISE_DS_Lin_14.7_1015_1.tar:

root@58f422d5ae63:/# ls -l share/
total 6385388
-rw-rw-r--. 1 app  app           5 Sep  4 15:40 Text File
-rw-------. 1 app  app  6538618880 Oct 18  2013 Xilinx_ISE_DS_Lin_14.7_1015_1.tar
-rwxrwxr-x. 1 app  app        1405 Sep  9 15:05 dockapp-start
-rw-r--r--. 1 root root          5 Sep  7 14:19 test.txt

Now we have two possibilities, install Xilinx ISE as root:

  • The setup will make changes to the root file system and we should commit them to a new Docker image, see here how this works.
  • The setup will be able to install Xilinx cable drivers

or install it it as unprivileged user:

  • From a security standpoint it should not make a huge difference since everything is running inside a container (at least in the future):

    Recent improvements in Linux namespaces will soon allow to run full-featured containers without root privileges, thanks to the new user namespace. This is covered in detail here. Moreover, this will solve the problem caused by sharing filesystems between host and guest, since the user namespace allows users within containers (including the root user) to be mapped to other users in the host system.

  • Installing Xilinx cable drivers will fail, but probably I don’t need them and you can install them later or rerun the setup.

I will start with installing it as unprivileged user app:

root@58f422d5ae63:/# su app
app@58f422d5ae63:/$ cd share/
app@58f422d5ae63:/share$ tar -xf Xilinx_ISE_DS_Lin_14.7_1015_1.tar
app@58f422d5ae63:/share$ cd Xilinx_ISE_DS_Lin_14.7_1015_1
app@58f422d5ae63:/share/Xilinx_ISE_DS_Lin_14.7_1015_1$ ./xsetup
Xilinx Setup inside a Docker container

Xilinx Setup inside a Docker container

It’s not possible to disable Xilinx’s WebTalk feature during installation... But luckily for us we have already disabled the network connection for the Docker container^^

Enables WebTalk to send software, IP and device usage statistics to Xilinx. For more information on WebTalk, please see Section 13 of the Xilinx End-User License Agreement and the WebTalk FAQ at:


Sandboxing proprietary applications with Docker


Docker is an open-source project that automates the deployment of applications inside software containers, providing that way an additional layer of abstraction and automatization of operating system-level virtualization on Linux. Docker uses resource isolation features of the Linux kernel such as cgroups and kernel namespaces to allow independent “containers” to run within a single Linux instance, avoiding the overhead of starting virtual machines.

Getting Started

The Docker documentations is very good, so this is where you should start:

Installing Docker

Just follow the guide for your Linux distribution:

On Fedora it looks like this:

[chris@thinkpad ~]$ sudo yum -y install docker-io
[chris@thinkpad ~]$ sudo systemctl start docker
[chris@thinkpad ~]$ sudo systemctl enable docker
[chris@thinkpad ~]$ sudo usermod -a -G docker chris # to run docker without sudo


To securely use USB devices inside Docker containers we need at least Docker 1.2.0. Since Fedora 20 is still shipping Docker 1.1.2 we have to enable the updates-testing repository while installing docker:

[chris@thinkpad ~]$ sudo yum --enablerepo=updates-testing install docker-io

User Guide

Now follow the user guide to get a bit familiar with the basics of Docker:

Docker Security

Some notes about Docker security:

Docker supports a so called “privileged” mode that was previously necessary to access USB devices for example (docker run -t -i -privileged -v /dev/bus/usb:/dev/bus/usb ubuntu bash). But this mode is really unsafe and should not longer be used. The Docker 1.2 release introduced two new flags for docker run --cap-add and --cap-drop that give a more fine grain control over the capabilities of a particular container.

One of the (many!) features of Docker 0.6 is the new “privileged” mode for containers. It allows you to run some containers with (almost) all the capabilities of their host machine, regarding kernel features and device access. [...] Note, however, that there are serious security implications there: since the private Docker instances run in privileged mode, they can easily escalate to the host, and you probably don’t want this!

Dockerizing your Application

The Interactive Approach


Start a new Docker container with Ubuntu 14.04, the first time you start it it will download the Ubuntu 14.04 base image (213 MB) automatically:

[chris@thinkpad ~]$ docker run ubuntu:14.04 /bin/echo 'Hello world'



[chris@thinkpad ~]$ docker run -i -t fedora /bin/bash
[chris@thinkpad ~]$ docker run -i -t fedora:20 /bin/bash

Let’s see what we can do with that image (

[chris@thinkpad ~]$ docker run -it ubuntu:14.04 /bin/bash
root@65a77c4901b3:/# echo "test"> test.txt
root@65a77c4901b3:/# cat test.txt
root@65a77c4901b3:/# exit
[chris@thinkpad ~]$ docker run -it ubuntu:14.04 /bin/bash
root@c688e3146470:/# cat test.txt
cat: test.txt: No such file or directory

As seen above, if we change something and start the image again a new container will be created and all changes are gone, but nothing is lost as we can restart old containers (

The command docker ps shows all our running containers:

[chris@thinkpad ~]$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED
c688e3146470        ubuntu:14.04        "/bin/bash"         About a minute ago

STATUS              PORTS               NAMES
Up About a minute                       drunk_torvalds
[chris@thinkpad ~]$

Whereas docker ps -a lists all containers:

[chris@thinkpad ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED
c688e3146470        ubuntu:14.04        "/bin/bash"         4 minutes ago
65a77c4901b3        ubuntu:14.04        "/bin/bash"         5 minutes ago

STATUS                     PORTS               NAMES
Up 4 minutes                                   drunk_torvalds
Exited (0) 4 minutes ago                       stupefied_mestorf
[chris@thinkpad ~]$

We can use the name of the old container (stupefied_mestorf) to start it again and reattach:

[chris@thinkpad ~]$ docker start stupefied_mestorf
[chris@thinkpad ~]$ docker attach stupefied_mestorf
root@65a77c4901b3:/# cat test.txt

Short form (with container ID or container name):

[chris@thinkpad ~]$ docker start -ai 65a77c4901b3
root@65a77c4901b3:/# cat test.txt


Let’s be paranoid and secure our penguins


The goal of this article is to give a short overview of practical solutions to run untrusted proprietary applications under Linux while limiting the damage that they can do and to prevent possible privacy exploits.

There is a interesting section in the Arch Linux Wiki about Securing Skype that got me thinking about it:

There are a couple of reasons you might want to restrict Skype’s access to your computer: The skype binary is disguised against decompiling, so nobody is (still) able to reproduce what it really does and it produces encrypted traffic even when you are not actively using Skype.

Trust the Vendor

Just assume the software has no security flaws, no remote exploitable bugs, AutoUpdate uses a secure HTTPS connection and checks the certificates, that it does not gather usage statistics or send crash reports that may contain sensitive information...

[chris@thinkpad ~]$ sudo ./proprietary_crap.bin

Pros: No additional work needed

Cons: No protection, the software may break your system, or worse

Comment: It just feels not right, I want a clean system without programs where I don’t know what they are doing in the background.

Different User Account

So this is probably the easiest solution, just add a new user account.


  • Easy to set up

    [chris@thinkpad ~]$ sudo useradd evil
    [chris@thinkpad ~]$ sudo passwd evil
    Changing password for user evil.
    New password:
    Retype new password:
    passwd: all authentication tokens updated successfully.
    [evil@thinkpad ~]$
  • Easy to use “su - special_user”

    [chris@thinkpad ~]$ su - evil
    [evil@thinkpad ~]$ ps -Af|grep chris |tail -n1
    chris    22265     1  0 02:04 ?        00:00:17 okular /var/tmp/sandboxing-notes.pdf --icon okular -caption Okular
    [evil@thinkpad ~]$ ls /home/chris/.gnupg/
    ls: cannot access /home/chris/.gnupg/: Permission denied
    [evil@thinkpad ~]$
  • No extra work needed to start X11 applications

    [evil@thinkpad ~]$ firefox &
    [1] 7628
    [evil@thinkpad ~]$


  • Full network access, using iptables to restrict network access for a single user way too complex and thus prone to security lapses

  • Running on the same X server

    Any application that has access to the X server can do a lot of things. It can snoop on other applications that display windows on the same server. It can log key presses. It can rebind keys. It can inject key presses into other applications. It has access to the clipboard. –

  • See the full process list with command arguments “ps -Af” and more...

  • What about SUID binaries?


  • The user evil should not be allowed to use sudo.
  • At least it protects your files in your home directory a little bit.


Review: Saleae Logic16 Logic Analyzer

My newest toy is a sixteen channel Saleae logic analyzer:

../../../_images/saleae_logic16_1_small.jpg ../../../_images/saleae_logic16_2_small.jpg ../../../_images/saleae_logic16_3_small.jpg

The Saleae Logic16 is one of the very few cross platform logic analyzers available, with application software that runs under Linux, Windows, and on the Mac.

Below you will find my first impressions, if you would like to know something more specific then ask in the comments or have a look at the Saleae homepage.


It works with logic levels between 1.8V and 5V, you either select 1.8V to 3.6V or 3.6 to 5.0V from the menu. The lower voltage settings should work in most circumstances. The 5V setting is provided to reduce the likelihood of channel to channel crosstalk when using 5V signals.

The inputs are protected against overvoltage (high DC impedance, low-capacitance diode clamps) and a resettable fuse protects the USB ground return line.

It can sample 2 channels at 100MHz, 4 channels at 50MHz, 8 channels at 25MHz or all 16 channels at 12.5MHz and can record up to 10 billion samples.

The aluminum case looks high-end and the carrying case is really nice and handy.

I haven’t opened the device and don’t know what’s inside, I would guess some kind of FPGA but that’s all I can tell at the moment. (Update: a very nice review on YouTube:


The software is cross platform and works on Linux, Windows, & Mac. There is also an SDK available for writing your own analyzer plugins in c++ and a device API, which provides low-level access to the logic analyzer.


  • Download the Logic 1.1.15 (64-bit).zip from or the beta version from
  • Extract it somewhere
  • And run the install_driver script, which only copies the udev rules file 99-SaleaeLogic.rules to /etc/udev/rules.d/99-SaleaeLogic.rules


  • Supported Protocols: asynchronous serial, I2C, SPI, CAN, 1-Wire, UNI/O, I2S/PCM, MP Mode 9-bit Serial (i.e. Multidrop and Multiprocessor mod), Manchester, DMX-512, Parallel, JTAG*, LIN*, Atmel SWI*, MDIO*, BiSS C*, PS/2 Keyboard/Mouse*, HDLC*, HMDI CEC*, and USB 1.1*. (* currently in beta)
  • Measure pulse wide and period and calculate frequency
  • Measurement cursors
  • Export data in different formats
  • ...

Some experiments

Generally a logic analyzer has the advantage (compared to using another micro controller, what I’ve done until now), that you can not only see the decoded data, but also the timings and that you can analyze unspecified protocols. A logic analyzer has also mush more channels than an oscilloscope and can capture a large amount of digital data.

Async serial

Recently I bought some cheap FT232RL USB to TTL serial adapters from eBay that work with 3.3V and 5V logic levels.

After adding a serial decoder and specifying which channel should be decoded I can see the decoded characters right above the signal:

Saleae Logic16: Decoding "Test\r\n"

Saleae Logic16: Decoding “Test\r\n”


Arch Linux ARM: Network tools missing



The newest Arch Linux ARM image for the OLinuXino ( ships without the tools needed to configure a wireless connection.


Other people are experiencing the same problem, why remove such fundamental tools, and the hint pacman -S wireless_tools is not very helpful if you have no internet connection.

So how should I install additional tools if can’t setup an internet connection.

Let’s try to download them on another PC, copy them to the SD card and then install them on the OLinuXino.