Skip to content

RPM Image Builder

Overview

Generates CentOS Stream 10 (aarch64) disk images for Qualcomm RB3 Gen2 platforms using kiwi-ng.

Features

  • Custom Linux kernel compilation (QCOM kernels, linux-next, upstream)
  • CentOS Stream 10 OS image generation using kiwi-ng
  • FIT multi-DTB image generation via build-dtb-image.sh
  • Board-specific flash artifact generation (generate_flat_build.sh)

Supported Targets

  • Operating System: CentOS Stream 10
  • Architecture: aarch64 (ARM64)
  • Platforms:
Board name Storage
qcs6490-rb3gen2 UFS

All three RB3 Gen2 kit variants (vision-kit, core-kit, industrial-kit) share a single board entry. All CDTs are bundled in the flash directory. cdt.bin targets the vision-kit by default. See CDT Selection.


Prerequisites

Install kiwi-ng

sudo pipx install kiwi
sudo pipx ensurepath   # then restart your shell

Host System Dependencies

# Fedora / CentOS Stream
sudo dnf install python3 git curl unzip dosfstools mtools rpm-build dtc uboot-tools \
                 createrepo_c e2fsprogs xfsprogs binfmt-support qemu-user-static parted kpartx \
                 grub2-efi-aa64 shim pipx

# Ubuntu / Debian
sudo apt install python3 python3-pip pipx git curl unzip dosfstools mtools rpm cpio \
                 device-tree-compiler u-boot-tools createrepo-c binfmt-support \
                 qemu-user-static qemu-utils parted kpartx e2fsprogs xfsprogs dnf

Disk Space

Minimum 50 GB free in the build directory.


Architecture & Build Pipeline

┌─────────────────────────────────────────────────────────────────┐
│                    QCOM RPM Image Build Flow                    │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Phase 1: Kernel Compilation (RPM)                              │
│  └─→ build_binrpm_pkg.py                                        │
│                                                                 │
│  Phase 2: OS Image Generation (kiwi-ng)                         │
│  └─→ kiwi-ng build → build/output/image.raw                     │
│                                                                 │
│  Phase 3: Flash Artifact Extraction                             │
│  └─→ extract_flash_artifacts.sh                                 │
│                                                                 │
│  Phase 4: Board-Specific Flash Packages                         │
│  └─→ generate_flat_build.sh                                     │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Project Structure

.
├── kiwi/
│   ├── config.xml               # kiwi image description (repos, packages, type)
│   ├── config.sh                # Post-install script (hostname, password, locale)
│   └── root/
│       └── usr/lib/repart.d/
│           └── 10-root.conf     # Auto-grow root partition on first boot
├── packages/                    # Drop custom kernel RPMs here before building
├── scripts/
│   ├── build_binrpm_pkg.py      # Kernel RPM builder
│   ├── extract_flash_artifacts.sh
│   └── generate_flat_build.sh
└── build/
    ├── output/
    │   ├── image.raw            # Full disk image (EFI + rootfs)
    │   └── flashimages/
    │       ├── efi.bin          # Extracted EFI System Partition
    │       ├── rootfs.img       # Extracted root filesystem
    │       └── dtbs.tar.gz      # Extracted device tree blobs
    └── out/
        └── flash_<board>_<storage>/  # Per-board flash packages

Detailed Workflow Phases

Phase 1: Kernel Compilation (RPM)

Script: scripts/build_binrpm_pkg.py

Native Compilation

python3 scripts/build_binrpm_pkg.py --qcom-next

Cross-Compilation Example

python3 scripts/build_binrpm_pkg.py \
  --qcom-next \
  --cross-prefix aarch64-linux-gnu- \
  --jobs 16

Kernel Outputs

work/linux/
├── arch/arm64/boot/Image
├── arch/arm64/boot/dts/*.dtb
└── rpmbuild/
    ├── RPMS/aarch64/kernel-*.rpm
    └── SRPMS/kernel-*.src.rpm

Phase 2: OS Image Generation

Tool: kiwi-ng

make image

This runs:

sudo kiwi-ng --type oem system build \
  --description kiwi/ \
  --target-dir build/output \
  [--add-repo file://$PWD/packages,rpm-md,local-packages,1]

kiwi reads configuration from:

  • kiwi/config.xml — image type, repositories, package list, bootloader, kernel cmdline
  • kiwi/config.sh — post-install script (hostname, root password, locale, services)
  • kiwi/root/ — overlay files copied verbatim into the image

Output

build/output/
└── image.raw    # Full GPT disk image (EFI System Partition + root filesystem)

Including a locally built kernel

Copy kernel RPMs into packages/ before building — make image will automatically run createrepo_c on the directory and pass it to kiwi as a high-priority local repository:

cp work/linux/rpmbuild/RPMS/aarch64/*.rpm packages/
make image

Adding extra firmware

Place any firmware files not available in linux-firmware under kiwi/root/usr/lib/firmware/ — they will be baked into the image:

kiwi/root/usr/lib/firmware/
└── qcom/
    └── <board-specific firmware files>

Phase 3: Flash Artifact Extraction

Extract the EFI System Partition and root filesystem from the raw disk image.

make flash-artifacts

Or manually:

sudo scripts/extract_flash_artifacts.sh \
  build/output/image.raw \
  build/output/flashimages

Outputs

build/output/flashimages/
├── efi.bin       # EFI System Partition (VFAT, contains GRUB2 + kernel)
├── rootfs.img    # Root filesystem (EXT4)
└── dtbs.tar.gz   # Device tree blobs

Phase 4: Board-Specific Flash Package Generation

generate_flat_build.sh downloads Qualcomm boot binaries and CDT files, generates GPT partition tables via qcom-ptool, and assembles a complete per-board flash directory ready for QDL / PCAT. Drive it through the Makefile:

# All supported boards (default)
make flash

# A specific board
make flash TARGET_BOARDS=qcs6490-rb3gen2
Under the hood: the raw generate_flat_build.sh invocation
make flash

Or manually:

./scripts/generate_flat_build.sh \
  --dtbs-tar    build/output/flashimages/dtbs.tar.gz \
  --esp-vfat    build/output/flashimages/efi.bin \
  --rootfs-ext4 build/output/flashimages/rootfs.img

Build a subset of boards

make flash TARGET_BOARDS=qcs6490-rb3gen2

Key options (generate_flat_build.sh)

Option Default Description
--dtbs-tar=<path> flashimages/dtbs.tar.gz DTB tarball; FIT image auto-generated from it; falls back to single-DTB on failure
--esp-vfat=<path> EFI System Partition image
--rootfs-ext4=<path> Root filesystem image
--target-boards=<list|all> all Comma-separated board names or all
--use-fit-image=(true|false) true true = FIT multi-DTB via build-dtb-image.sh (falls back to single-DTB on failure); false = single-DTB
--verbose=(true|false) false Enable debug output

Makefile variables

The Makefile targets (make image, make flash-artifacts, make flash) accept these overrides on the command line (see make help for the full list):

Variable Default Description
ARCH aarch64 Target architecture passed to kiwi-ng
TARGET_BOARDS qcs6490-rb3gen2 Comma-separated boards (or all) for make flash
USE_FIT_IMAGE 1 1 = FIT multi-DTB image (recommended); 0 = single-DTB VFAT
ARTIFACTDIR build/out Flash package output directory
EXTRA_FLASH_OPTS unset Extra flags forwarded to generate_flat_build.sh
EXTRA_KIWI_OPTS unset Extra flags forwarded to kiwi-ng
KIWI_PACKAGES_DIR packages Directory for custom kernel RPMs

Flash outputs

build/out/
├── dtb-multidtb.bin              # FIT multi-DTB FAT image (USE_FIT_IMAGE=1)
└── flash_qcs6490-rb3gen2_ufs/
    ├── prog_firehose_ddr_*.elf   # Firehose programmer
    ├── rawprogram*.xml           # Flash programming script
    ├── patch*.xml                # Patch script
    ├── gpt_*.bin                 # GPT partition table
    ├── efi.bin                   # EFI System Partition
    ├── rootfs.img                # Root filesystem
    ├── dtb.bin                   # DTB VFAT (FIT multi-DTB or single-DTB)
    ├── dtb-multi-dtb-image.vfat  # FIT multi-DTB alias (USE_FIT_IMAGE=1)
    ├── dtb-<soc>-image.vfat      # SoC-specific DTB alias (USE_FIT_IMAGE=1)
    ├── cdt.bin                   # Active CDT (vision-kit default)
    ├── cdt_core_kit.bin          # Core-kit CDT
    ├── cdt_industrial_kit.bin    # Industrial-kit CDT
    └── vmlinux                   # Kernel ELF (for crash debugging)

License

This project is licensed under the BSD-3-Clause-Clear License. See LICENSE.txt for the full license text.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages