4. 生成并烧写bootloader

任务目标

在Android SoC BSP开发中,bootloader(通常为U-Boot)负责初始化硬件并引导内核。本案例以全志A33平台为例,完成U-Boot的交叉编译、生成boot.img镜像,并通过fastboot烧写到开发板的eMMC启动分区。

环境依赖

  • Ubuntu 18.04+主机,已安装交叉编译工具链:arm-linux-gnueabihf-(32位)或aarch64-linux-gnu-(64位SoC)
  • U-Boot源码(版本2018.05+,支持目标板配置)
  • 开发板进入fastboot模式(通常按住BOOT键上电)
  • 主机已安装fastboot工具(sudo apt install android-tools-fastboot)

关键实现

以下以全志A33(Cortex-A7)为例,展示从配置到生成boot.img的完整编译流程。核心步骤为:加载板级默认配置 → 交叉编译 → 使用mkimage打包生成Android boot镜像。

#!/bin/bash
# build_uboot_a33.sh - 全志A33 U-Boot编译脚本

set -e

# 1. 环境变量
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm

# 2. 进入U-Boot源码目录(请根据实际路径修改)
cd u-boot-2018.05

# 3. 清理旧配置
make distclean

# 4. 加载A33开发板默认配置(以实际板卡配置名为准)
make A33_Lichee_Defconfig

# 5. 编译U-Boot(生成u-boot.bin)
make -j$(nproc)

# 6. 生成Android boot.img(包含U-Boot头部+镜像)
#    全志平台使用mkimage工具打包,输出boot.img
#    参数说明:
#    -A arm     : ARM架构
#    -O linux   : 操作系统为Linux
#    -T kernel  : 镜像类型为内核(bootloader也使用此格式)
#    -C none    : 不压缩
#    -a 0x4a000000 : 加载地址(A33平台固定)
#    -e 0x4a000000 : 入口地址
#    -n 'A33 U-Boot' : 镜像名称
#    -d u-boot.bin : 输入文件
mkimage -A arm -O linux -T kernel -C none \
        -a 0x4a000000 -e 0x4a000000 \
        -n 'A33 U-Boot' -d u-boot.bin boot.img

echo "编译完成,生成 boot.img"
ls -lh boot.img

烧写步骤

# 1. 开发板进入fastboot模式后,USB连接主机,验证设备识别
fastboot devices

# 2. 烧写boot.img到boot分区(全志平台bootloader分区名为boot)
fastboot flash boot boot.img

# 3. 重启开发板
fastboot reboot

验证方法

  1. 编译验证:脚本执行无报错,且boot.img文件生成,大小约300KB~1MB(取决于U-Boot功能配置)。
  2. 烧写验证:fastboot flash命令返回OKAY,无FAILED错误。
  3. 启动验证:开发板重启后,串口终端(波特率115200)应输出U-Boot启动日志,包含U-Boot 2018.05版本信息及硬件初始化打印,最终停留在Hit any key to stop autoboot提示符。

常见问题

  • fastboot无法识别设备:检查USB线缆是否支持数据传输,安装驱动(Linux下通常无需额外驱动),确认开发板确实进入fastboot模式(可观察屏幕或串口提示)。
  • 编译报错缺少头文件:确认交叉编译工具链已安装且CROSS_COMPILE路径正确,执行arm-linux-gnueabihf-gcc -v验证。
  • 烧写后无法启动:确认-a和-e地址与目标SoC的SRAM/DRAM映射一致(A33为0x4a000000),不同SoC地址不同,需查阅芯片手册。