1 of 28

Modernizing an Existing Embedded Linux Device

Take an existing embedded Linux product and create a modern, maintainable BSP — from kernel and U-Boot to a bootable SD card.

CASE STUDY

BREWIE B20 · ALLWINNER A13 · LINUX 3.4 (2016)

X.425 Session 4:

BoardSupportPackage (BSP) Engineering

2 of 28

The BSP Engineering Workflow

Every step of this process fits into one of six stages. Keep asking: "Which piece of information does Buildroot need?"

Build System

Hardware Description

Board Identification

Information Gathering

Discover Hardware

Investigation feeds the build system. The build system produces the image. The image boots the hardware.

3 of 28

Generic Information Gathering

This checklist applies to every embedded board. Fill it in before writing a single line of config.

Category

Information to Collect

CPU

SoC model, core count, RAM size

Bootloader

U-Boot? Barebox? Version?

Kernel

Version, patches, config

Storage

SD, eMMC, NAND — which is primary?

Boot Sequence

bootargs, bootcmd, load addresses

Device Tree / FEX

Hardware description format

Display / Touch

Resolution, interface, controller

USB / Network / Audio

Host vs OTG, Ethernet, WiFi, codec

GPIO / Peripherals

LEDs, buttons, SPI, I²C, UART

4 of 28

Generic Investigation Checklist

On-Board Commands

uname -a

cat /proc/cpuinfo

cat /proc/cmdline

dmesg

lsmod

mount

lsblk

find /boot

Identify the BSP Type

Look for these files to determine your starting point:

Found *.dtb?

→ Modern kernel with Device Tree support

Found script.bin?

→ Legacy Allwinner BSP using FEX format

5 of 28

Case Study: Brewie Investigation

Finding script.bin was the breakthrough — it confirmed a legacy Allwinner BSP and gave us the complete hardware description in a convertible format.

CPU

Allwinner A13

Kernel

3.4.90

Build System

Buildroot 2014

Hardware Desc.

script.bin

Bootloader

U-Boot

Storage

SD Card

6 of 28

Recovering the Hardware Description

From FEX to Device Tree

FEX (Flat EXchange format) is Allwinner's proprietary hardware configuration format used by older (pre-Device Tree) Linux kernels, especially the vendor 3.x BSP kernels.

  • CPU and memory settings
  • LCD timing
  • Touchscreen configuration
  • GPIO assignments
  • UART, SPI, I²C configuration
  • MMC/SD interfaces
  • USB configuration
  • Backlight
  • Power rails

It serves the same purpose that a Device Tree Source (.dts) serves today.

Example Conversion

; script.fex

lcd_x=480

lcd_y=272

lcd_dclk_freq=9

; sun5i-brewie.dts

display-timings {

native-mode = <&timing0>;

timing0: timing0 {

clock-frequency = <9000000>;

hactive = <480>;

vactive = <272>;

};

};

Nearly all hardware information is preserved through this conversion.

01

script.bin

02

bin2fexscript.fex

03

Manual conversion → .dts

7 of 28

Build the BSP

Everything before this point was investigation. Now Buildroot takes over.

Generate SD Image

Buildroot: Linux & RootFS

Buildroot: U-Boot

script.fex → DT

The conversion pipeline flows from hardware description through Buildroot configuration to a bootable SD image.

Files You Create

board/brewie/

genimage.cfg

post-build.sh

linux.config

sun5i-brewie.dts

8 of 28

Generic BSP Migration Strategy

What to Replace

Existing

Replace With

Vendor U-Boot

Mainline U-Boot

Vendor Kernel

Mainline Linux

script.bin

Device Tree

Vendor RootFS

Buildroot

Vendor BusyBox

Buildroot BusyBox

What to Reuse

Don't rewrite what upstream already supports. Preserve these values from the original BSP:

LCD Timings

Touchscreen

RTC

SPI / I²C

UART

GPIO Assignments

9 of 28

Build and Test

Build Commands

make brewie_defconfig

make

Output

output/images/sdcard.img

Flash Options

  • dd directly to SD card
  • Balena Etcher
  • Raspberry Pi Imager

Boot Verification Checklist

Treat each peripheral independently. Verify one, then move to the next.

U-Boot prompt

Kernel boots

Login prompt

LCD display

Touch input

WiFi / Network

RTC

10 of 28

Results and Lessons Learned

The Transformation

Before

Linux 3.4 · script.bin · Vendor BSP · Unmaintained

After

Linux 6.x · Device Tree · Buildroot BSP · Repeatable

Key Lessons

Gather information first

Never start building until the hardware is documented.

Preserve the original description

script.bin → FEX → Device Tree preserves everything.

Don't rewrite upstream drivers

If mainline supports it, use mainline.

A BSP is documentation

Buildroot automates the complete, reproducible image.

"A successful BSP migration is about understanding the hardware — not rewriting the software."

11 of 28

What do I need?

Where do I find it?

CPU

/proc/cpuinfo

Kernel

uname -a

Boot arguments

/proc/cmdline

Hardware description

script.bin or *.dtb

Display

fbset, dmesg, FEX/DT

Touchscreen

dmesg, i2cdetect

I²C devices

i2cdetect

SPI devices

/dev/spidev*, FEX/DT

Kernel configuration

/proc/config.gz or /boot/config-*

Bootloader

/boot, serial console

Root filesystem

mount, lsblk

Modules

lsmod

The BSP Discovery Cheat Sheet

12 of 28

What is a Device Tree?

A Device Tree is not code — it is structured data describing hardware. The kernel reads it at boot to discover what's connected, replacing hard-coded board logic with a flexible hardware contract.

13 of 28

Device Tree: The Hardware Contract

Linux Driver

Hardware contract uses DTS answers, not hard-coded pins

Device Tree (DTS)

Board-specific mapping of hardware to logical names

Core Hardware

Physical pins, buses, and peripherals

Drivers no longer hard-code pins like gpio = PB7;. Instead, they ask the DTS: "Which GPIO did the board designer connect?" The answer comes from the Device Tree — cleanly separating driver logic from board layout.

14 of 28

Anatomy of a DTS

/ {

model = "Brewie B20";

compatible = "brewie,b20",

"allwinner,sun5i-a13";

};

aliases {

serial0 = &uart1;

};

chosen {

stdout-path = "serial0:115200n8";

};

model & compatible

The most important property. Tells Linux: "I am an Allwinner A13 board." Matching drivers load automatically.

aliases

Maps logical names to hardware nodes. Software requesting serial0 gets UART1.

chosen

Directs kernel boot messages to UART1 at 115200 baud.

15 of 28

Peripherals: How Drivers Get Bound

&i2c0 {

status = "okay";

rtc@51 {

compatible = "nxp,pcf8563";

reg = <0x51>;

};

};

&i2c0 — Enable Controller

Activates the I²C bus controller on the SoC.

rtc@51 — Device Address

RTC chip at I²C address 0x51.

compatible — Driver Match

Linux finds nxp,pcf8563 in its driver table and binds it. No

16 of 28

The Complete Brewie B20 DTS

This DTS covers every peripheral on the board — each node engineered from real hardware sources.

Core

Model, compatible strings, UART1 console (PG3/PG4)

I²C Buses

I²C0: AXP209 PMIC + PCF8563 RTC · I²C2: ft5x06 touchscreen

Storage & SPI

MMC0 SD card (4-bit) · SPI2 with spidev

Display & USB

LCD RGB24 (PD0–PD27) · PWM backlight (PB02) · Framebuffer 480×272 · USB EHCI0 + OHCI0

17 of 28

Where Did This DTS Come From?

Every node was engineered, not copied. The DTS is assembled from multiple real-world sources.

DTS Node

Source

Method

model / compatible

Created manually

Board identity

LCD timings

script.fex

Allwinner config

Touch (ft5x06)

dmesg

Runtime probe

RTC address

dmesg

I²C scan

UART console

Boot log

Serial output

Backlight / GPIO / Memory

script.fex

Allwinner config

Not copied — Engineered. Every line traces back to hardware evidence.

18 of 28

Building with Buildroot

Required Files

brewie_b20_defconfig

Selects kernel, U-Boot, ext4 rootfs, and genimage. Place in buildroot/configs/.

sun5i-brewie.dts

Board hardware description. Place in board/brewie/.

genimage.cfg + post-image.sh

Defines sdcard.img layout and runs genimage after the build.

Run make brewie_b20_defconfig then make — builds everything including the kernel and final SD card image.

19 of 28

How Linux Boots: The Full Picture

ROM Start

U-Boot Loads

Kernel Init

The Device Tree is the bridge between bootloader and kernel. U-Boot passes the DTB to the kernel, which probes hardware, binds drivers by compatible string, mounts the root filesystem, and hands off to user-space applications.

ROM → U-Boot

Hardware init, load kernel + DTB

Kernel + DTB

Parse tree, bind drivers

Rootfs → Apps

Mount filesystem, start userspace

20 of 28

Part II: Engineering the Unknowns

Goal

Turn a bootable image into a working product, while preserving a reproducible build.

Method

Collect evidence, form a hypothesis, change one subsystem, and test on hardware.

The Difficult Work: Operating at Boundaries

• Legacy FEX versus Device Tree

• Bootloader versus Kernel

• Driver versus Application ABI

• Board Wiring versus Generic Bindings

Teaching Point:BSP engineering continues after the login prompt.

21 of 28

Boot Failure #1: The Kernel Was Not Necessarily Crashing

The Illusion of the Last Line

The last printed line was often only the last visible event; several boots returned to U-Boot without an oops or panic.

Identical Symptoms

A watchdog timeout, an early reset, a failed root mount, and a deferred probe can look deceptively similar from a serial console.

Useful Instrumentation

To diagnose these ambiguous failures, rely on: earlycon, initcall_debug, ignore_loglevel, deferred_probe_timeout, and the U-Boot reset/boot transcript.

Teaching Point: Timestamp the failure, but do not confuse the last log line with the root cause.

22 of 28

Use the Old BSP as a Measurement Instrument

Inputs Analyzed

Inputs included dmesg.txt, script.fex, fex-analysis.json, update.zip, and live inspection of the old machine.

Revealed Subsystems

The old system revealed the real RTC (PCF8563 at 0x51), touch controller (0x38), framebuffer modes, GPIO states, WiFi device, and application paths.

The Reference Mismatch

An Olimex/A13 reference assumption was wrong for the actual Brewie board; GPIO numbering and pin ownership differed.

Teaching Point: Legacy software is valuable evidence, but board identity must be verified before copying a configuration.

23 of 28

Isolate Subsystems Before Re-enabling Them

AXP209 & Stabilization

AXP209 probing caused I2C timeouts (-110), so it was disabled while the rest of the boot path was stabilized.

Incremental Reintroduction

RTC, touch, USB, WiFi, watchdog, audio, video decode, and display were reintroduced incrementally.

Dependency Discoveries

CPU Frequency: A CPU frequency change exposed a power/voltage dependency: the reported 384 MHz initial state was safer than blindly forcing a new rate. MMC/rootfs: MMC/rootfs was separated from kernel startup: the kernel ran correctly but needed built-in MMC support to mount /dev/mmcblk0p2.

Teaching Point: A minimal boot is a diagnostic instrument, not the final product.

24 of 28

Deferred Probe Is a Dependency-Graph Problem

EPROBE_DEFER Loop

The display backend and LCD controller repeatedly returned -EPROBE_DEFER; the device was present but a supplier, binding, or dependency was incomplete.

System Investigation

Inspection of /sys/devices, device links, waiting_for_supplier, compatible strings, and driver symlinks narrowed the problem.

Resolution & Alignment

The panel compatible was corrected from the invalid generic value to panel-dpi; LCD timing, pins, endpoints, and backlight dependencies were aligned. DRM card1 reported a connected Unknown-1 connector and the sun4i DRM framebuffer appeared.

Teaching Point: Read deferred-probe output as a graph of dependencies, not as a random delay.

25 of 28

The Backlight Was a Board-Level Signal

PWM & Enable Signal

PWM PB2 alone did not illuminate the panel. The actual Brewie hardware also needed the PB10 enable/latch signal.

GPIO Mapping Discovery

The old system's gpio7_pb10 test identified the board signal; the modern GPIO mapping was GPIO42, not the initially assumed GPIO35.

DTS Integration & Product Rules

DTS Configuration: The working DTS combines PWM backlight control with the panel enable GPIO and correct polarity/ownership. Brightness Rule: Hardware observation found an additional product rule: brightness 0/10 was off, while brightness 9 enabled the light.

Teaching Point: A backlight may require PWM, a power gate, sequencing, polarity, and a board-specific threshold.

26 of 28

Framebuffer Compatibility Matters to Applications

DRM Display Stack

The modern display stack was working as DRM: card0 was GPU, card1 was the display engine, and the connector was connected.

linuxfb Platform Failure

Qt's linuxfb platform still failed because /dev/fb0 was absent; DRM_FBDEV_EMULATION alone did not provide the legacy framebuffer device node.

CONFIG_FB_DEVICE Resolution

Enabling CONFIG_FB_DEVICE produced the compatibility node required by the existing Qt5 test path.

Teaching Point: A kernel driver can be healthy while the user-space ABI expected by an application is missing.

27 of 28

Reproducing the Product Display Path

Buildroot & Test Path

Buildroot now contains Qt5 GUI, linuxfb, QML/Quick, and a small board-side test program. The test uses target mode: QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0

Display Isolation

The six-color-square QML screen separates display bring-up from the original Brewie application, minimizing side effects.

Test Sequence

Execute the command sequence to enable the panel backlight and launch the test screen application:

echo 9 > /sys/class/backlight/backlight/brightness; qt-screen-test

Teaching Point: Validate the product interface with a minimal independent application before integrating legacy application behavior.

28 of 28

Engineering Lessons from the Brewie B20

1. Verify the Board

Preserve evidence, but verify the board. Old logs and scripts are clues, not an authoritative hardware description.

2. Isolate Failures

Keep bootloader, kernel, Device Tree, root filesystem, and application failures separate in the diagnosis.

3. Controlled Reduction & Signal Tracking

Experiments: Use controlled reduction and one-variable experiments; record both successful and misleading hypotheses. Tracking: Monitor pin mux, ownership, polarity, electrical enable signals, timing, and the expected application ABI.

Final Result: A reproducible Buildroot image with MMC/rootfs, RTC, touch, WiFi, DRM display, board backlight, framebuffer compatibility, and Qt5 test coverage.