common-raspberrypi
Common Buildroot BR2_EXTERNAL tree for Raspberry Pi projects. This repository provides shared board support, packages, rootfs overlays, and patches that are used across multiple projects.
Supported boards:
- Raspberry Pi 1 Model B+
- Raspberry Pi Zero W
This repository also pins the upstream Buildroot version as a git submodule, serving as the single source of truth for which Buildroot release is used. When a project pulls in this repo, it transitively gets the tested Buildroot version.
Repository layout
common-raspberrypi/
├── external.desc Buildroot external tree descriptor (name: RPI_COMMON)
├── external.mk Includes all common package .mk files
├── Config.in Top-level Kconfig menu for common packages
├── Makefile Wrapper for standalone build invocations
├── flash.sh SD card flashing helper script
├── buildroot/ [submodule] Upstream Buildroot, pinned to release tag
├── board/
│ └── raspberrypi/
│ ├── post-build.sh Shared post-build script (mdev rules, networking, build-info)
│ ├── post-image.sh Shared post-image script (genimage invocation)
│ ├── genimage.cfg.in SD card partition layout template
│ ├── config_common.txt Raspberry Pi firmware config.txt
│ ├── cmdline_common.txt Kernel command line
│ ├── extlinux.conf U-Boot extlinux boot configuration
│ ├── linux_defconfig Custom Linux kernel configuration
│ ├── uboot_defconfig Custom U-Boot configuration
│ ├── device_table.txt File permission fixups (SSH keys, mdev scripts)
│ ├── dtoverlay/ Custom device tree overlays
│ ├── uboot-patches/ Patches applied to U-Boot (DT overlay support)
│ └── rootfs-overlay/ Shared rootfs overlay (copied into target rootfs)
│ ├── etc/
│ │ ├── ssh/ Development SSH host keys
│ │ └── wpa_supplicant.conf
│ └── lib/
│ └── mdev/ Hotplug scripts (USB modeswitch, WLAN setup)
├── package/ Shared Buildroot packages
├── patches/ Patches to upstream Buildroot packages
└── configs/
└── raspberrypi_common_defconfig Defconfig for standalone builds
Boot architecture
The system boots through the Raspberry Pi firmware into U-Boot, which then loads the Linux kernel via extlinux:
- Raspberry Pi firmware (
bootcode.bin,start.elf) — readsconfig.txt(generated fromconfig_common.txt), loadsu-boot.bin. - U-Boot — reads
extlinux/extlinux.conf, loads the kernel (zImage), device tree, and device tree overlays. - Linux kernel — boots with the command line from
extlinux.conf.
U-Boot is patched (via uboot-patches/) to support device tree overlays.
The genimage.cfg.in template is expanded at build time by post-image.sh
to produce the final SD card image with a FAT boot partition and an ext4
rootfs partition.
Board selection
The default device tree targets the Raspberry Pi 1 B+. To build for the
Raspberry Pi Zero W, edit config_common.txt and extlinux.conf to
uncomment the Zero W device tree and comment out the B+ one. See the comments
in those files for details.
Standalone setup
Use this to develop and test the common tree without any project-specific additions. This is also what CI should run on every commit to this repo.
Prerequisites
A Linux host with standard Buildroot dependencies installed. See the Buildroot manual for the full list. On Debian/Ubuntu:
sudo apt-get install -y build-essential gcc g++ bash patch gzip bzip2 \
perl tar cpio unzip rsync file bc wget libncurses-dev git
Clone and initialize
git clone git@github.com:your-org/common-raspberrypi.git
cd common-raspberrypi
git submodule update --init
This pulls the Buildroot source into buildroot/ at the pinned release tag.
Build the image
The wrapper Makefile passes any target through to Buildroot:
make raspberrypi_common_defconfig # Load the defconfig
make # Build the full image (takes a while on first run)
The SD card image will be at output/images/sdcard.img.
Flash the SD card
sudo ./flash.sh /dev/sdX
The script validates that the target device is removable, unmounts any mounted partitions, and writes the image with progress output.
Useful build commands
make menuconfig # Open Buildroot configuration menu
make savedefconfig # Save current .config back to the defconfig
make linux-rebuild # Rebuild just the kernel (any Buildroot target works)
make clean # Clean build artifacts
Any valid Buildroot target is passed through directly by the Makefile.
Creating a new project
A project is a separate git repository that uses this common tree as a submodule. Each project is its own BR2_EXTERNAL and contains only project-specific packages, overlays, defconfigs, and board overrides.
Step 1: Create the project repository
mkdir myproject-raspberrypi
cd myproject-raspberrypi
git init
Step 2: Add common as a submodule
git submodule add git@github.com:your-org/common-raspberrypi.git common
git submodule update --init --recursive
The --recursive is important because it also pulls common's own Buildroot
submodule into common/buildroot/.
Step 3: Create the BR2_EXTERNAL descriptor
Create external.desc at the project root. The name must be unique across all
external trees and must be a valid C identifier (uppercase, underscores only):
name: MY_PROJECT
desc: My project-specific Buildroot configuration
Step 4: Create supporting directories
mkdir -p rootfs-overlay/etc
mkdir -p package
mkdir -p configs
echo '/output/' > .gitignore
Step 5: Create external.mk
This file includes only the project's own packages. The common packages are
handled by the common tree's own external.mk — Buildroot merges them
automatically because both trees are passed as separate BR2_EXTERNAL paths.
include $(sort $(wildcard $(BR2_EXTERNAL_MY_PROJECT_PATH)/package/*/*.mk))
Step 6: Create Config.in
Same principle — only source the project's own package configs. This file can start empty and be populated as packages are added:
menu "My Project packages"
endmenu
Step 7: Create a project defconfig
Create configs/raspberrypi_myproject_defconfig. Start by copying the common
defconfig and modify it:
cp common/configs/raspberrypi_common_defconfig configs/raspberrypi_myproject_defconfig
Edit the defconfig to add both overlays (common first, then project-specific):
BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_RPI_COMMON_PATH)/board/raspberrypi/rootfs-overlay $(BR2_EXTERNAL_MY_PROJECT_PATH)/rootfs-overlay"
Step 8: Create the wrapper Makefile
Create a Makefile at the project root. Like the common Makefile, it uses a
catch-all rule to pass any Buildroot target through directly:
BUILDROOT_DIR := $(CURDIR)/common/buildroot
OUTPUT_DIR := $(CURDIR)/output
BR2_EXTERNAL := $(CURDIR)/common:$(CURDIR)
CONFIG_EXISTS := $(wildcard $(OUTPUT_DIR)/.config)
.PHONY: all
all:
ifeq ($(CONFIG_EXISTS),)
@echo "No .config found. Load a defconfig first, e.g.:"
@echo " make raspberrypi_myproject_defconfig"
@exit 1
endif
$(MAKE) -C $(BUILDROOT_DIR) BR2_EXTERNAL=$(BR2_EXTERNAL) O=$(OUTPUT_DIR)
%:
$(MAKE) -C $(BUILDROOT_DIR) BR2_EXTERNAL=$(BR2_EXTERNAL) O=$(OUTPUT_DIR) $@
Note the key differences from the common Makefile:
BUILDROOT_DIRpoints tocommon/buildroot/(nested submodule)BR2_EXTERNALlists both trees, colon-separated:common:project
Step 9: Commit and build
git add -A
git commit -m "Initial project skeleton"
make raspberrypi_myproject_defconfig
make
Project directory structure
After following these steps, your project should look like this:
myproject-raspberrypi/
├── external.desc
├── external.mk
├── Config.in
├── Makefile
├── .gitmodules
├── .gitignore
├── common/ [submodule -> common-raspberrypi]
│ ├── buildroot/ [nested submodule -> upstream Buildroot]
│ ├── board/raspberrypi/
│ ├── package/
│ └── ...
├── configs/
│ └── raspberrypi_myproject_defconfig
├── rootfs-overlay/ Project-specific rootfs overlay
├── package/ Project-specific packages
└── output/ Build output (gitignored)
Wireless networking
The build includes support for USB Wi-Fi adapters based on the Realtek RTL8821CU chipset, as well as the Raspberry Pi Zero W's built-in Wi-Fi (Broadcom BCM43430). Both paths end with wpa_supplicant handling authentication and DHCP providing an IP address.
Raspberry Pi Zero W (built-in Wi-Fi)
The Zero W's Broadcom BCM43430 is connected via SDIO. The brcmfmac driver
and firmware blobs (included via BR2_PACKAGE_BRCMFMAC_SDIO_FIRMWARE_RPI)
are loaded at boot. The wlan0 interface is brought up automatically by the
auto wlan0 stanza in /etc/network/interfaces (appended by
post-build.sh), which starts wpa_supplicant and obtains an IP via DHCP.
USB RTL8821CU adapters
RTL8821CU adapters require an extra USB modeswitch step, handled through mdev hotplug rules:
- USB modeswitch — the adapter initially enumerates as a CD-ROM device
(
0bda:1a2b). An mdev rule triggersusb_modeswitchto switch it into Wi-Fi mode (0bda:c820). - WLAN setup — once the Wi-Fi device appears, a second mdev rule runs
wlan_setup.sh, which brings upwlan0and startswpa_supplicant. - DHCP — the interface obtains an IP address via DHCP.
Configuring Wi-Fi credentials
Edit board/raspberrypi/rootfs-overlay/etc/wpa_supplicant.conf with the
target network's SSID and passphrase:
network={
ssid="MyNetwork"
psk="MyPassphrase"
}
Post-build rootfs modifications
The post-build.sh script makes the following modifications to the target
rootfs at build time:
- Adds mdev rules for USB modeswitch (
rtl8821cu_usb_modeswitch.sh) and WLAN setup (wlan_setup.sh). - Appends
wlan0configuration to/etc/network/interfaces(DHCP with wpa_supplicant). - Generates
/etc/build-infowith the build user, date, and git revision.
Adding a new shared package
- Create a directory under
package/with the package name. - Add a
Config.inwith the Kconfig entry. - Add a
.mkfile with the Buildroot package recipe. - Source the new
Config.inin the top-levelConfig.in. - Enable the package in
configs/raspberrypi_common_defconfig. - Build and verify:
make my-new-package-rebuild.
Adding patches to upstream Buildroot packages
Place patch files under patches/<package-name>/. Buildroot automatically
applies patches from BR2_EXTERNAL_RPI_COMMON_PATH/patches/<package-name>/
during the package build. Patches must follow Buildroot's naming convention:
NNNN-description.patch (e.g., 0001-fix-cross-compilation.patch).
U-Boot patches live separately under board/raspberrypi/uboot-patches/ and
are applied via the BR2_TARGET_UBOOT_PATCH defconfig option.