Skip to main content

Bootloader Development

This guide covers bootloader development for embedded Linux systems, focusing on U-Boot for the Rock 5B+ platform.

Understanding Bootloaders

1. Boot Process Overview

┌─────────────────────────────────────┐
│ Power On │
├─────────────────────────────────────┤
│ ROM Bootloader │
├─────────────────────────────────────┤
│ U-Boot │
├─────────────────────────────────────┤
│ Linux Kernel │
├─────────────────────────────────────┤
│ Init Process │
├─────────────────────────────────────┤
│ User Space │
└─────────────────────────────────────┘

2. Bootloader Responsibilities

  • Hardware Initialization: CPU, memory, peripherals
  • Device Tree Loading: Hardware configuration
  • Kernel Loading: Load and start Linux kernel
  • Environment Management: Boot parameters and configuration
  • Recovery Mode: System recovery and updates

U-Boot Development

1. U-Boot Source Code

# Clone U-Boot source
git clone https://github.com/radxa/u-boot.git -b stable-5.10-rock5
cd u-boot

# Configure for Rock 5B+
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- rock5b_defconfig

# Build U-Boot
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)

2. U-Boot Configuration

# Edit configuration
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig

# Key configuration options:
# - CONFIG_ARM64=y
# - CONFIG_ROCKCHIP_RK3588=y
# - CONFIG_CMD_BOOTZ=y
# - CONFIG_CMD_DTB=y

3. Custom U-Boot Commands

// Custom command implementation
#include <common.h>
#include <command.h>

static int do_mycommand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
if (argc < 2) {
printf("Usage: mycommand <parameter>\n");
return CMD_RET_USAGE;
}

printf("My command executed with parameter: %s\n", argv[1]);

return CMD_RET_SUCCESS;
}

U_BOOT_CMD(
mycommand, 2, 1, do_mycommand,
"My custom command",
"parameter - Description of parameter"
);

Device Tree Configuration

1. Device Tree Basics

// rock5b.dts
/dts-v1/;

#include "rk3588.dtsi"

/ {
model = "Radxa ROCK 5B";
compatible = "radxa,rock-5b", "rockchip,rk3588";

chosen {
stdout-path = "serial2:1500000n8";
bootargs = "console=ttyS2,1500000n8";
};

memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x80000000>;
};
};

2. Custom Device Tree

// Custom device tree overlay
/dts-v1/;
/plugin/;

/ {
fragment@0 {
target-path = "/";

__overlay__ {
my-custom-device {
compatible = "my,custom-device";
status = "okay";
my-parameter = <0x12345678>;
};
};
};
};

Boot Environment

1. U-Boot Environment Variables

# Set boot environment
setenv bootargs 'console=ttyS2,1500000n8 root=/dev/mmcblk0p2 rw'
setenv bootcmd 'load mmc 0:1 0x80080000 Image; load mmc 0:1 0x80000000 rk3588-rock-5b.dtb; booti 0x80080000 - 0x80000000'
setenv bootdelay 3

# Save environment
saveenv

2. Boot Scripts

# Create boot script
echo 'load mmc 0:1 0x80080000 Image' > boot.scr
echo 'load mmc 0:1 0x80000000 rk3588-rock-5b.dtb' >> boot.scr
echo 'booti 0x80080000 - 0x80000000' >> boot.scr

# Compile script
mkimage -C none -A arm64 -T script -d boot.scr boot.scr.uimg

Bootloader Debugging

1. Serial Console Debugging

# Connect serial console
# Baud rate: 1500000
# Data bits: 8
# Stop bits: 1
# Parity: None
# Flow control: None

# U-Boot debug commands
md 0x80000000 100 # Memory dump
mm 0x80000000 # Memory modify
mw 0x80000000 0x12345678 # Memory write

2. Network Boot

# Configure network
setenv ipaddr 192.168.1.100
setenv serverip 192.168.1.1
setenv netmask 255.255.255.0
setenv gatewayip 192.168.1.1

# Boot from network
tftp 0x80080000 Image
tftp 0x80000000 rk3588-rock-5b.dtb
booti 0x80080000 - 0x80000000

Custom Bootloader Features

1. Recovery Mode

// Recovery mode implementation
#include <common.h>
#include <command.h>

static int recovery_mode = 0;

static int do_recovery(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
recovery_mode = 1;
printf("Entering recovery mode...\n");

// Load recovery image
if (load_recovery_image()) {
printf("Recovery image loaded successfully\n");
return CMD_RET_SUCCESS;
} else {
printf("Failed to load recovery image\n");
return CMD_RET_FAILURE;
}
}

U_BOOT_CMD(
recovery, 1, 1, do_recovery,
"Enter recovery mode",
""
);

2. Secure Boot

// Secure boot implementation
#include <common.h>
#include <crypto.h>

static int verify_kernel_signature(void *kernel, size_t size)
{
// Load public key
// Verify signature
// Return verification result
return 1; // Placeholder
}

static int secure_boot(void)
{
if (verify_kernel_signature(kernel_addr, kernel_size)) {
printf("Kernel signature verified\n");
return 0;
} else {
printf("Kernel signature verification failed\n");
return -1;
}
}

Bootloader Optimization

1. Boot Time Optimization

// Optimize boot time
static void optimize_boot_time(void)
{
// Disable unnecessary peripherals
// Optimize memory initialization
// Use faster boot methods
// Minimize delay loops
}

2. Memory Optimization

// Memory usage optimization
static void optimize_memory_usage(void)
{
// Use stack for temporary data
// Minimize global variables
// Use const data where possible
// Optimize data structures
}

Testing and Validation

1. Bootloader Testing

# Test bootloader functionality
# 1. Power cycle testing
# 2. Boot time measurement
# 3. Memory testing
# 4. Peripheral testing
# 5. Recovery mode testing

2. Automated Testing

#!/bin/bash
# Automated bootloader testing script

echo "Testing U-Boot functionality..."

# Test basic commands
echo "Testing basic commands..."
uboot_test_commands

# Test boot process
echo "Testing boot process..."
uboot_test_boot

# Test recovery mode
echo "Testing recovery mode..."
uboot_test_recovery

echo "All tests completed"

Best Practices

1. Code Organization

  • Use modular design
  • Implement proper error handling
  • Document all functions
  • Use consistent coding style
  • Implement proper logging

2. Security Considerations

  • Implement secure boot
  • Use encrypted storage
  • Validate all inputs
  • Implement access control
  • Regular security updates

3. Performance Optimization

  • Minimize boot time
  • Optimize memory usage
  • Use efficient algorithms
  • Profile critical paths
  • Regular performance testing

Next Steps

Resources