Use these recipes as a complement to Beyond Linux From Scratch to expand your system.

1 The PiLFS Bootscripts

The PiLFS Bootscripts tarball is a small collection of scripts and fixes from various sources that are specific to the Raspberry Pi. The following scripts can be installed:

This little fix tells the kernel to keep 8MB of RAM free at all times for incoming network traffic. Without this fix, it's easy to hang the Pi when doing a lot of work over SSH. All it does is add vm.min_free_kbytes=8192 to /etc/sysctl.conf.

The original LFS swap init script will try to enable swap space before the root file system is properly mounted. This won't work if you're using a swap file instead of a dedicated swap partition. This fix simply adjusts the timing of that init script.

The Pi doesn't have a way of keeping time between reboots. This script adds a save/restore function to set an approximate date until the exact date can be obtained via NTP.

Start/stop script for the Random Number Generator Daemon for use with the hardware RNG device present on the Pi.

Switches the cpufreq governor from the default "powersave" to "ondemand" which allows for overclocking the Pi.

2 Adding a Swap File

To create a swap file where count is the number of megabytes you'd like:

dd if=/dev/zero of=/swapfile bs=1M count=512
mkswap /swapfile
swapon -v /swapfile

To activate the swap file on boot, add a line to /etc/fstab

/swapfile     swap         swap     pri=1               0     0

3 Tapping the Pi Hardware Random Number Generator

The BCM2835 chip on the Pi contains a hardware entropy source that can be tapped by crypto-heavy applications to improve the quality of randomness and might even help speed up some operations.

You'll need to build rngd which in turn will feed applications with random goodness from the hardware RNG:

./configure --prefix=/usr
make install

make install-rngd from the PiLFS Bootscripts takes care of starting the daemon.

4 Overclocking the Pi

On September 19 2012 the Raspberry Pi Foundation introduced a Pi "turbo mode", which dynamically enables overclock and overvolt under the control of a cpufreq driver, without affecting your warranty.

The first step is to add a set of overclock values to your /boot/config.txt. These are the preset values offered by Raspbian's raspi-config:

Variable No OC Modest Medium High Turbo
arm_freq 700 800 900 950 1000
core_freq 250 250 250 250 500
sdram_freq 400 400 450 450 600
over_voltage 0 0 2 6 6

The final step is to switch the cpufreq governor from the default "powersave" to "ondemand" with this command:

echo "ondemand" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

make install-switch-cpu-governor from the PiLFS Bootscripts takes care of this step for you on boot.

You can keep an eye on the current frequency and temperature with these commands:

cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
/opt/vc/bin/vcgencmd measure_temp

5 Resizing Your ext4 Partition

When you write an image to your SD card, you'll usually want to resize the data partition to fit the free space available on the card.

Start fdisk and press 'p' to print the partition table:

fdisk /dev/mmcblk0

Note the Start sector (98304 on the PiLFS Base image) of the Linux partition.

Now press 'd' and '2' to delete it.

Then press 'n', 'p', '2', the Start sector, 'enter' and 'w'.

This re-creates the ext4 partition with the maximum size available.

Finally, reboot your Pi, then perform the actual resize:

resize2fs /dev/mmcblk0p2

6 Optimized Memcpy/Memset Replacement

These ARM-accelerated versions of selected functions from string.h replace the default routines of the glibc library. To use them, grab a copy from this github repository:

wget -O arm-mem.tar.gz

Then we compile them into a shared library, put it in place and make sure it gets used as a replacement for glibc's functions, like so:

sed -i 's:CFLAGS +=* :&-fPIC :' Makefile
cp -v /usr/lib
echo "/usr/lib/" >> /etc/

7 Compiling the Kernel

First grab the latest kernel sources if you haven't got them already:


After unpacking, ensure the sources are in pristine condition:

make mrproper

Issue the following sed command if you want the kernel to appear exactly as the official one (with a 4.4.X+ version string):

sed -i 's/EXTRAVERSION =.*/EXTRAVERSION = +/' Makefile

Create a default kernel .config file for the Raspberry Pi:

make bcmrpi_defconfig

Or for the Raspberry Pi 2:

make bcm2709_defconfig

If you want you can customize the kernel configuration:

make menuconfig

Now we can build our kernel, then install the kernel modules:

make modules_install

Finally copy the compressed kernel to the boot partition:

cp -v arch/arm/boot/zImage /boot/kernel.img

Or for the Raspberry Pi 2:

cp -v arch/arm/boot/zImage /boot/kernel7.img

8 Compiling External Kernel Modules

What if you just want to compile a third-party kernel module compatible with the latest official Raspberry Pi kernel? In my case I wanted to compile the DirectFB Fusion module without having to build a complete kernel.

You'll still need the complete kernel sources so grab them first:


After unpacking, ensure the sources are in pristine condition:

make mrproper

Issue the following sed command so that your module ends up in the correct place (/lib/modules/4.4.X+):

sed -i 's/EXTRAVERSION =.*/EXTRAVERSION = +/' Makefile

Create a default kernel .config file for the Raspberry Pi:

make bcmrpi_defconfig

Or for the Raspberry Pi 2:

make bcm2709_defconfig

Now we need to grab an important file called Module.symvers from the Firmware repo and put that in the root of the source tree:


Or for the Raspberry Pi 2:


Next we issue a command that will compile all the little extra kernel bits and pieces that are necessary to build modules:

make modules_prepare

And the last step needed is a build symlink pointing to the kernel sources:

ln -sv $PWD /lib/modules/4.4.X+/build

There, you should now be able to compile your third-party kernel module. And don't forget that you need to refresh your modules.dep file before you modprobe your new module, like so:


9 Building the Userland Source

Now that Broadcom has open sourced the ARM userland libraries, we can replace the contents of /opt/vc from the firmware repo with our own build.

You will need to have cmake installed to perform the build.

Let's start with obtaining the userland sources:

wget -O userland.tar.gz

And now we build and install (you might want to rename/backup your current /opt/vc before installing):

mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make install

You should build the included hello_pi examples to verify that your new libraries are working properly:

cd /opt/vc/src/hello_pi
chmod +x

Note that the hello_font example requires FreeType to build.

10 Building With QEMU User Mode Emulation

QEMU has two operating modes, User mode and System mode emulation. In user mode, only the ARM CPU is emulated and your real file system is used as storage. This is the fastest method but requires that you run a Linux system (real or virtual). To run under Windows/Mac, try the System Emulation.

The running kernel needs to have support for CONFIG_BINFMT_MISC and have /proc/sys/fs/binfmt_misc mounted:

mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
cat /proc/sys/fs/binfmt_misc/status

If it says enabled, you're good to go.

Next you'll want to create a directory to hold your chroot environment:

export LFS=/lfs
mkdir $LFS
cd $LFS

For Raspberry Pi:

tar xvf ch5-tools-rpi1-20160824.tar.xz

Or Raspberry Pi 2:

tar xvf ch5-tools-rpi2-20160824.tar.xz

Now we need to find ourselves a static qemu-arm binary. You could potentially compile your own but I'm just going to snatch it from Ubuntu :)

Grab the amd64 or i386 download, whichever suits your PC, and save it to a temp directory.

Extract the .deb file:

ar -vx qemu-user-static_2.3+dfsg-5ubuntu9_i386.deb
tar xvf data.tar.xz

Make a directory for the binary in your chroot and copy it over:

mkdir -pv $LFS/usr/bin
cp -v usr/bin/qemu-arm-static $LFS/usr/bin

We'll also need to make a wrapper binary that will call qemu-arm-static with the correct arguments to emulate the same CPU family and kernel version as that of a Raspberry Pi:

gcc -static qemu-arm-wrapper.c -s -o qemu-arm-wrapper
cp -v qemu-arm-wrapper $LFS/usr/bin

Or to emulate the Raspberry Pi 2:

gcc -static qemu-arm-wrapper-rpi2.c -s -o qemu-arm-wrapper
cp -v qemu-arm-wrapper $LFS/usr/bin

Now that we have our static QEMU binary and wrapper you may delete your temp directory.

Next comes the fun part! We are going to register a binfmt_misc handler for our ARM binaries. You can do this either on the command line or put it in a boot script:

echo ":arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm-wrapper:" > /proc/sys/fs/binfmt_misc/register

Feel free to read Documentation/binfmt_misc.txt in the Linux kernel source tree if you want to know what all that gibberish means :)

At this point you can check if everything will work correctly by trying to chroot into your /lfs directory:

chroot "$LFS" /tools/bin/env -i HOME=/root TERM="$TERM" PS1='\u:\w\$ ' PATH=/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin /tools/bin/bash --login +h

If you see a prompt that reads "I have no name!", everything is working correctly.

Now you can exit your chroot and start following the LFS book (and PiLFS guide) from 6.2. Preparing Virtual Kernel File Systems.

11 Building With QEMU System Emulation

What if you're stuck with Windows or Mac OS X and can't use the more elegant QEMU user mode emulation? Maybe you just prefer to prepare a complete SD card in a sandboxed virtual machine with limited access to your precious file system?

What we can do is emulate hardware very similar to the Raspberry Pi, running a similar kernel and the same LFS base system you would find on the SD card.

Disclaimer: Your emulated Pi will most likely be many times slower than a real Pi. It's probably faster to run QEMU user mode emulation in a virtual machine.

I have verified everything working in QEMU v2.4.0 on Yosemite built with the standard Homebrew formula.

Windows users should grab qemu-2.4.0-win32.tar.lzma.

You'll also need to download the virtual hard disk image and suitable QEMU Linux kernel.

Unzip disk and kernel to the same directory and try launching QEMU first with the simplest invocation (don't bother trying to add more -m memory, it doesn't work):

qemu-system-arm -M versatilepb -cpu arm1176 -m 256 -kernel pilfs-qemu-kernel.img -hda pilfs-qemudisk-20130401.img -append "root=/dev/sda2 rootfstype=ext4"

Now if we want to get fancy, we can skip that ugly QEMU window and redirect the login console to our terminal, like so:

qemu-system-arm -M versatilepb -cpu arm1176 -m 256 -kernel pilfs-qemu-kernel.img -hda pilfs-qemudisk-20130401.img -append "root=/dev/sda2 rootfstype=ext4 console=ttyAMA0" -nographic

Coolatious! I hear you exclaim, but how do I quit QEMU now? Press CTRL+A H for some helpful commands, CTRL+A X to quit.

For the fanciest of pants you can also SSH into the VM:

qemu-system-arm -M versatilepb -cpu arm1176 -m 256 -kernel pilfs-qemu-kernel.img -hda pilfs-qemudisk-20130401.img -append "root=/dev/sda2 rootfstype=ext4 console=ttyAMA0" -nographic -net nic -net user,hostfwd=::2222-:22
ssh root@localhost -p 2222

What hardware is emulated exactly?

  • ARM Versatile Platform Baseboard
  • ARM1176 Core (ARMv6 with VFP hard floats)
  • SYM53C8XX SCSI Controller
  • SMC91C111 Ethernet Adapter
  • ARM PrimeCell PL110 Color LCD Controller
  • AMBA PrimeCell PL011 UART
  • AMBA KMI Keyboard Controller

What if I want to build my own kernel for QEMU?

You can grab the kernel .config I used as a reference.

You will also need to apply this patch to add ARMv6 support to the Versatile board.

12 Building OMXPlayer

First install the following prerequisites (in order):

Download the latest OMXPlayer source from the github repo:

wget -O omxplayer.tar.gz

Since we're not cross-compiling, we need to massage the Makefile for our purposes:

sed -i '/include Makefile.include/d' Makefile
sed -i 's:INCLUDES+=*:&-I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -I/usr/include/freetype2 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include :' Makefile
sed -i 's:LDFLAGS+=*:&-L/opt/vc/lib :' Makefile
sed -i 's/$(STRIP)/strip/' Makefile
sed -i '/cp -a ffmpeg_compiled/d' Makefile

Now we can build and copy the binary somewhere nice:

cp -v omxplayer.bin /usr/bin/omxplayer
cp -v omxplayer.1 /usr/share/man/man1

OMXPlayer comes with a free font to be used for subtitles, put it where OMXPlayer expects it to be:

mkdir -p /usr/share/fonts/truetype/freefont
cp -v fonts/FreeSans* /usr/share/fonts/truetype/freefont

Sometimes the background console shines through while playing a video, or equally annoying, stays black after playing a video. This can be fixed with the fbset utility and a simple wrapper function in your ~/.profile:

function omxplay() { omxplayer -r -t1 "$@" ; fbset -depth 8 && fbset -depth 16 ;}

13 Adding yt - The YouTube Console Client

yt is a command-line front-end to YouTube which allows you to browse YouTube videos and play them directly from the command-line. It uses youtube-dl and OMXPlayer to actually play the videos. The combination of a text based interface and OMXPlayer makes yt a great YouTube client for the Raspberry Pi.

First you need to install OMXPlayer, obviously.

Next, add the youtube-dl video grabber:

wget -O /usr/bin/youtube-dl
chmod +x /usr/bin/youtube-dl

Then we need to add the Python Setuptools installer system:

wget -O - | python

Now we have all the required components, so we can grab and install yt:

wget -O yt.tar.gz
python install
easy_install --upgrade whitey

Type "yt --player omxplayer" to start the client, have fun!

14 Building Quake3

First install the following prerequisites (in order):

Next we need to compile OpenAL using this CMake build procedure:

cd build
make install

Let's fetch the Quake3 source:

wget -O quake3.tar.gz

Now we can start the build:


Now you just have to decide where to install your Quake3 binaries, I chose /root/quake3 here:

cp -rv build/release-linux-arm ~/quake3

And the final step is to copy the pak#.pk3 files from the original Quake3 CD:

cp -v pak{0..8}.pk3 ~/quake3/baseq3

Start the game with ~/quake3/ioquake3.arm - Happy fragging!

15 Building Accelerated SDL + DGen Genesis Emulator

With all the fun software out there depending on the SDL multimedia library, wouldn't it be nice if SDL could take better advantage of the Pi's GPU?

Vanfanel thought so too and wrote a Dispmanx backend for SDL, which takes a small resolution (320x240) output from any SDL application and hardware-scales it to your monitor's native fullscreen resolution (like 1920x1080).

I tried it with DGen and really enjoyed watching Sonic frolic about in 1080p at 60FPS (with a bit of overclock) - smooth as silk!

Building SDL:

For SDL, the only prerequisites are ALSA-lib and ALSA-utils (to be able to adjust the volume with alsamixer). Let's build!

wget -O SDL12-dispmanx.tar.gz
sed -i 's:DISPMANX_INCLUDES="*:&-I/opt/vc/include/interface/vmcs_host/linux :' configure
./configure --prefix=/usr --disable-static --enable-video-dispmanx --disable-video-kms --disable-video-fbcon --disable-video-x11 --disable-video-directfb
make install

That's all there is to it really, but you'll need to ensure that your SDL application outputs to a small (320x240) plain resolution without any fancy scaling effects etc. so that when you start the application you should see something like this:

dispmanx: Opening display[0]...
Using internal program mode: width=320 height=240
Using physical mode: 1920 x 1080 16 bpp

Building DGen:

Now let's build DGen so we have something to play with (apparently, the largest HQX scaler doesn't compile on the Pi. You can either cross-compile it or live without it for now):

./configure --prefix=/usr --disable-hqx
make install

So, to get DGen to output in 320x240 you can either specify -S 1 on the command line, or put int_scale = 1 in your ~/.dgen/dgenrc.

Also, adding bool_screen_thread = yes to your ~/.dgen/dgenrc should give you better graphics performance on the Pi!

16 Building RetroArch Emulators

RetroArch is like an emulator framework to which you add one or more game system cores.

You need the following prerequisites to build RetroArch:

Grab the latest sources:

wget -O retroarch.tar.gz

Then configure and install. Add --enable-neon if compiling for Raspberry Pi 2.

./configure --prefix=/usr
make install
cp -v tools/retroarch-joyconfig /usr/bin

Next you might want to setup a joypad:


Paste the resulting output anywhere in /etc/retroarch.cfg or ~/.config/retroarch/retroarch.cfg. You can optionally bind a button to input_exit_emulator_btn to quit the emulator with the joypad. I also like to bind input_menu_toggle_btn to the joypad so that I can change games through a nifty menu system without having to exit RetroArch.

Now you'll want to grab one or more emulator cores, most of them can be found in the libretro github. Here's a list of some nice ones:

Game System Git Repository
Genesis / SMS / GG
Final Burn Alpha
Game Boy / Color

Building a core is usually pretty straight forward, you either just type make or point out which Makefile to build. Here's an example for FCEU:

wget -O fceu.tar.gz
cd fceumm-code
make -f Makefile.libretro

For every compiled core you'll end up with a file called something. If we do find . -name '*' for FCEU we'll find You should copy this file somewhere in an organized fashion that makes sense to you, for example:

mkdir -p ~/retroarch/cores
cp -v ~/retroarch/cores

Next we'll want to add some info files. These are required for RetroArch to pick a suitable core automatically for any given ROM file.

git clone
cp -rv dist/info ~/retroarch

Now add the following directives to your ~/.config/retroarch/retroarch.cfg:

libretro_path = "~/retroarch/cores/" # Set this to any core
libretro_directory = "~/retroarch/cores"
libretro_info_path = "~/retroarch/info"
rgui_browser_directory = "~/retroarch/roms"

Time to try out the emulation! Just type retroarch followed by the ROM file name to start. You can also specify a specific core to load using the -L argument. Or type retroarch --menu to browse ROMs through the spiffy menu system.

17 Building Wayland / Weston

The GPU accelerated desktop on the Pi that we've all been waiting for is inching ever closer each day.

We have the DirectFB project making good progress, and we have the Wayland / Weston & QT5 camps making some really impressive headway. I'll personally be watching all these projects very closely but let's start with Wayland.

These instructions will get you a "pure" Wayland / Weston environment free of X11 dependencies, which obviously means that the XWayland compatibility layer will not be built. If you need the ability to run X apps inside Weston, follow the Xorg BLFS guide to get your Xorg server up and running first.

First ensure that pkgconfig will be able to locate a few Raspberry Pi specific graphics libraries:

export PKG_CONFIG_PATH="/usr/lib/pkgconfig:/opt/vc/lib/pkgconfig"

Now work your way through this list of dependencies (in order):

On to the fun stuff! Now we can build Wayland:

./configure --prefix=/usr --disable-documentation
make install

Then we need to add wayland-protocols:

./configure --prefix=/usr
make install

And finally we build Weston - the reference Wayland compositor:

./configure --prefix=/usr --disable-egl --disable-xwayland --disable-x11-compositor --disable-drm-compositor --disable-weston-launch --enable-demo-clients-install WESTON_NATIVE_BACKEND=""
make install

Almost there, we just need to create a directory for Weston's socket and lock files, like so:

echo "/run/shm/wayland dir 1700 root root" >> /etc/sysconfig/createfiles

And set the environment variable XDG_RUNTIME_DIR to point there, like so:

echo "export XDG_RUNTIME_DIR=/run/shm/wayland" >> ~/.profile

Time to play! We can now run weston with an accelerated minimal desktop and a terminal.

For more details and the original source for this writeup, check out this site.

Also, here's a nice list of Weston key bindings.

Now go build some cool stuff on top of Wayland and let me know about it!

18 Building Kodi (XBMC)

Let's begin with the dependencies that are required for Kodi to build.

First of all, you need a Java runtime to build the interface files. Note that Java is not required to run Kodi, it's only used during the build. Head on over to the Java SE Embedded Downloads page and trade your soul in for ejdk-8u65-linux-arm-sflt.gz.

Untar and put it somewhere nice and make sure that the java executable is in your path:

cp -rv ejdk1.8.0_65/linux_arm_sflt/jre /opt/java
export PATH="$PATH:/opt/java/bin"

Now we can work our way down the list of dependencies:

We also need yajl, which compiles like this:

mkdir build
cd build
make install

And finally TinyXML which needs a patch to produce a shared library:

patch -Np1 -i ../tinyxml_2_6_2-shared_lib.patch
make install

Phew! So those are the bare minimum dependencies for building Kodi. You may want to add additional software that Kodi can make use of, like Samba and Avahi etc. In particular, I would recommend that you also install libgpg-error, libgcrypt and libmicrohttpd and remove --disable-webserver from the configure line below. You'll be able to remote-control Kodi from your browser or your phone which is a very convenient feature to have on the Pi.

If your TV supports CEC, you'll also want to build libCEC so that you can use your TV remote to control Kodi:

mkdir build
cd build
make install
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DRPI_INCLUDE_DIR=/opt/vc/include -DRPI_LIB_DIR=/opt/vc/lib ..
sed -i 's/#define LIB_INFO.*/#define LIB_INFO ("3.0.1")/' ../src/libcec/env.h
sed -i '/\\n, compiled on/d' ../src/libcec/env.h
make install

Alright, let's start building Kodi!

You will definitely need a swap file to build Kodi, so set that up first.

Now grab the latest stable Kodi release:


If you're building for Raspberry Pi 2, apply this patch to override the raspberry-pi platform target specs:

patch -Np1 -i ../xbmc-15.2-Isengard-rpi2-target.patch

Whip the sources into shape with a bootstrap:


Now we can run configure:

CFLAGS="-I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux" CXXFLAGS="-I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux" LDFLAGS="-L/opt/vc/lib" ./configure --prefix=/usr --disable-debug --disable-gl --enable-gles --disable-joystick --disable-x11 --disable-ssh --disable-samba --disable-dvdcss --disable-avahi --disable-mysql --disable-webserver --disable-optical-drive --with-platform=raspberry-pi --enable-player=omxplayer

Note that the configure script will pause mid-way and build Kodi's own version of FFMPEG as it will not currently build against the official release.

And we make and pray to His Noodly Appendage!

make install

Tada! Just fire it up with kodi.

19 Adding on-board Bluetooth support for RPi3

The Raspberry Pi 3 comes equipped with an on-board Bluetooth 4.1 controller.

To make use of it, you'll need to build BlueZ - the Bluetooth protocol stack.

First build these dependencies (in order):

When it's time to build BlueZ, you need to apply this patch which contains various Pi specific fixes:

patch -Np1 -i ../bluez-5.40-rpi-fixes.patch

Once BlueZ is installed, one last step is required to make the Bluetooth controller work:

cat > /etc/bluetooth/uart.conf << "EOF"
# Start uart.conf
# Attach serial devices via UART HCI to BlueZ stack
# Use one line per device
# See the hciattach man page for options

ttyAMA0 bcm43xx 921600 noflow

# End of uart.conf

After a reboot, your Bluetooth controller should be up and ready for action. Try pairing with a BT device like so:

power on
agent on
scan on

For more info on Bluetooth poking from the command line, including Obex FTP and such, check out the Arch Linux wiki