IMX6ULL-ALPHA开发板适配uboot2023.04:从官方EVK到自定义板卡的移植实战
1. 移植前的准备工作在开始移植uboot之前我们需要做好充分的准备工作。首先需要明确的是移植uboot并不是一件简单的事情特别是当我们选择较新的uboot版本时可能会遇到各种兼容性问题。我最初尝试移植uboot官网的最新版本时就遇到了LCD驱动无法正常工作的问题最终不得不转向NXP官方提供的uboot版本。开发环境配置如下开发软件VSCode配合SSH远程连接操作系统Ubuntu 22.04 LTS交叉编译工具链arm-none-linux-gnueabihf-gcc (版本10.3-2021.07)uboot版本NXP官方的uboot-imx-lf_v2023.04开发板硬件配置核心板EMMC 512MB版本底板ALPHA V2.0建议在开始前准备好以下材料正点原子ALPHA开发板的原理图NXP官方EVK开发板的原理图开发板配套的Linux内核源码串口调试工具SD卡和读卡器2. 获取并准备uboot源码移植的第一步是获取正确的uboot源码。我推荐使用NXP官方维护的uboot版本而不是uboot官方的主线版本因为NXP版本已经针对i.MX6ULL处理器做了专门的优化和适配。获取源码的命令如下git clone https://github.com/nxp-imx/uboot-imx.git -b lf_v2023.04下载完成后解压源码并进入目录。我习惯使用VSCode进行代码编辑因为它提供了很好的代码导航和搜索功能对于uboot这样的大型项目非常有用。在开始修改前建议先编译一次原始代码确保基础环境没有问题make mx6ull_14x14_evk_defconfig make ARCHarm CROSS_COMPILEarm-none-linux-gnueabihf- -j20如果编译成功说明你的交叉编译工具链和环境配置是正确的可以开始移植工作了。3. 创建板级配置文件移植的核心工作就是创建适合ALPHA开发板的配置文件。我们从最简单的配置文件开始复制EVK的默认配置文件cp configs/mx6ull_14x14_evk_emmc_defconfig configs/mx6ull_alpha_defconfig修改关键配置项将CONFIG_TARGET_MX6ULL_14X14_EVKy改为CONFIG_TARGET_MX6ULL_ALPHAy将CONFIG_DEFAULT_DEVICE_TREEimx6ull-14x14-evk改为CONFIG_DEFAULT_DEVICE_TREEimx6ull-alpha这里需要注意设备树名称的修改非常重要它决定了uboot启动时加载哪个设备树文件。ALPHA开发板与EVK开发板在外设上有不少差异我们需要通过设备树来正确描述这些差异。4. 添加板级支持文件接下来需要创建ALPHA开发板的板级支持文件。这个过程相对繁琐但方法很直接复制EVK的板级目录cp -r board/freescale/mx6ullevk board/freescale/mx6ullalpha重命名关键文件cd board/freescale/mx6ullalpha mv mx6ullevk.c mx6ullalpha.c修改Kconfig文件 需要将文件中所有的MX6ULLEVK替换为MX6ULLALPHA确保编译系统能够识别我们的新板型。修改MAINTAINERS文件 更新维护者信息虽然我们可以保留原来的维护者邮箱但需要将文件名和路径都改为ALPHA相关的。修改Makefile 将obj-y : mx6ullevk.o改为obj-y : mx6ullalpha.o这些修改看似简单但需要非常仔细任何一个小错误都可能导致编译失败或者运行时出现问题。建议每修改一个文件后都保存并检查是否有遗漏。5. 修改板级初始化代码mx6ullalpha.c文件是板级初始化的核心需要仔细修改。主要修改点包括修改checkboard函数int checkboard(void) { puts(Board: MX6ULL ALPHA\n); return 0; }修改运行时配置#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG env_set(board_name, ALPHA); env_set(board_rev, 14X14); #endif根据ALPHA开发板的实际硬件调整外设初始化代码特别是GPIO、网络PHY和LCD相关的配置。这部分修改需要参考ALPHA开发板的原理图确保每个外设的引脚配置与硬件一致。例如网络PHY的复位引脚、LCD的背光控制引脚等都可能与EVK开发板不同。6. 添加板级头文件头文件包含了很多重要的配置参数我们需要为ALPHA开发板创建专用的头文件复制并重命名头文件cp include/configs/mx6ullevk.h include/configs/mx6ullalpha.h修改关键定义将__MX6ULLEVK_CONFIG_H改为__MX6ULLALPHA_CONFIG_H修改findfdt和findtee函数的实现使其指向ALPHA开发板对应的设备树文件根据ALPHA开发板的硬件特性调整以下参数内存布局参数环境变量存储位置启动参数网络配置特别要注意的是环境变量的存储位置ALPHA开发板使用的EMMC可能与EVK开发板的分区布局不同需要确保uboot能够正确读写环境变量。7. 配置Kconfig系统为了让我们的新板型能够出现在配置菜单中需要修改Kconfig文件在arch/arm/mach-imx/mx6/Kconfig中添加config TARGET_MX6ULL_ALPHA bool Support mx6ull_alpha depends on MX6ULL select BOARD_LATE_INIT select DM select DM_THERMAL select IOMUX_LPSR select IMX_MODULE_FUSE select OF_SYSTEM_SETUP imply CMD_DM添加板级Kconfig的引用source board/freescale/mx6ullalpha/Kconfig这些修改确保了在运行make menuconfig时能够选择我们的ALPHA开发板配置并且包含必要的驱动和功能支持。8. 添加设备树文件设备树是现代Linux系统硬件描述的核心uboot也依赖设备树来描述硬件。我们需要为ALPHA开发板创建专用的设备树文件复制EVK的设备树文件cp arch/arm/dts/imx6ull-14x14-evk.dts arch/arm/dts/imx6ull-alpha.dts cp arch/arm/dts/imx6ul-14x14-evk.dtsi arch/arm/dts/imx6ull-alpha.dtsi cp arch/arm/dts/imx6ull-14x14-evk-u-boot.dtsi arch/arm/dts/imx6ull-alpha-u-boot.dtsi修改主设备树文件更新model和compatible属性根据ALPHA开发板的硬件调整外设配置添加或删除不用的外设节点特别注意EMMC配置 ALPHA开发板使用的是8位总线宽度的EMMC需要确保usdhc2节点配置正确usdhc2 { pinctrl-names default, state_100mhz, state_200mhz; pinctrl-0 pinctrl_usdhc2_8bit; pinctrl-1 pinctrl_usdhc2_8bit_100mhz; pinctrl-2 pinctrl_usdhc2_8bit_200mhz; bus-width 8; non-removable; status okay; };设备树的修改需要非常小心特别是引脚复用配置一个错误的配置可能导致外设无法工作甚至系统无法启动。建议每次修改后都对照原理图检查。9. 网络驱动移植ALPHA开发板使用的网络PHY与EVK开发板不同需要进行相应的修改修改配置文件 在mx6ull_alpha_defconfig中将PHY驱动从Micrel改为SMSC# CONFIG_PHY_MICREL is not set # CONFIG_PHY_MICREL_KSZ8XXX is not set CONFIG_PHY_SMSCy修改设备树 更新网络相关的节点添加复位引脚配置fec2 { pinctrl-names default; pinctrl-0 pinctrl_enet2 pinctrl_enet2_reset; phy-mode rmii; phy-handle ethphy1; phy-reset-gpios gpio5 8 GPIO_ACTIVE_LOW; phy-reset-duration 200; status okay; };添加复位引脚配置pinctrl_enet2_reset:enet2resetgrp { fsl,pins MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x10B0 ; };修改PHY驱动 在drivers/net/phy/phy.c的genphy_config_aneg函数中添加PHY复位代码int genphy_config_aneg(struct phy_device *phydev) { int result; phy_reset(phydev); // 添加的复位代码 ... }完成这些修改后网络功能应该可以正常工作。可以通过以下命令测试网络setenv eth1addr 32:34:46:78:9A:DD setenv serverip 192.168.8.2 setenv ipaddr 192.168.8.3 saveenv ping ${serverip}10. LCD驱动移植LCD驱动的移植相对复杂需要根据具体的LCD屏幕参数进行配置修改设备树中的LCD配置lcdif { pinctrl-names default; pinctrl-0 pinctrl_lcdif_dat pinctrl_lcdif_ctrl; display display0; status okay; display0: display0 { bits-per-pixel 24; bus-width 24; display-timings { native-mode timing0; timing0: timing0 { clock-frequency 9200000; hactive 480; vactive 272; hfront-porch 8; hback-porch 4; hsync-len 41; vback-porch 2; vfront-porch 4; vsync-len 10; hsync-active 0; vsync-active 0; de-active 1; pixelclk-active 0; }; }; }; };根据实际LCD参数调整clock-frequency像素时钟频率hactive/vactive分辨率hfront-porch/hback-porch/hsync-len水平同步参数vfront-porch/vback-porch/vsync-len垂直同步参数这些参数需要严格遵循LCD手册中的时序要求任何参数错误都可能导致显示异常。正点原子的开发板配套资料中通常会提供这些参数。11. 解决常见问题在移植过程中可能会遇到各种问题以下是一些常见问题及解决方法uboot启动时显示信息不全 这是uboot的一个已知问题可以通过reset命令重启uboot来显示完整信息。内核启动失败 可能是设备树配置问题尝试删除OF_SYSTEM_SETUP选项config TARGET_MX6ULL_ALPHA ... # select OF_SYSTEM_SETUP # 注释掉这行 ...校验码错误 修改board/freescale/mx6ullalpha/imximage.cfg文件中的校验参数DATA 4 0x021B083C 0x01380138 DATA 4 0x021B0848 0x40402E32 DATA 4 0x021B0850 0x40403432编译错误确保所有文件重命名和路径修改都正确检查Kconfig和Makefile中的拼写错误清理工程后重新编译make distclean12. 编译与测试完成所有修改后可以创建一个编译脚本简化编译过程#!/bin/bash make distclean make mx6ull_alpha_defconfig make ARCHarm CROSS_COMPILEarm-none-linux-gnueabihf- -j20给脚本添加执行权限chmod x mkuboot.sh运行脚本编译uboot./mkuboot.sh编译成功后会生成以下重要文件u-boot.bin原始的uboot二进制文件u-boot-dtb.bin包含设备树的uboot二进制文件u-boot.imx添加了NXP特定头部的uboot镜像将生成的u-boot.imx烧写到SD卡或EMMC中上电测试。如果一切正常你应该能看到uboot启动日志并且能够通过串口与uboot交互。13. 优化与调试uboot移植完成后还可以进行一些优化工作优化启动速度减少不必要的驱动初始化调整环境变量优化bootcmd添加自定义命令 可以在uboot中添加一些方便调试的自定义命令比如读取传感器数据、控制GPIO等。调试技巧使用bdinfo命令查看板级信息使用md和mm命令查看和修改内存使用dm tree命令查看设备模型移植过程中串口调试是最重要的手段。建议在关键初始化函数中添加调试打印帮助定位问题。14. 总结与经验分享uboot移植是一个需要耐心和细致的工作。通过这次IMX6ULL-ALPHA开发板的uboot移植我总结了以下几点经验版本选择很重要 不要盲目追求最新版本的uboot稳定性和兼容性更重要。NXP官方维护的uboot版本通常比uboot官方主线版本更适合i.MX系列处理器。方法比细节重要 uboot移植有一套固定的模式和方法掌握这些方法比记住每个配置细节更重要。核心思路就是替换与适配——找到参考板的配置然后逐步修改适配到目标板。调试是成功的关键 遇到问题时要学会使用uboot提供的调试工具和命令。有时候一个小小的环境变量设置错误就可能导致系统无法启动。文档和社区是宝贵资源 uboot的官方文档、NXP的参考手册以及各种技术社区都是解决问题的好去处。很多问题可能已经有现成的解决方案。保持代码整洁 在修改uboot代码时保持代码的整洁和可读性。添加适当的注释方便日后维护和升级。移植完成后建议保存好所有的修改最好能够打上标签或者创建分支方便后续维护和升级。同时记录下移植过程中遇到的问题和解决方法形成文档这对以后的工作会有很大帮助。