2026-04-16 19:44:11 -03:00
2026-03-27 20:52:06 -03:00
2026-04-16 18:42:23 -03:00
2026-04-09 21:33:25 -03:00
2026-03-27 20:57:59 -03:00
2026-03-27 20:57:59 -03:00
2026-03-27 20:52:06 -03:00
2026-04-09 16:07:34 -03:00
2026-03-27 20:57:59 -03:00
2026-03-27 20:57:59 -03:00
2026-03-28 14:34:44 -03:00
2026-03-28 14:31:06 -03:00
2026-04-16 19:44:11 -03:00

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:

  1. Raspberry Pi firmware (bootcode.bin, start.elf) — reads config.txt (generated from config_common.txt), loads u-boot.bin.
  2. U-Boot — reads extlinux/extlinux.conf, loads the kernel (zImage), device tree, and device tree overlays.
  3. 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_DIR points to common/buildroot/ (nested submodule)
  • BR2_EXTERNAL lists 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:

  1. USB modeswitch — the adapter initially enumerates as a CD-ROM device (0bda:1a2b). An mdev rule triggers usb_modeswitch to switch it into Wi-Fi mode (0bda:c820).
  2. WLAN setup — once the Wi-Fi device appears, a second mdev rule runs wlan_setup.sh, which brings up wlan0 and starts wpa_supplicant.
  3. 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 wlan0 configuration to /etc/network/interfaces (DHCP with wpa_supplicant).
  • Generates /etc/build-info with the build user, date, and git revision.

Adding a new shared package

  1. Create a directory under package/ with the package name.
  2. Add a Config.in with the Kconfig entry.
  3. Add a .mk file with the Buildroot package recipe.
  4. Source the new Config.in in the top-level Config.in.
  5. Enable the package in configs/raspberrypi_common_defconfig.
  6. 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.

Description
No description provided
Readme 106 KiB
Languages
Shell 81.5%
Makefile 18.5%