Update: please see rpibuntu.kicherer.org for up-to-date informaton.

Foreword

Recently, I bought a Raspberry Pi 2 (RPi2) as a light-weight HTPC. The most interesting feature for me were the four ARMv7 CPU cores which give more performance and greater flexibility regarding the available software. As I am mostly using Ubuntu on the machines that are not powerful enough for Gentoo Linux, I wanted to install a recent Ubuntu version on the RPi2. I also tried ArchLinux for ARM but as other Arch installations before, it failed too often for my taste due to its release policy. The most recent issue was an unintended ABI change in OpenSSL which causes wpa_supplicant to fail joining WPA2 protected WiFi networks. This is bad, if your device has only a WiFi uplink, so you can't simply update to a fixed version, and annoying, if it is a device without keyboard that is located behind your furniture.

For the ARMv7-based RPi2, the official Ubuntu wiki offers a community-maintained 14.04 image and Ubuntu Mate offers an image with a complete desktop. As I wanted to start with something minimal and more recent, e.g., including systemd, I started to write a script that builds my own image.

Image description

The resulting image, simply called Pibuntu, contains a basic Ubuntu 15.04 that has the necessary software to boot on a RPi2 and has no graphical user interfaces. However, you can install your favorite software afterwards of course.

During early startup, the RPi2 firmware expects (by default) a file kernel7.img on the boot partition that should contain a valid kernel and boots it with the arguments in cmdline.txt. However, multiple kernels can be installed and the user would have to manually update the file kernel7.img depending on the desired kernel. To provide a convenient environment, I tried to installed Grub on the device which automatically boots the most recent kernel. Unfortunately, I was not able to get it to work on the RPi2 although a version for ARM exists. Hence, I built U-Boot for the RPi2 and wrote a small script update-uboot similar to the handy update-grub that looks for available kernels and initrd images and creates an U-Boot config that presents a boot menu at startup and boots the most recent kernel after a timeout of 2 seconds.

While developing this menu, the RPi2 freezed randomly during U-Boot execution. It turned out that the default scriptaddr variable caused the boot menu to be loaded at address 0x0 but something else is using the memory in this area and hence caused problems. After I changed the address to 0x00100000 the boot process worked smoothly.

The installed Linux kernel v4.0.9 is based on the sources from the official Raspberry GitHub repository, plus the Ubuntu-specific patches from the kernel PPA. This kernel will start Ubuntu from the BTRFS root filesystem using systemd. Most of the other packages come from http://ports.ubuntu.com but the image also includes my custom repository with RPi2-specific packages. If you are looking for other sources, you can also check out the custom PPA mentioned in the official Ubuntu wiki.

Update 2015-08-21: My repository now also contains a build of Kodi and TvHeadend for the Raspberry Pi 2 and there is an additional armhf-testing repository with the latest kernel 4.1.6, RPi2 firmware and Kodi 15.1. For convenience, you can install the package kodi-desktop to boot the RPi2 directly into Kodi.

Short installation guide

If you want to install Pibuntu 15.04, download this image, unzip it and write it to a SD card, e.g., using this command:

cat pibuntu_15.04.img.zip | gunzip -d | dd of=/dev/sdX

where /dev/sdX is the device for your card. Check dmesg to find the right device. Please note that this will erase existing data on the card!

If you are interested, you can also use this script to build and customize your own image with up-to-date packages.

The installed system will automatically configure the Ethernet interface with DHCP and accept SSH connections, so you don't need to attach a monitor and keyboard. You can login as user pibuntu with the password pibuntu.

Afterwards, you might want to:

  • recreate the SSH host keys with: rm /etc/ssh/ssh_host_*; dpkg-reconfigure openssh-server
  • increase the size of the root partition to use all available space on your SD card:
    • start a partitioning tool, e.g., fdisk, delete the second partition and recreate it with the default values to use the complete available space
    • execute: btrfs filesystem resize max $my_path_to_mounted_root to make BTRFS use the complete space inside the resized partition
  • create a BTRFS snapshot so you can rollback into the original state later:
    • mount the root volume somewhere using: mount /dev/sdX2 /my_mnt_dir/ -o subvol=/ and go into this directory
    • execute: btrfs subvolume snapshot @root $my_snapshot_name
  • I also wrote APT::Install-Recommends "0"; into /etc/apt/apt.conf.d/01norecommend in order to avoid unnecessary packages on this embedded device. Please note that this might cause problems. Only use it if you can find missing dependencies yourself.
  • setup automatic updates