Skip to content

BSP: From SoC to Board

Advanced11 min read
Assumes: 5.2 The Boot Chain, 5.4 Multi-OS Layout
TL;DR

A Board Support Package (BSP) is the software layer that translates a generic SoC into a working system on a specific board. It contains the device tree (hardware description), kernel configuration (feature flags), drivers (peripheral access), firmware blobs (DSP/GPU/modem binaries), and board-specific pin/peripheral mappings. On Qualcomm automotive platforms, the BSP includes files like sa8155p-adp.dts, the msmnile defconfig, QUP serial engine configs, PMIC regulator definitions, and TrustZone access control tables. Without a BSP, you have a powerful SoC connected to nothing. Every debug technique, every flash operation, every driver issue you encounter traces back to what the BSP defines.

You’ve seen “BSP” in partition docs, build logs, and team emails. This page explains what’s actually inside it and why it matters for everything you do downstream. Get it wrong and the SoC thinks it has peripherals that don’t exist. Get it right and nobody notices. Classic infrastructure work.

A BSP is not a single file — it’s a structured collection of artifacts that together make QNX and AAOS boot and run on a particular board. Think of it as layers stacking from silicon up to OS:

flowchart TB
    subgraph silicon ["Silicon IP (fixed by Qualcomm)"]
        CPU["Kryo CPU cores"]
        GPU["Adreno GPU"]
        DSP["Hexagon DSP"]
        UFS["UFS controller"]
        UART["UART / QUP engines"]
        PMIC["PMIC interface"]
    end

    subgraph bsp ["BSP Layer (configured per board)"]
        DT["Device Tree\n.dts / .dtsi"]
        DEF["Kernel defconfig\nfeature flags"]
        DRV["Drivers\nkernel modules + resource managers"]
        FW["Firmware blobs\n.mbn / .elf"]
        PIN["Pin control &\nQUP mapping"]
        REG["PMIC regulator\ndefinitions"]
    end

    subgraph os ["OS Layer"]
        LINUX["Linux / AAOS"]
        QNX["QNX"]
        AMSS["AMSS / modem"]
    end

    silicon --> bsp --> os
BSP Component What It Does Qualcomm Example
Device tree Describes hardware topology — which peripherals exist, their addresses, IRQs, clocks sa8155p-adp.dts, sa8295p-adp.dts
Kernel config Enables/disables kernel features and driver support msmnile_gki_defconfig + vendor fragments
Drivers Code that talks to hardware — built-in or loadable modules qcom,geni-uart, display DRM, UFS host
Firmware blobs Pre-built binaries for subsystems the kernel doesn’t control directly adsp.mbn, cdsp.mbn, GPU firmware
Pin/pad control Maps SoC pins to board traces — UART TX/RX, I2C SDA/SCL, GPIO msmnile-pinctrl.dtsi, TLMM reserved ranges
PMIC regulators Voltage rail definitions for the power management IC pmm8155au-rpmh-regulators nodes
TZ access control Which QUP engines are accessible by which execution environment QUPAC_Access.c in TrustZone images
Mental Model

A BSP is like a house wiring plan. The SoC is the electrical panel — raw capacity, many circuit breaker slots. The device tree is the blueprint — which rooms get which circuits, where outlets go. Drivers are the electricians — they connect each outlet and make it work. Firmware blobs are pre-installed appliances (the dishwasher has its own controller). Without the wiring plan, you have a powerful panel connected to nothing.

Mnemonic: BSP = the adapter that makes one OS fit one board. Different board? Different BSP.

Think About It

You move your software from an ADP reference board to an OEM’s custom board. The SoC is identical. What changes?

Reveal Answer

The board .dts overlay — pin control, PMIC regulator sequences, display/camera/CAN nodes, status = "okay" enables, and reserved-memory carveouts for that PCB layout. The shared SoC .dtsi stays; you add OEM drivers, update defconfig/compatible bindings, rawprogram.xml partition sizes, and QNX startup for new UART/slog routing. On first boot, diff the flashed DTB against ADP and watch serial for probe -517 deferrals on custom I2C or SerDes paths.

Device Tree: The Hardware Description Language

Section titled “Device Tree: The Hardware Description Language”

The device tree is the most important part of the BSP for day-to-day work. It’s a data structure that tells the kernel — through HAL drivers — what hardware exists on the board — no probing, no guessing.

Qualcomm automotive device trees follow an include hierarchy — general SoC definitions at the bottom, board-specific overrides at the top:

flowchart TB
    SoC["sa8155p.dtsi\nSoC-level: CPU topology, memory map,\nperipheral base addresses, interrupt controller"]
    Board["sa8155p-adp.dts\nBoard-level: which peripherals enabled,\npin mappings, regulators, stdout-path"]
    OEM["oem-carrier.dts (OEM overlay)\nOEM-specific: custom displays,\ncamera configs, additional GPIOs"]

    SoC -->|"#include"| Board
    Board -->|"optional overlay"| OEM
File Scope Who Owns It
sa8155p.dtsi SoC definition — shared across all SA8155P boards Qualcomm (upstream + downstream)
sa8155p-adp.dts ADP reference board — enables UFS, debug UART, PMICs, USB Qualcomm reference BSP
OEM .dts overlay Carrier board customizations — OEM displays, sensors, CAN transceivers Tier-1 / OEM

Key rule: .dtsi = include file (shared, reusable). .dts = source file (board-specific, top-level). A .dts includes one or more .dtsi files and overrides nodes as needed.

Every device tree node has a compatible property that tells the kernel which driver to bind:

&qup2_uart17 {
compatible = "qcom,geni-debug-uart";
status = "okay";
};

The kernel walks its driver table looking for a match on "qcom,geni-debug-uart". If no driver has that compatible string compiled in, the hardware exists on the board but nothing talks to it. This is the single most common BSP misconfiguration: hardware is wired, device tree declares it, but the kernel config doesn’t enable the matching driver.

Common Gotcha

If you define a peripheral in the device tree but forget status = "okay", it won’t work. The status property defaults to "disabled". A peripheral defined in the SoC .dtsi does nothing until the board .dts enables it. Forgetting this override is the #1 reason a peripheral “doesn’t exist” even though it’s in the device tree. Always check status first.

On the SA8295P ADP, the debug UART is connected to QUP2 Serial Engine 17. The BSP enables it in three layers:

  1. SoC DTSI defines the QUP hardware block with base address, clocks, interrupts
  2. Board DTS enables the specific serial engine and sets the compatible to "qcom,geni-debug-uart"
  3. Board DTS sets stdout-path = "serial0:115200n8" in the chosen node so the kernel uses it for console output
/* sa8295p-adp.dts — relevant excerpts */
/ {
aliases {
serial0 = &qup2_uart17;
};
chosen {
stdout-path = "serial0:115200n8";
};
};
&qup2 {
status = "okay";
};
&qup2_uart17 {
compatible = "qcom,geni-debug-uart";
status = "okay";
};

This is the device tree chain that makes your UART console work. If you ever lose serial output, trace this chain: is the QUP parent enabled? Is the UART node status "okay"? Is stdout-path pointing to the right alias?

Device tree quick-check commands

On a running Linux system, you can inspect the live device tree:

Terminal window
# See the full flattened device tree the kernel booted with
ls /proc/device-tree/
# Check if a specific node is enabled
cat /proc/device-tree/soc/geniqup@.../serial@.../status
# Decompile the running device tree to readable DTS
dtc -I fs /proc/device-tree -O dts > running.dts
# Search for a compatible string
grep -r "geni-debug-uart" /proc/device-tree/

On QNX, hardware enumeration is in the startup code and resource managers rather than a live /proc tree. Use pidin syspage=asinfo to see memory-mapped hardware regions.

Qualcomm BSPs ship in at least two configurations that affect what you can do:

Variant Build Flag JTAG UART Console Crashdump Use Case
Debug / Dev DEBUG_BUILD=1 Open (unfused) Full kernel output Enabled (mini + full) Bench development, bring-up
Performance / Prod Default Fuse-controlled May be silent Policy-controlled Production vehicles, DVT boards

The debug BSP enables extra kernel config fragments (CONFIG_KGDB, CONFIG_DEBUG_INFO, CONFIG_FTRACE), keeps JTAG accessible, and sets download mode so crashes produce ramdumps instead of silent reboots. The performance BSP strips debug symbols, disables invasive trace, and relies on fuse state for debug access.

This matters for Module 10: When your debug tools “don’t work” on a new board, the first question is always: which BSP variant is flashed? A production BSP on a dev board deliberately hides the debug interfaces you need.

Fuse state vs BSP variant

Fuses are permanent — once blown, JTAG disable or secure boot enforcement cannot be undone. BSP variant is software — you can reflash a debug BSP onto a fuse-open board. The combination determines your debug surface:

Board Fuses BSP Variant Debug Access
Open (dev) Debug BSP Full: JTAG, UART, crashdump, KGDB
Open (dev) Prod BSP Partial: JTAG works (fuse allows), but kernel debug features stripped
Closed (prod) Debug BSP Limited: BSP enables features, but fuses block JTAG and may block dump
Closed (prod) Prod BSP Minimal: only production diagnostics (UDS/DoIP)

In practice, bench boards are fuse-open + debug BSP. Pre-production (DVT/PVT) boards may be fuse-open + production BSP for validation. Production vehicles are fuse-closed + production BSP.

Platform vs Board: The Naming You Need to Know

Section titled “Platform vs Board: The Naming You Need to Know”

Three distinct things share similar names. Keeping them straight prevents confusion in docs and email threads:

flowchart LR
    SoC["SA8155P\n(SoC / silicon)"]
    ADP["SA8155P-ADP\n(Qualcomm reference board)"]
    OEM["OEM Carrier Board\n(your program's board)"]

    SoC -->|"is mounted on"| ADP
    SoC -->|"is mounted on"| OEM
    ADP -->|"reference BSP\nprovided by Qualcomm"| REF["Reference BSP"]
    OEM -->|"customized BSP\nby Tier-1"| CUSTOM["Program BSP"]
    REF -->|"base for"| CUSTOM
Term What It Is Example
SA8155P The SoC die — Kryo + Adreno + Hexagon + PMIC interface Qualcomm silicon
SA8155P-ADP Qualcomm’s Automotive Development Platform — a reference board with the SoC, connectors, and debug headers Your bench board
OEM carrier board The actual production PCB designed by the Tier-1 for an OEM program What goes in the car
Reference BSP Qualcomm’s BSP for the ADP board — enables all debug interfaces, standard peripherals Starting point for Tier-1
Program BSP Tier-1’s customized BSP — OEM display configs, custom sensors, production debug policy What you flash daily

Tier-1s start with the reference BSP and layer customizations: new device tree overlays for OEM hardware, modified defconfigs for feature flags, additional drivers for custom peripherals, and production-grade debug policies. When you flash a build, you’re flashing the program BSP, not Qualcomm’s reference.

Memorization aid: BSP = Board Specific Package. Emphasis on “Board” — the SoC is generic, the BSP makes it specific to this board. When someone says “BSP issue,” they mean the software layer between silicon and OS, not the silicon itself.

The BSP is the foundation layer that every other module builds on:

Downstream Topic BSP Dependency
Boot chain (Page 5.2) XBL loads device tree blob, ABL passes it to kernel
Kernel (Page 6.6) Kernel reads device tree to discover hardware, loads modules matching compatible strings
Flash (Module 8) Partition layout and rawprogram XML are BSP artifacts
Debug bench (Page 10.1) Physical connectors only work if BSP enables the corresponding peripherals
Debug interfaces (Page 10.3) UART, JTAG availability depends on BSP variant and device tree config
OTA (Page 8.5–8.6) UpdateEngine, capsule agents are BSP-integrated services
Connect the Dots

Module 5.1 introduced the SoC blocks (CPU, GPU, DSP) — the BSP is how those blocks get wired to the physical board. Page 5.2 (boot chain) showed XBL and ABL loading images — those images include the device tree blob the BSP defines. Module 6 (operating systems) runs on top of what the BSP enables. Page 10.1 (debug bench) covers the physical connectors — the BSP determines which ones actually function. Page 10.3 (debug interfaces) explains UART/JTAG — the BSP controls whether they’re enabled via device tree and debug policy.

  1. A BSP bridges SoC silicon to a specific board via device tree, drivers, config, and firmware.
  2. Device tree hierarchy: .dtsi (SoC, shared) -> .dts (board, specific) -> OEM overlay (program, custom).
  3. The compatible string in device tree binds hardware nodes to kernel drivers. Missing driver + present node = silent failure.
  4. status = "okay" is required to activate any peripheral — the default is "disabled".
  5. Debug vs production BSP controls your entire debug surface. Always know which variant is on the board.

Check Your Understanding

1. What is the relationship between a .dtsi file and a .dts file in a Qualcomm BSP?

Recall

2. A new UART peripheral is defined in the SoC .dtsi but you get no serial output. What is the most likely BSP-level cause?

Applied

3. You have JTAG access on bench board A but not on bench board B, even though both have the same SoC. What determines the difference?

Applied

4. A device tree node declares compatible = "qcom,geni-debug-uart" but the UART still does not probe. What BSP artifact is most likely missing?

Recall

5. You port software from SA8155P-ADP reference board to an OEM carrier board with a different display panel and CAN transceiver. The SoC is identical. What BSP changes are required?

Applied

6. An engineer flashes a production BSP onto a fuse-open bench board and loses UART console output. Can they recover debug access without replacing hardware?

Synthesis

Connects to: Module 10 — Debug Engineering

Module Review: Qualcomm Cockpit SoC

Question 1 of 12

Engineering needs to passthrough a PCIe NVMe SSD to the AAOS VM for development. Which BSP components must be modified?

🔗 Connects to: Module 9 — ISO 21434

Further Reading
  • QNX Neutrino — Building a BSP — QNX documentation for BSP structure, startup code, buildfiles, and board-specific configuration that bridges SoC silicon to a bootable QNX platform.
  • Linux Device Tree Documentation — Kernel documentation for device tree source (.dts/.dtsi) hierarchy, compatible strings, and status properties that define the Linux/ABL side of automotive BSP development.
  • Device Tree Specification — Official devicetree.org specification for the hardware description format used in board .dts files, overlays, and reserved-memory carveout definitions.
  • Qualcomm Developer Portal — Qualcomm engineering resources, blog posts, and documentation for Snapdragon automotive platform bring-up, secure boot, and BSP integration.
  • Android Boot Image Header — AOSP specification for boot.img structure that ABL loads using the device tree blob (DTB) compiled from BSP .dts sources.
  • QNX Software Development Platform 8.0 — QNX SDP product page covering BSP tooling, board support packages, and hypervisor integration for automotive target platforms.
  • Linux Kernel Driver Model Documentation — Kernel driver API reference explaining how device tree compatible strings bind hardware nodes to kernel modules — the mechanism behind BSP driver matching described on this page.