2. 目标硬件平台分析
BSP 移植的第一步不是写代码,而是把目标板“读透”。同一颗 SoC 在不同板子上,内存映射、外设挂载、时钟来源、启动介质都可能不同,BSP 里大量配置项(如 CONFIG_...、设备树节点、链接地址、串口基址)都直接由这些硬件事实决定。本节给出一套可复用的梳理方法:以 SoC 数据手册(Datasheet/TRM)和板级原理图(Schematic)为两个信息源,交叉核对出六类关键信息,并落成一份可交付的《目标平台硬件信息表》。
一、处理器架构:先确定“编译目标”
架构决定了工具链、指令集、字节序、异常模型和启动入口。需要确认的字段包括:内核型号(如 Cortex-A53、Cortex-M7、RISC-V U74)、架构版本(ARMv8-A / RV64GC)、位宽(32/64 位)、字节序(小端/大端)、核数(单核/多核 SMP)、是否含 MMU/MPU、浮点与 SIMD 支持(NEON/FPU)。这些直接映射到交叉编译前缀,例如 64 位 ARM 常用 aarch64-linux-gnu-,32 位 ARM 常用 arm-linux-gnueabihf-,RISC-V 常用 riscv64-linux-gnu-。
实操中建议用一条命令验证工具链与目标是否匹配,而不是凭型号猜测:
# 查看工具链默认目标
aarch64-linux-gnu-gcc -dumpmachine
# 输出示例:aarch64-linux-gnu
# 查看目标 ELF 的架构属性
aarch64-linux-gnu-readelf -h vmlinux | grep -E "Machine|Class|Data"
# 期望:AArch64 / ELF64 / little endian
若 Machine 与内核型号不符,后续所有镜像都无法运行,因此这一步必须在移植早期完成。
二、内存映射:地址空间是 BSP 的“坐标系”
内存映射回答三个问题:物理地址范围、各区域的用途、以及 CPU 视角与外设视角是否一致。梳理时按“区域—起始地址—大小—属性”四列记录,典型区域包括:DDR 主存、片上 SRAM/TCM、BootROM、外设寄存器区(Peripheral/APB/AHB)、保留区。属性需标注是否可缓存(Cacheable)、是否可缓冲(Bufferable)、是否可执行(XN)。
例如某 Cortex-A53 平台(示例参数,非实测):DDR 起始 0x4000_0000,大小 2 GiB;外设区 0x0A00_0000 起,大小 64 MiB,属性为 Device-nGnRnE;BootROM 位于 0x0000_0000,大小 128 KiB。这些值将直接写入设备树 reg 属性和内核 mem= 参数。
关键动作是核对“同一外设的基址在 TRM 与原理图中是否一致”。TRM 给的是 SoC 内部地址,原理图给的是板级连接,两者在地址译码上必须吻合;若板上有地址重映射(如 PCIe 窗口、FPGA 映射区),需单独列出。
三、外设清单与时钟树:从“有什么”到“怎么配”
外设清单按接口类型分组:存储类(eMMC/SD/NAND/QSPI Flash)、通信类(UART/I2C/SPI/CAN/USB/以太网)、显示与音频(MIPI-DSI/HDMI/I2S)、调试类(JTAG/SWD/UART)。每个外设记录:控制器实例号、基址、中断号(GIC SPI/PPI)、引脚复用(Pinmux)、供电域、以及依赖的时钟与复位。
时钟树是外设能否工作的前提。梳理顺序为:晶振(如 24 MHz)→ PLL(如 CPU PLL、DDR PLL、外设 PLL)→ 分频器 → 各外设时钟门控。需要记录每个外设的时钟源、目标频率、分频比和门控位。例如 UART0 时钟源为 OSC24M,经分频得到 24 MHz,再按波特率 115200 计算分频系数;若时钟树配错,串口会输出乱码而非无输出,这是排障时的重要区分点。
四、启动介质与调试接口:决定“怎么跑起来、怎么看”
启动介质决定 BootROM 的搜索顺序和镜像格式。常见组合:eMMC(含 Boot Partition 与 User Area)、SD 卡、QSPI NOR/NAND、UART/USB 下载模式。需要确认:启动模式引脚(Boot Mode Strap)的默认电平、BootROM 支持的介质优先级、镜像头部格式(如 i.MX 的 IVT/DCD、Allwinner 的 eGON、Rockchip 的 IDB)。若启动模式引脚被板上电阻固定,则无法通过软件切换,必须记录实际电平。
调试接口是移植过程中的“眼睛”。至少保留一路 UART 作为早期控制台,记录其基址、波特率、引脚;JTAG/SWD 用于在 BootROM 阶段单步,需记录 TDI/TDO/TCK/TMS 引脚与电平标准(1.8 V/3.3 V)。若板上无 JTAG 引出,则只能依赖串口日志,此时串口必须在 SPL 阶段就初始化成功。
五、可交付成果:目标平台硬件信息表
把上述六类信息汇总为一张表,作为后续设备树编写、内核配置和排障的基线。下表为示例结构(数值为教学示例,非实测):
| 类别 | 项目 | 示例值 | 来源 | BSP 落地位置 |
|---|---|---|---|---|
| 架构 | 内核/位宽/字节序 | Cortex-A53 / 64 位 / 小端 | TRM | 工具链前缀、-march |
| 内存映射 | DDR 起始/大小 | 0x4000_0000 / 2 GiB | TRM | 设备树 memory 节点 |
| 内存映射 | 外设区基址/属性 | 0x0A00_0000 / Device-nGnRnE | TRM | 设备树 soc 节点 |
| 外设 | UART0 基址/中断 | 0x0A10_0000 / SPI 32 | TRM+原理图 | 设备树 uart0 节点 |
| 时钟树 | UART0 时钟源/频率 | OSC24M / 24 MHz | TRM | 设备树 clocks 属性 |
| 启动介质 | 启动模式/镜像格式 | eMMC / IVT+DCD | 原理图+TRM | SPL 配置、烧录脚本 |
| 调试接口 | 控制台 UART / JTAG | UART0 115200 / 1.8 V SWD | 原理图 | 内核 cmdline、OpenOCD 配置 |