Getting Started with the Raspberry Pi Compute Module 3: Buildroot Setup, Configuration, and Flashing

I recently encountered the Raspberry Pi Compute Module 3 (CM3) while prototyping with one of my clients. I wanted to share my notes for getting Buildroot configured for CM3 builds.

Getting Buildroot

You can find Buildroot in the official repository or on the Buildroot Github mirror. To create your project, either fork the buildroot repository or copy the source into your own project repo.

Modifying Buildroot For Your Project

Now that we've downloaded our repository, it's time to get our project configured.

Note that Raspberry Pi CM3 support is included in the raspberrypi3_defconfig. There are separate device trees in the Raspberry Pi kernel for the rpi3 and CM3 boards.

The easiest way to make modifications to the config is by using menuconfig and graphically browsing the various options available to you:

$ make raspberrypi3_defconfig
$ make menuconfig
# make modifications...
$ make savedefconfig

And your changes will be applied to the raspberrypi3_defconfig file for future use. You can also manually modify the defconfig file to reflect the changes you want.

Below are some useful configuration options to handle up front.

Download Location

You can control where Buildroot downloads packages by using the BR2_DL_DIR variable. This can be specified in your defconfig (BR2_DL_DIR="$(HOME)/br2_downloads"), or you can set it as an environment variable in the shell (export BR2_DL_DIR=${HOME}/br2_downloads).

Having an external download directory is very useful for many reasons:

  • Continuous Integration and Nightly builds can share a download cache on your build server
  • You can store downloads on a central server and cache downloads for your whole team
  • You can safely blow away your repository and not be required to re-download all packages.

Compiler Cache

If you install the ccache tool on your machine, you can make use of the compiler cache to speed up your buildroot builds. You can enable this through menuconfig or add the following lines to your defconfig file:

BR2_CCACHE=y
BR2_CCACHE_DIR=".buildroot-ccache"
BR2_CCACHE_INITIAL_SETUP=""
BR2_CCACHE_USE_BASEDIR=y

config.txt

Since there is no BIOS to store configuration options, the Raspberry Pi platforms utilize a file called config.txt to store any non-volatile boot options.

One problem I ran into was that after plugging the CM3 into the HDMI port on my TV, most of the text was cut off of the screen. Luckily there is a simple fix in the config.txt file:

# Disable overscan assuming the display supports displaying the full resolution
# If the text shown on the screen disappears off the edge, comment this out
disable_overscan=1

So I just commented out this line to fix the issue:

#disable_overscan=1

convert from ext4 to ext3

When I built the default image for the CM3, I noticed that the ext4 image had to be mounted in read-only mode, so I converted the image to be output in ext3. I haven't dug into this issue in depth yet, so only perform these steps if you want to fall back to ext3.

To convert to ext3, you will first need to switch from ext4 to ext3 in raspberrypi3_defconfig:

-BR2_TARGET_ROOTFS_EXT2_4=y
+BR2_TARGET_ROOTFS_EXT2_3=y

Then, in board/raspberrypi/genimage-raspberrypi3.cfg, you need to convert the partition image from rootfs.ext4 to rootfs.ext3:

partition rootfs {
     partition-type = 0x83
-    image = "rootfs.ext4"
+    image = "rootfs.ext3"
}

Now you should have an ext3 image!

Building

As mentioned above, CM3 support is included in the raspberrypi3_defconfig. To compile for the CM3, you simply need to run:

$ make raspberrypi3_defconfig
$ make

Buildroot needs to download and compile all of the packages you selected. Now is the time to take a break and go for a walk.

Flashing the Firmware Image to EMMC

Once the build is completed, you will find the images in output/images/. For the CM3, you want to flash the sdcard.img binary to the device

For full instructions on flashing, I recommend reading this "Flashing the Compute Module EMMC" article. Here is a brief summary of the steps for experienced users:

  • Software
    • Clone usbboot repository
      • git clone --depth=1 https://github.com/raspberrypi/usbboot
    • Install libusb-1.0.0-dev
      • sudo apt-get install libusb-1.0-0-dev
    • Build usbboot
      • cd usbboot; make
  • Hardware Setup
    • Make sure J4 (USB SLAVE BOOT ENABLE) is set to EN
    • Plug in USB cable to J15 USB connector
  • Run rpiboot (in usbboot directory)
    • sudo ./rpiboot
  • Power on CM3
    • Plug in USB cable to J2 USB connector (power)
  • After rpiboot completes, there will be a drive mounted under /dev/sd*.
    • On my Ubuntu machine, it mounts as /dev/sdb
    • Check /dev before plugging in the CM3 so you know which drive to write to. You can also check the timestamps.
  • Flash the image to the /dev/sdx device that corresponds to CM3
    • sudo dd if=path/to/sdcard.img of=/dev/sdx bs=4MiB

Now you should be up and running!

Accessories You'll Need

One thing that I wasn't aware of up front is that you need to have a hardware kit ready to go to chat with the device. I recommend purchasing the following items to make talking to your CM3 module easier:

  • Powered USB Hub
  • USB Mouse
  • USB Keyboard
  • USB Wifi dongle (there's no onboard wifi)

Now you should be up and running with a basic CM3 host framework. Please let me know if you run into any issues with these steps! In future articles I will describe enabling device tree overlays, enabling USB/serial shells, and other useful tips.

Further Reading