Search This Blog

Monday, September 21, 2026

Cross Compilation - sunxi-tools

In order to reuse or change a bit of stuff in my allwinner soc i am on quest to have its linux tools cross compiled. Most of the tools have cross compilation features but somehow doesnt work or has a missing library dependency. This is to document what those dependency are and how to get it to work.

Deconstructing the Makefile Requirements

Inspecting the sunxi-tools Makefile reveals three non-negotiable external C dependencies:

  • libusb-1.0: Provides low-level USB communication with Allwinner devices in FEL mode.

  • zlib: Handles compression and decompression routines.

  • libfdt: Manages Flattened Device Trees (FDT) for hardware board descriptions.

The Makefile resolves these libraries dynamically via pkg-config:

Makefile
LIBUSB_CFLAGS ?= `$(PKG_CONFIG) --cflags $(LIBUSB)`
LIBUSB_LIBS   ?= `$(PKG_CONFIG) --libs $(LIBUSB)`

If pkg-config fails to find valid .pc metadata files pointing to target-specific MinGW libraries, compilation fails immediately. The Docker container must therefore satisfy two requirements: host cross-compiled static libraries and make them discoverable to pkg-config.

Setting Up the Dockerfile Architecture

Base Image Selection: gcc:16.1.0

Using an official GCC base image provides a modern Debian Linux foundation pre-packed with native development tools, ensuring build consistency regardless of the host OS running Docker.

Target Environment Setup: MinGW-w64

To target 64-bit Windows platforms, we establish the cross-compiler prefix and install the requisite toolchains:

Dockerfile
ENV MINGW_PREFIX=/usr/x86_64-w64-mingw32

RUN apt-get update && apt-get install -y \
    mingw-w64 \
    cmake \
    autoconf \
    automake \
    pkg-config \
    git \
    wget \
    && rm -rf /var/lib/apt/lists/*

Dependency Compilation Strategies

Each of the three core dependencies requires a distinct build strategy for MinGW target integration:

┌────────────────────────────────────────────────────────┐
│                  MinGW Target Root                     │
│               /usr/x86_64-w64-mingw32                  │
└──────────────────────────┬─────────────────────────────┘
                           │
      ┌────────────────────┼────────────────────┐
      │                    │                    │
┌─────▼──────┐      ┌──────▼─────┐      ┌───────▼──────┐
│    zlib    │      │   libfdt   │      │    libusb    │
│  (1.3.1)   │      │  (v1.7.0)  │      │   (1.0.26)   │
└─────┬──────┘      └──────┬─────┘      └───────┬──────┘
      │                    │                    │
 Built via win32    Built from source    Extracted from
 Makefile.gcc       via custom flags     pre-built MinGW
 (Cross-compiled)   (make libfdt)        static release

1. zlib (v1.3.1) — Cross-Compiled Source

zlib includes a built-in Win32 Makefile designed for cross-compiling with GCC tools:

Dockerfile
# Cross-compiling zlib using MinGW toolchain
RUN wget https://zlib.net/zlib-1.3.1.tar.gz && \
    tar -xzf zlib-1.3.1.tar.gz && \
    cd zlib-1.3.1 && \
    make -f win32/Makefile.gcc PREFIX=x86_64-w64-mingw32- && \
    cp zlib1.dll ${MINGW_PREFIX}/lib/ && \
    cp libz.a ${MINGW_PREFIX}/lib/ && \
    cp zlib.h zconf.h ${MINGW_PREFIX}/include/

2. libfdt (v1.7.0) — Selective Library Build

Since sunxi-tools only requires the core device tree parser and not the full suite of utility binaries, we explicitly target make libfdt:

Dockerfile
RUN git clone https://git.kernel.org/pub/scm/utils/dtc/dtc.git && \
    cd dtc && \
    git checkout v1.7.0 && \
    make libfdt CC=x86_64-w64-mingw32-gcc AR=x86_64-w64-mingw32-ar && \
    cp libfdt/libfdt.a ${MINGW_PREFIX}/lib/ && \
    cp libfdt/libfdt.h libfdt/fdt.h libfdt/fdt_env.h ${MINGW_PREFIX}/include/

3. libusb (v1.0.26) — Binary Integration

To avoid complex Windows driver cross-compilation overhead, we extract pre-compiled static libraries directly from official Windows binaries:

Dockerfile
RUN wget https://github.com/libusb/libusb/releases/download/v1.0.26/libusb-1.0.26.7z && \
    7z x libusb-1.0.26.7z -o/tmp/libusb && \
    cp /tmp/libusb/MinGW64/static/libusb-1.0.a ${MINGW_PREFIX}/lib/ && \
    cp /tmp/libusb/include/libusb-1.0/libusb.h ${MINGW_PREFIX}/include/

Synthesizing Custom pkg-config Files

Pre-compiled binary drops and manual static builds frequently omit .pc metadata tailored to the target path. To enable seamless resolution by the sunxi-tools Makefile, we write custom .pc definitions directly to ${MINGW_PREFIX}/lib/pkgconfig/:

Example: libusb-1.0.pc

Ini, TOML
prefix=/usr/x86_64-w64-mingw32
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include

Name: libusb-1.0
Description: C API for USB device access
Version: 1.0.26
Libs: -L${libdir} -lusb-1.0
Cflags: -I${includedir}

By exporting PKG_CONFIG_PATH=${MINGW_PREFIX}/lib/pkgconfig, x86_64-w64-mingw32-pkg-config effortlessly emits the precise target flags (-L and -I) required during link time.

Development Workflow via Docker Compose

To avoid cluttering the host environment and allow rapid iteration, use docker-compose.yml to bind-mount the local source directory into the container workspace.

docker-compose.yml

YAML
version: '3.8'

services:
  sunxi-builder:
    build: .
    container_name: sunxi_mingw_builder
    volumes:
      - .:/workspace
    stdin_open: true
    tty: true
    working_dir: /workspace


Step-by-Step Execution

  1. Build the Container Image:

    Bash
    docker-compose build
    
  2. Launch Interactive Shell:

    Bash
    docker-compose run sunxi-builder
    
  3. Trigger Cross-Compilation inside Workspace:

    Bash
    make OS=Windows_NT \
    CC=x86_64-w64-mingw32-gcc \ PKG_CONFIG=x86_64-w64-mingw32-pkg-config \ CROSS_COMPILE=arm-none-eabi-

Upon completion, static Windows binaries (sunxi-fel.exe, sunxi-nand-part.exe, etc.) will be placed directly into your mounted host directory, fully configured and ready for deployment.

Perform Few Checks

x86_64-w64-mingw32-objdump -p sunxi-fel.exe | grep "DLL Name"

        DLL Name: KERNEL32.dll

        DLL Name: msvcrt.dll

        DLL Name: WS2_32.dll


Run the following command to list all the connected all winner SOCs

sunxi-fel.exe -l

USB device 001:027   Allwinner A64     92c000ba:84004620:50344424:2c0b020d


Run the following command to get the version of the tool.

sunxi-fel.exe version

No comments:

Post a Comment