Exynos 4412开发板U-Boot移植实战从零构建完整启动环境当一块非官方评估板的开发板如FS4412拿到手时最令人头疼的问题往往是启动环境的适配。不同于官方评估板开箱即用的体验这类开发板需要开发者深入U-Boot源码进行一系列针对性的修改。本文将带你完整走过Exynos 4412开发板的U-Boot移植全过程从源码获取到最终烧写每个步骤都配有详细的代码修改清单和原理说明。1. 准备工作与环境搭建在开始移植前我们需要建立一个清晰的开发环境。不同于简单的应用开发U-Boot移植对工具链和开发环境有特定要求工具链选择推荐使用Linaro GCC 4.7或更高版本这是经过验证对ARMv7架构支持最好的工具链之一开发主机建议使用Ubuntu 18.04/20.04 LTS避免因glibc版本问题导致的兼容性错误源码获取U-Boot官方仓库中针对Exynos 4412的支持从2013.10版本开始成熟# 获取U-Boot源码 git clone git://git.denx.de/u-boot.git cd u-boot git checkout v2023.04 -b exynos4412提示建议在源码目录外单独建立工作目录存放移植补丁和构建脚本保持源码树的干净开发板硬件确认清单串口调试接口引脚定义通常为J1连接器核心板内存配置DDR3容量与时序存储设备类型eMMC/NAND Flash网络PHY型号如DM9000AEP2. 基础移植板级支持包创建U-Boot对非官方开发板的支持始于创建一个新的板级支持包(BSP)。以FS4412为例我们需要基于最接近的官方板通常是Origen进行适配。2.1 创建板级目录结构在board/samsung/目录下创建fs4412子目录复制origen板的相关文件mkdir -p board/samsung/fs4412 cp board/samsung/origen/* board/samsung/fs4412/需要重命名的关键文件origen.c→fs4412.corigen.h→fs4412.hMakefile中的目标名变更2.2 修改boards.cfg配置在顶层目录的boards.cfg文件中添加新板配置fs4412 arm armv7 fs4412 samsung exynos对应的各字段含义为板名称架构CPU类型板级目录厂商目录SoC系列2.3 基础编译测试执行初始配置和编译make fs4412_config make -j4此时生成的u-boot.bin还不能正常运行但可以验证基础编译环境是否正常。常见问题排查工具链路径错误检查CROSS_COMPILE变量设置依赖缺失安装libssl-dev和bison/flex版本冲突确保工具链与U-Boot版本匹配3. 关键外设驱动移植基础框架搭建完成后需要逐个移植关键外设驱动。这是确保开发板基本功能可用的关键步骤。3.1 串口调试输出配置串口是开发阶段最重要的调试手段修改board/samsung/fs4412/lowlevel_init.S/* 在lowlevel_init中添加串口初始化 */ ldr r0, 0x13800000 Exynos4412 UART2基址 mov r1, #0x0 str r1, [r0, #0x08] UFCON mov r1, #0x3 str r1, [r0, #0x0C] UMCON mov r1, #0x5 str r1, [r0] UBRDIV对应的时钟配置需要添加到fs4412.c中/* 在board_init函数中添加 */ writel((readl(0x1003C000) | (0x124)), 0x1003C000); // UART时钟门控 writel(0x666666, 0x10010210); // CLK_SRC_PERIL0 writel(0x7777, 0x10010214); // CLK_DIV_PERIL03.2 DM9000网卡驱动适配FS4412通常采用DM9000AEP网卡需要修改以下文件include/configs/fs4412.h中添加#define CONFIG_DRIVER_DM9000 #define CONFIG_DM9000_BASE 0x05000000 #define DM9000_IO CONFIG_DM9000_BASE #define DM9000_DATA (CONFIG_DM9000_BASE 4) #define CONFIG_DM9000_USE_16BITboard/samsung/fs4412/fs4412.c中添加GPIO配置/* 网卡GPIO初始化 */ writel(0x00220020, 0x11000000 0x120); // GPK0CON writel(0x00002222, 0x11000000 0x140); // GPK0PUD3.3 eMMC/SD卡驱动移植Exynos 4412的存储控制器支持eMMC4.4协议需要特别注意时钟配置/* 在fs4412.c中添加eMMC初始化 */ #define EXYNOS4_CLOCK_BASE 0x10030000 #define CLK_SRC_FSYS_OFFSET 0x10C40 #define CLK_DIV_FSYS3_OFFSET 0x10C48 void emmc_init(void) { /* 时钟源选择MPLL */ writel((readl(EXYNOS4_CLOCK_BASE CLK_SRC_FSYS_OFFSET) ~0xF0000) | 0x60000, EXYNOS4_CLOCK_BASE CLK_SRC_FSYS_OFFSET); /* 分频设置 */ writel((readl(EXYNOS4_CLOCK_BASE CLK_DIV_FSYS3_OFFSET) ~0xFF0F) | 0x1001, EXYNOS4_CLOCK_BASE CLK_DIV_FSYS3_OFFSET); }对应的GPIO配置/* eMMC引脚配置 */ writel(0x33333333, 0x11000040); // GPK0CON writel(0x0000FFFF, 0x11000048); // GPK0PUD4. 启动流程深度定制商业开发板通常需要添加厂商特定的启动校验和加密流程这部分需要特别注意与硬件设计的配合。4.1 BL1引导加载器集成Exynos 4412采用两级启动机制需要在U-Boot前添加三星提供的BL1# 生成最终镜像的shell脚本 #!/bin/bash make -j4 split -b 14336 u-boot.bin bl2 ./sdfuse_q/chksum ./sdfuse_q/add_padding cat E4412_N.bl1.bin bl2.bin u-boot.bin final.bin注意BL1二进制文件需要从开发板供应商处获取不同PCB版本可能不兼容4.2 启动设备检测机制为支持多种启动方式SD卡/eMMC需要添加启动设备检测逻辑int board_late_init(void) { char *boot_device getenv(bootdevice); if (!boot_device) { if (/* 检测SD卡 */) { setenv(bootdevice, mmc); } else if (/* 检测eMMC */) { setenv(bootdevice, emmc); } } return 0; }对应的设备树需要添加/ { chosen { bootargs consolettySAC2,115200 root/dev/mmcblk0p2 rootwait; }; };5. 调试技巧与问题排查U-Boot移植过程中有效的调试手段可以大幅提高效率。以下是经过验证的实用技巧5.1 LED调试法在关键代码路径添加LED控制帮助定位启动卡死位置/* 在start.S中添加 */ ldr r0, 0x11000100 GPX1CON ldr r1, [r0] bic r1, r1, #0xF0000000 orr r1, r1, #0x10000000 str r1, [r0] 配置GPX1_7为输出 ldr r0, 0x11000104 GPX1DAT mov r1, #0x80 str r1, [r0] 点亮LED5.2 内存检测方法DDR初始化是常见问题点添加内存测试命令int do_memtest(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { ulong start CONFIG_SYS_SDRAM_BASE 0x100000; ulong end start 0x100000; memory_test(start, end, 0xAAAAAAAA, 0x55555555); return 0; } U_BOOT_CMD( memtest, 1, 1, do_memtest, simple memory test, );5.3 常见问题解决方案串口无输出检查UART时钟配置验证串口引脚复用设置确认终端软件波特率(通常115200)网卡无法工作用示波器检测DM9000的片选信号检查PHY复位电路时序验证MAC地址配置eMMC识别失败确认时钟频率不超过200MHz检查CMD/DATA线上拉电阻验证电源稳定时间6. 高级功能定制基础功能稳定后可以考虑添加提升开发效率的高级功能。6.1 快速启动优化通过裁剪不必要的功能和命令减少启动时间/* 在include/configs/fs4412.h中禁用 */ #undef CONFIG_CMD_NET #undef CONFIG_CMD_NFS #undef CONFIG_CMD_PING /* 减小环境变量区 */ #define CONFIG_ENV_SIZE 0x20006.2 安全启动实现添加简单的镜像校验机制int verify_image(ulong addr, ulong size) { ulong checksum 0; ulong *p (ulong *)addr; for (int i 0; i size/4; i) { checksum *p; } return (checksum *(p 1)); }6.3 量产工具集成创建自动化烧写脚本#!/bin/bash # fs4412_program.sh sudo dd if/dev/zero of$1 bs512 seek1 count2047 sudo dd ifu-boot.bin of$1 bs512 seek1 convnotrunc sync7. 完整源码修改清单以下是所有需要修改的文件及其关键变更点文件路径修改内容备注board/samsung/fs4412/Makefile目标名变更origen→fs4412include/configs/fs4412.h添加板级配置宏网络、存储等arch/arm/cpu/armv7/start.S添加LED调试代码早期调试用board/samsung/fs4412/lowlevel_init.S串口初始化确保调试输出common/main.c修改启动延时设为0快速启动drivers/mmc/s5p_mshc.c添加eMMC支持4.4/4.5协议关键补丁示例--- a/board/samsung/fs4412/fs4412.c b/board/samsung/fs4412/fs4412.c -15,6 15,7 #include asm/arch/cpu.h #include asm/arch/mmc.h #include asm/arch/power.h #include asm/arch/sromc.h DECLARE_GLOBAL_DATA_PTR; -22,6 23,10 { struct exynos4_power *pwr (struct exynos4_power *)EXYNOS4_POWER_BASE; /* 初始化网卡 */ dm9000aep_pre_init(); s5p_config_sromc(); gd-bd-bi_boot_params PHYS_SDRAM_1 0x100;移植完成后建议使用git维护所有修改git init git add . git commit -m Initial port for FS4412 board这样既方便后续升级也能清晰追踪每个修改的目的。当需要同步新版U-Boot时可以通过git rebase减少合并冲突。