Introduction to Coreboot on RK3399
In the realm of embedded systems and custom hardware development, gaining complete control over the boot process is paramount. Traditional proprietary bootloaders often present a black box, limiting debugging capabilities, customization, and even system security. Coreboot, an open-source, lightweight, and extensible replacement for proprietary BIOS/UEFI firmware, offers a powerful alternative. This guide delves into the intricate process of configuring and flashing Coreboot onto a custom board powered by the Rockchip RK3399 System-on-Chip (SoC) with the ultimate goal of booting Android Open Source Project (AOSP).
The Rockchip RK3399 is a popular ARM-based SoC, widely used in Single Board Computers (SBCs), tablets, and embedded devices, primarily due to its robust performance and versatile I/O. By replacing its default boot firmware with Coreboot, developers can achieve faster boot times, enhanced security, and the flexibility to tailor the boot environment precisely for AOSP, which often demands specific kernel parameters and device tree configurations.
Prerequisites and Setup
Hardware Requirements
- Rockchip RK3399 Custom Board: A prototype board or an existing development board (like Pinebook Pro or Rock Pi 4) where you have physical access to the SPI flash chip.
- SPI Programmer: Essential for reading and writing the SPI flash. Tools like the CH341A programmer, Bus Pirate, or even a Raspberry Pi with `flashrom` can be used.
- Serial Console Adapter: A 3.3V USB-to-TTL serial adapter (e.g., FT232RL or CP2102 based) for debugging boot output.
- JTAG Debugger (Optional but Recommended): For deep-level debugging of CPU initialisation, an ARM-compatible JTAG probe (e.g., Olimex ARM-USB-TINY-H) is invaluable.
- Soldering Equipment: Fine-tipped soldering iron, flux, solder, and potentially an SOIC8 test clip for connecting to the SPI flash without desoldering.
Software Environment
- Linux Host Machine: A modern Linux distribution (Ubuntu or Debian recommended) for building Coreboot and AOSP.
- Coreboot Source Code: The latest Coreboot repository from `coreboot.org`.
- Flashrom Utility: For interacting with the SPI flash chip.
- Coreboot Toolchain Dependencies: Standard build tools, libraries, and cross-compiler components.
- AOSP Source Code (for eventual integration): A compiled AOSP image and its corresponding kernel and device tree files.
Setting Up the Build Environment
First, clone the Coreboot repository and install necessary build tools:
sudo apt update && sudo apt install -y git build-essential bison flex ncurses-dev libftdi1 libftdi-dev libusb-dev libpci-dev m4 subversion python3-dev
Next, build the cross-compiler toolchain, which is crucial for compiling Coreboot for an ARM64 target:
cd coreboot/util/crossgcc./buildgcc ARCH=arm64
This process can take a significant amount of time, depending on your system’s performance. Once completed, the toolchain will be available for Coreboot compilation.
Coreboot Configuration for Rockchip RK3399
Navigate to the Coreboot source directory and initiate the configuration process using `make menuconfig`:
cd corebootmake menuconfig
Within the `menuconfig` interface, you’ll need to select specific options tailored for the RK3399:
- Mainboard: Navigate to `Mainboard` -> `Mainboard vendor` and select `Generic` or `Rockchip`. Then, for `Mainboard model`, choose `Generic Rockchip RK3399 based board`. If your specific board (e.g., Pinebook Pro) has direct Coreboot support, select that.
- Chipset: Under `Chipset`, ensure `Rockchip RK3399` is selected.
- General Setup: Configure `Console output` to `UART`. Set the `Baud rate` to `115200` for your serial debug console.
- Payload: For AOSP integration, a robust payload like U-Boot is typically used to load the Android kernel. Select `Payload` -> `A more flexible payload` -> `U-Boot`. You will need to build U-Boot separately for Coreboot and specify its path under `Path to U-Boot coreboot payload`. The Coreboot community often provides pre-built U-Boot payloads, or you can compile your own with specific configurations for your board’s eMMC/SD boot.
- Binary Blobs: The RK3399, like many modern SoCs, requires proprietary binary blobs for critical hardware initialization, particularly for DRAM. These blobs are usually provided by the SoC vendor or can be extracted from stock firmware. Under `Firmware` -> `Add a binary blob`, specify the path to these necessary blobs (e.g., DDR PHY initialization code). Without these, your board will likely not even power on its RAM.
- Debugging: Enable `Debug Options` -> `Enable verbose output` to get detailed boot messages on your serial console.
After configuring, save your settings and exit `menuconfig`.
Building and Flashing Coreboot
Building the Coreboot Image
With the configuration saved, building the Coreboot ROM image is straightforward:
make
This command compiles Coreboot and its chosen payload, producing the `coreboot.rom` file in the `build/` directory. You can inspect this image using `cbfstool` (Coreboot File System Tool) to verify its contents, such as included payloads and FMAP layout:
./util/cbfstool/cbfstool build/coreboot.rom print
Flashing Coreboot to Your RK3399 Board
This is the most critical and potentially risky step. Improper flashing can brick your board. Always proceed with extreme caution.
-
Identify SPI Flash Chip: Locate the SPI flash chip on your custom board. It’s usually an 8-pin SOIC or WSON package. Refer to your board’s schematics or the chip’s datasheet to identify its pins (VCC, GND, CLK, MISO, MOSI, CS).
-
Connect SPI Programmer: Power off your RK3399 board completely. Connect your SPI programmer to the flash chip using either an SOIC8 test clip or by carefully soldering wires to the pins. Ensure correct pin alignment. Crucially, verify that the board’s power rails are completely off or that the flash chip is isolated if your programmer provides power, to prevent conflicts.
-
Backup Original Firmware: **DO NOT SKIP THIS STEP!** Before writing anything new, always create a backup of your board’s original firmware. This allows you to revert if something goes wrong.
sudo flashrom -p <programmer_type> -r original_firmware.binReplace `<programmer_type>` with your specific programmer, e.g., `ch341a_spi`, `buspirate_spi:dev=/dev/ttyUSB0`, or `rpi_spi:dev=/dev/spidev0.0` for a Raspberry Pi. Verify the backup file size and integrity.
-
Erase and Write Coreboot: Once the backup is secure, you can erase the old firmware and write your new Coreboot image.
sudo flashrom -p <programmer_type> -w build/coreboot.rom --if-ran-no-op --ifitwontrain --erase-allThe `–if-ran-no-op` and `–ifitwontrain` flags are safety measures to prevent `flashrom` from writing if it cannot reliably detect or erase the chip.
-
Verify Write (Optional but Recommended): After writing, it’s good practice to read the flash again and compare it to your Coreboot image to ensure a successful write.
sudo flashrom -p <programmer_type> -r verify_firmware.bin sudo diff build/coreboot.rom verify_firmware.binA successful comparison (`diff` shows no output) indicates a correct flash.
Integrating AOSP with Coreboot
Coreboot’s role is to initialize the fundamental hardware components and then pass control to a payload. For AOSP, this payload is typically U-Boot, which then loads the Android kernel.
U-Boot Configuration for AOSP
If you’re using U-Boot as your Coreboot payload, ensure it’s configured to:
- Initialize necessary peripherals for AOSP (e.g., eMMC, SD card, USB).
- Locate and load the Android kernel (usually `zImage` or `Image.gz-dtb`) and `initramfs` from the designated storage (e.g., eMMC partition).
- Pass the correct `bootargs` to the Android kernel, which are vital for AOSP to function correctly (e.g., root filesystem path, console settings).
Android Kernel and Device Tree
The Android kernel, compiled for ARM64 and patched for your RK3399 board, is fundamental. Critically, the Device Tree Blob (`.dtb`) file, which describes all the hardware components to the kernel, must be correctly configured for your custom board. This `.dtb` is usually generated from `.dts` files within your kernel source (`arch/arm64/boot/dts/rockchip/rk3399-xxx.dts`). Coreboot can embed a basic DTB, but the AOSP kernel typically expects a more complete one.
The overall boot flow will be: Coreboot -> U-Boot (payload) -> Android Kernel (with DTB) -> Android Userspace.
Debugging and Troubleshooting
- Serial Console is Key: Your serial console adapter is your most valuable debugging tool. Connect it to the UART pins on your board and use `minicom` or `screen` to capture boot output.
screen /dev/ttyUSB0 115200
Conclusion
Successfully configuring and flashing Coreboot on a Rockchip RK3399 custom board to run AOSP is a testament to deep hardware understanding and meticulous software engineering. This journey provides unparalleled control over your device’s boot process, enabling faster boot times, enhanced security, and the flexibility to truly customize your hardware-software stack. While challenging, particularly with the reliance on binary blobs and the intricacies of hardware-specific initialization, the rewards for embedded developers and hardware hackers are significant. This detailed guide serves as a foundation, encouraging further exploration into Coreboot’s capabilities and its power to liberate embedded systems from proprietary constraints.
Android Mobile Specs & Compare Directory
Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!
Compare Devices Specs →