From 3ea090ba17e759c43b4cc373bca731be12e533ff Mon Sep 17 00:00:00 2001 From: Gabriel Lima Date: Thu, 16 Apr 2026 19:44:11 -0300 Subject: [PATCH] Update README.md --- README.md | 304 ++++++++++++++++++++++++++---------------------------- 1 file changed, 145 insertions(+), 159 deletions(-) diff --git a/README.md b/README.md index 3a5b724..17e8511 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,13 @@ -# br2-external-common +# common-raspberrypi -Common Buildroot BR2_EXTERNAL tree for all Raspberry Pi projects. This -repository provides shared board support, packages, rootfs overlays, and -patches that are used across multiple projects. +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 @@ -11,29 +16,61 @@ a project pulls in this repo, it transitively gets the tested Buildroot version. ## Repository layout ``` -br2-external-common/ +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 (rootfs fixups) -│ ├── post_image.sh Shared post-image script (genimage invocation) -│ ├── genimage.cfg SD card partition layout -│ └── overlay/ Shared rootfs overlay (copied into target rootfs) -│ └── etc/ -│ └── network/ -│ └── interfaces -├── package/ -│ ├── my-shared-lib/ Example shared library (CMake package) -│ └── my-common-tool/ Example shared tool (generic package) +│ ├── 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/ - └── rpi_common_test_defconfig Minimal defconfig for standalone CI testing + └── 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 @@ -52,40 +89,43 @@ sudo apt-get install -y build-essential gcc g++ bash patch gzip bzip2 \ ### Clone and initialize ```sh -git clone git@github.com:your-org/br2-external-common.git -cd br2-external-common +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 test image +### Build the image -The wrapper Makefile handles the Buildroot invocation: +The wrapper Makefile passes any target through to Buildroot: ```sh -make defconfig # Loads rpi_common_test_defconfig -make # Builds the full image (takes a while on first run) +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 + +```sh +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 ```sh make menuconfig # Open Buildroot configuration menu -make savedefconfig # Save current .config back to the test defconfig +make savedefconfig # Save current .config back to the defconfig make linux-rebuild # Rebuild just the kernel (any Buildroot target works) -make my-shared-lib-rebuild # Rebuild a specific package make clean # Clean build artifacts -make distclean # Remove the entire output directory ``` -You can use a different defconfig by passing DEFCONFIG: - -```sh -make defconfig DEFCONFIG=rpi_common_minimal_defconfig -``` +Any valid Buildroot target is passed through directly by the Makefile. ## Creating a new project @@ -96,15 +136,15 @@ project-specific packages, overlays, defconfigs, and board overrides. ### Step 1: Create the project repository ```sh -mkdir br2-external-myproject -cd br2-external-myproject +mkdir myproject-raspberrypi +cd myproject-raspberrypi git init ``` ### Step 2: Add common as a submodule ```sh -git submodule add git@github.com:your-org/br2-external-common.git common +git submodule add git@github.com:your-org/common-raspberrypi.git common git submodule update --init --recursive ``` @@ -121,7 +161,17 @@ name: MY_PROJECT desc: My project-specific Buildroot configuration ``` -### Step 4: Create external.mk +### Step 4: Create supporting directories + +```sh +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 @@ -131,108 +181,70 @@ automatically because both trees are passed as separate BR2_EXTERNAL paths. include $(sort $(wildcard $(BR2_EXTERNAL_MY_PROJECT_PATH)/package/*/*.mk)) ``` -### Step 5: Create Config.in +### Step 6: Create Config.in -Same principle — only source the project's own package configs: +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" -source "$BR2_EXTERNAL_MY_PROJECT_PATH/package/my-app/Config.in" - endmenu ``` -### Step 6: Create a project defconfig +### Step 7: Create a project defconfig -Create `configs/rpi_myproject_defconfig`. Start by copying the common test +Create `configs/raspberrypi_myproject_defconfig`. Start by copying the common defconfig and modify it: ```sh -cp common/configs/rpi_common_test_defconfig configs/rpi_myproject_defconfig +cp common/configs/raspberrypi_common_defconfig configs/raspberrypi_myproject_defconfig ``` -Edit the defconfig to: - -1. Add both overlays (common first, then project-specific): +Edit the defconfig to add both overlays (common first, then project-specific): ``` -BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_RPI_COMMON_PATH)/board/raspberrypi/overlay $(BR2_EXTERNAL_MY_PROJECT_PATH)/overlay" +BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_RPI_COMMON_PATH)/board/raspberrypi/rootfs-overlay $(BR2_EXTERNAL_MY_PROJECT_PATH)/rootfs-overlay" ``` -2. Add project-specific packages: +### Step 8: Create the wrapper Makefile -``` -BR2_PACKAGE_MY_APP=y -``` - -The common packages (`BR2_PACKAGE_MY_SHARED_LIB`, etc.) remain as-is. - -### Step 7: Create the wrapper Makefile - -Create a `Makefile` at the project root: +Create a `Makefile` at the project root. Like the common Makefile, it uses a +catch-all rule to pass any Buildroot target through directly: ```makefile BUILDROOT_DIR := $(CURDIR)/common/buildroot OUTPUT_DIR := $(CURDIR)/output BR2_EXTERNAL := $(CURDIR)/common:$(CURDIR) -DEFCONFIG ?= rpi_myproject_defconfig - CONFIG_EXISTS := $(wildcard $(OUTPUT_DIR)/.config) -.PHONY: all defconfig menuconfig savedefconfig clean distclean +.PHONY: all all: ifeq ($(CONFIG_EXISTS),) - @echo "No .config found. Run 'make defconfig' first." + @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) -defconfig: - $(MAKE) -C $(BUILDROOT_DIR) BR2_EXTERNAL=$(BR2_EXTERNAL) O=$(OUTPUT_DIR) $(DEFCONFIG) - -menuconfig: - $(MAKE) -C $(BUILDROOT_DIR) BR2_EXTERNAL=$(BR2_EXTERNAL) O=$(OUTPUT_DIR) menuconfig - -savedefconfig: - $(MAKE) -C $(BUILDROOT_DIR) BR2_EXTERNAL=$(BR2_EXTERNAL) O=$(OUTPUT_DIR) savedefconfig \ - BR2_DEFCONFIG=$(CURDIR)/configs/$(DEFCONFIG) - -clean: - $(MAKE) -C $(BUILDROOT_DIR) BR2_EXTERNAL=$(BR2_EXTERNAL) O=$(OUTPUT_DIR) clean - -distclean: - rm -rf $(OUTPUT_DIR) - %: $(MAKE) -C $(BUILDROOT_DIR) BR2_EXTERNAL=$(BR2_EXTERNAL) O=$(OUTPUT_DIR) $@ ``` -Note the key difference from the common Makefile: +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 8: Create supporting directories - -```sh -mkdir -p overlay/etc -mkdir -p package -mkdir -p board -mkdir -p configs - -echo '/output/' > .gitignore -``` - ### Step 9: Commit and build ```sh git add -A git commit -m "Initial project skeleton" -make defconfig +make raspberrypi_myproject_defconfig make ``` @@ -241,100 +253,74 @@ make After following these steps, your project should look like this: ``` -br2-external-myproject/ +myproject-raspberrypi/ ├── external.desc ├── external.mk ├── Config.in ├── Makefile ├── .gitmodules ├── .gitignore -├── common/ [submodule -> br2-external-common] +├── common/ [submodule -> common-raspberrypi] │ ├── buildroot/ [nested submodule -> upstream Buildroot] │ ├── board/raspberrypi/ │ ├── package/ │ └── ... ├── configs/ -│ └── rpi_myproject_defconfig -├── overlay/ Project-specific rootfs overlay +│ └── raspberrypi_myproject_defconfig +├── rootfs-overlay/ Project-specific rootfs overlay ├── package/ Project-specific packages -│ └── my-app/ └── output/ Build output (gitignored) ``` -## Branching strategy +## Wireless networking -This repository uses long-lived branches to support multiple Buildroot -versions simultaneously, mirroring Buildroot's own LTS release model. +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. -### Branch naming +### Raspberry Pi Zero W (built-in Wi-Fi) -- `main` — Tracks the latest Buildroot release (currently 2026.02). Active - development of shared packages happens here. -- `YYYY.MM.x` — Maintenance branches for older Buildroot LTS lines (e.g., - `2023.02.x`). These receive only bug fixes and minor Buildroot bumps within - the same LTS series. +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. -### Creating a maintenance branch +### USB RTL8821CU adapters -When a project needs to stay on an older Buildroot version: +RTL8821CU adapters require an extra USB modeswitch step, handled through +mdev hotplug rules: -```sh -# Start from the last commit that used the older Buildroot -git checkout -b 2023.02.x +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. -# Verify the buildroot submodule points to the right tag -cd buildroot -git log --oneline -1 # Should show 2023.02.x tag -cd .. +### Configuring Wi-Fi credentials -git push -u origin 2023.02.x +Edit `board/raspberrypi/rootfs-overlay/etc/wpa_supplicant.conf` with the +target network's SSID and passphrase: + +``` +network={ + ssid="MyNetwork" + psk="MyPassphrase" +} ``` -### Bumping a minor Buildroot version on a maintenance branch +### Post-build rootfs modifications -For example, upgrading from 2023.02.1 to 2023.02.2: +The `post-build.sh` script makes the following modifications to the target +rootfs at build time: -```sh -git checkout 2023.02.x - -cd buildroot -git fetch --tags -git checkout 2023.02.2 -cd .. - -git add buildroot -git commit -m "buildroot: bump to 2023.02.2" -git push -``` - -Then in the project that uses this branch: - -```sh -cd common -git pull origin 2023.02.x -cd .. - -git add common -git commit -m "common: pick up buildroot 2023.02.2" -``` - -### Backporting shared package fixes - -When a bug fix on `main` also applies to a maintenance branch: - -```sh -git checkout 2023.02.x -git cherry-pick -# Resolve conflicts if the package versions have diverged -# Test with: make defconfig && make -git push -``` - -### End-of-life - -When a legacy project is decommissioned, its maintenance branch can be -archived (renamed to `archive/2023.02.x`) or deleted. No other projects -are affected. +- 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 @@ -342,15 +328,15 @@ are affected. 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/rpi_common_test_defconfig`. +5. Enable the package in `configs/raspberrypi_common_defconfig`. 6. Build and verify: `make my-new-package-rebuild`. -See `package/my-shared-lib/` (CMake example) and `package/my-common-tool/` -(generic example) for reference. - ## Adding patches to upstream Buildroot packages Place patch files under `patches//`. Buildroot automatically applies patches from `BR2_EXTERNAL_RPI_COMMON_PATH/patches//` 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.