Bsquask

Bsquask

The blog of Andy Nichols (nezticle)

The Bsquask Branch

You may have noticed that there are 2 branches published in RaspberryPi-Buildroot. The reason for this is that the master branch is intended to be the minimum set of changes to stock BuildRoot that others can fork for their own projects. The bsquask branch is where I keep my customized BuildRoot based Linux environment.

Features Implemented

I’ve implemented some neat things in the bsquask branch so far (some of which will get ported to master if it makes sense)

Upstart

Rather than using sysinitv or systemd for the system init process (which is the only process started by the Linux kernel and is the parent of all other processes), I’ve chosen to use Upstart. Upstart is event driven, so services are started in terms of what events occur. By converting packages sysinitv style service files to upstart style, I was able to reduce boot times to a console to just 3 seconds. It’s also much easier to write upstart services than it is to write new sysinitv ones.

Linux kernel 3.6.11

As of December 27th, 2012, the stable Raspberry Pi kernel is 3.6.11. I hope to soon pull this into the master branch as well.

VideoCore with CMA enabled

With the firmware that corresponds to the 3.6.11 kernel update, we now have the possibility of using a contiguous memory allocator to eliminate the need to set a boot-time split between GPU memory and system RAM. Now what should happen is that each should only reserve a minimum, and then request more from each other when necessary. So if you are running an OpenGL application that needs a lot GPU memory, then more memory is requested at runtime by the CMA from the memory pool.

CMA is enabled in the Bsquask branch, but should be probably still be considered experimental.

XBox and Wiimote support

The demos that I write for the Raspberry Pi generally use game console controllers so I’ve built in support for XPad and XWiimote in the the kernel, and have added the user-space libraries to use them. This includes a custom Qt 5 module I wrote to make using them from Qt 5 easier, as well as a bluetooth daemon and utilities to sync wiimotes.

Features Planned

These are the projects I’m currently working on for the Bsquask branch

Splash screen

Since Qt 5 can paint directly to the console framebuffer, it’s possible to implement dynamic splash screens using Qt 5, QtQuick, and OpenGL. By listening for Upstart events, its also possible to display the progress of the boot if you wanted. The splash screen application is started by just adding an Upstart service file. I have a prototype of this working now, but it really doesn’t make sense to have a splash screen when booting only takes 3 seconds.

Wayland Compositor

Right now we still boot up to a command prompt. I tend to disable this and boot strait to a single demo application, but what I plan to do is implement a Wayland compositor using QtWayland which the system will boot into. This will launch into a simple interface with an application launcher, and application switcher. That way you will be able to run and switch between multiple applications. I have prototype of this will will be releasing soon on GitHub.

Remove Busybox

I intend to remove Busybox and install the actual util-linux packages. We have the luxury of lots of system resources with the Raspberry Pi, no need to limit ourself to using Busybox. I am currently experimenting with configurations for this.

Diference From Upstream BuildRoot

Today I am working on updating the Bsquask SDK to BuildRoot 2012.11 from the previous 2012.08 release. In the process I thought it would be nice to review all of the changes that have been made to the Bsquask SDK’s master branch.

Here is the whole 4000 line diff in case you are interested in every detail. The majority of the diff consists of the Linux kernel configuration, and the BusyBox configuration.

Breakdown of the diff:

A README file that documents how to use the Bsquask SDK

A custom busybox-1.20.2 configuration, which disables the busybox init integration from being built (since we default to using and building sysinitv)

A custom linux-3.2 configuration, which is a copy of the RaspberryPi defconfig with alsa and xpad modules built into the kernel.

A service file for ntpdate, which is needed because the stock Raspberry Pi does not come with a real time clock, and thus we need to set the current time from an external source

An inittab file that specifies what to mount, what services to start, and how many tty consoles to start.

An interfaces file defining the default behavior for the Ethernet port on the Raspberry Pi is to try and acquire an IP address using DHCP.

A script that should be run after all packages are generated that sets the root password, sets the default shell to bash, packages the boot partition, and installs the custom ntpdate service, inittab, and interface files mentioned above.

A BuildRoot defconfig for building for the Raspberry Pi. This sets up a minimal environment to cross compile and run Qt 5 applications without X11. This includes the custom packages necessary for the Raspberry Pi (bootloader, VideoCore, custom Linux kernel)

Bootloader

The bootloader files for the Raspberry Pi are distributed in binary blobs provided in the Raspberry Pi firmware repository. This repository can take a significant time to clone, so I’ve opted for packaging the necessary files for use with the script, in the interest of speeding up build times for the Bsquask SDK.

Kernel

The RaspberryPi does have source code available to build the Linux kernel, so we do. There are patches that have not been accepted into the upstream Linux kernel, so the kernel sources are provided here. Cloning this git repository locally can take nearly the same amount of time to build every other package in the Bsquask SDK, so I also package snapshots of the Raspberry Pi Linux kernel source code into a tar.gz and host it.

VideoCore

Right now the VidoeCore files are packaged using the pre-built hard-float version provided in the firmware repository. It is possible to build these files locally now, and I have an unreleased BuildRoot recipe I’m still testing to replace the current one. Right now these files are hosted by me as well for the same reason given above.

OMXPlayer

OMXPlayer is build because it’s nice for demoing the multimedia capabilities of the Raspberry Pi. With this player you can play 1080p h.264 videos on the Raspberry Pi without breaking a sweat.

Wayland

I package Wayland because I need it for QtWayland, and I intend to use this as part of lightweight window compositor in place of an X11 server.

Qt5 Packages

The Bsquask SDK was developed so that I could run Qt5 applications on the Raspberry Pi with the minimal base required to enable all features. Most Qt 5 modules should be packaged now, but only the basic ones are enabled by default (as these work the best on the Raspberry Pi).

Toolchain

Probably the most controversial and troublesome thing, I define and provide a custom toolchain for building for the Raspberry Pi. The problem was that the intended target is ARMv6 hard-float, and most pre-build toolchains are configured for either building ARMv5tel soft-float, or ARMv7 hard-float. That leaves us stuck in the middle with a toolchains that won’t work right for us. The toolchain I provide was generated with crosstool-NG.

Bsquask SDK

If you’re visiting this page, it likely that you are familiar with my project RaspberryPi-Buildroot (aka the Bsquask SDK). If not then, the please check it out!

The objective of this project is to provide an SDK and root file system for the Raspberry Pi that is lightweight and takes full advantage of the hardware available. The resulting image produced is small Linux distribution known as Bsquask.

The Bsquask SDK provides a GCC 4.6.3 toolchain for building armv6 binaries with the hard-float ABI, as well as bootloaders, kernel image, rootfs, and development sysroot for the Raspberry Pi.

I created the Bsquask SDK because I needed an easy way to work with Qt 5 on the Raspberry Pi. In general when you are working with an embedded device, you need 3 things: a toolchain, a sysroot, and a system image.

Toolchains

When I first started working with the Raspberry Pi in May of 2012, I began a search for a Linux distribution that I could base my Qt 5 development work on top of. I use Ubuntu Linux as my host OS, so I’m most comfortable with Debian based distributions. So naturally I was interested in the Raspbian project. It was then that I was surprised to learn that to build the Raspbian distribution they were using i.MX53’s to build packages natively for armv6 hard-float. They use rigs that looks sort of like this:
buildfarm
The crazy thing though is that it took months to build the base Debian packages. Thats right months! On my Quad-core desktop it can take between 20-60 minutes to build Qt 5 (depending on which modules I build), so I can only imagine how long that would take doing native builds.

Just say no to native builds!

The correct way to develop for embedded devices is cross compilation. That is having a toolchain that is a native binary for your host machine (x86_64 Ubuntu 12.04 in my case), and generates binaries for your device (armv6hf Raspberry Pi). This means that builds for your device take roughly the same time as they do for your desktop. So rather than taking a month to build a base Linux OS, which you may need to rebuild if you want to change a base-layer package, you bring the time scale back down into the order of minutes. In the case of the Bsquask SDK, we cross compile every dependency of the base OS and that takes between 1-2 hours.

For the Bsquask SDK, I actually generated the toolchain using crosstool-NG

Sysroot

When you are developing middle-ware for an embedded device having a complete sysroot is very important. The sysroot contains all of the development files needed to build software for a given OS image running on your device. So this includes the development headers for libraries, and the cross-compiled libraries to link against. For the Bsquask SDK I chose to use BuildRoot to generate the sysroot and image.
buildroot
The way this works is that I define a recipe on how to cross compile an entire image for a given device. BuildRoot downloads the source code of each package, compiles it using our toolchain, then installs the resulting binaries, headers, libraries into a sysroot. The recipe also specifies which files from each project need to go into the image that we will deploy to the device. So on the device we have limited space, and no need for the development header files, so we do not copy those to the device target folder. When we build the entire system specified in the recipe, and a kernel, these are then compressed to tar.gz files that become the system image.

Images

So what we get in the end is two tar.gz files that we can extract to the two partitions of a Raspberry Pi compatible SD card. You boot up the Raspberry Pi with this SD card, and now you have a device that you can easily build new software for. In the case of the Bsquask SDK you just boot up to a login prompt (no X11). The recipe builds the minimum packages necessary to use all the functionality of Qt 5, which should fulfill all of your embedded device middle-ware needs (and if it doesn’t thats something I should know about).

Conclusion

The Raspberry Pi is an awesome device, and a blank slate for many developers creativity. In general embedded Linux development is difficult, but by combining the Raspberry Pi ease of use (just throw all files on the SD card), and the complete development environment provided by the Bsquask SDK, you are only limited now by your imagination. So check out the Bsquask SDK and if you run into any problems, just drop me an email or file a Github issue.