保姆级教程:在Ubuntu 20.04上为imx6ull编译并烧写U-Boot 2016.03(含交叉编译环境配置)
深度实战在Ubuntu 20.04上构建imx6ull定制化U-Boot全流程指南当我们需要为嵌入式设备如imx6ull开发板构建引导加载程序时U-Boot无疑是最佳选择之一。作为一款开源的、功能强大的bootloaderU-Boot支持多种架构包括ARM、PowerPC等特别适合嵌入式系统的启动和初始化。本文将详细介绍如何在Ubuntu 20.04系统上从零开始为imx6ull开发板编译并烧写U-Boot 2016.03版本涵盖交叉编译环境配置、源码编译、镜像烧写等完整流程。1. 开发环境准备与工具链配置在开始U-Boot编译之前我们需要确保开发环境已经准备就绪。Ubuntu 20.04是一个稳定且广泛使用的Linux发行版非常适合作为嵌入式开发的宿主系统。首先我们需要安装一些基础开发工具和库sudo apt update sudo apt install -y build-essential git bison flex libssl-dev对于U-Boot的图形化配置界面还需要安装ncurses库sudo apt install -y libncurses5-dev接下来是最关键的交叉编译工具链配置。由于imx6ull采用ARM架构我们需要ARM交叉编译器。这里推荐使用Linaro提供的gcc-linaro-4.9.4版本mkdir -p ~/toolchains cd ~/toolchains wget https://releases.linaro.org/components/toolchain/binaries/4.9-2017.01/arm-linux-gnueabihf/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz sudo mkdir -p /usr/local/arm sudo tar -xvf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf.tar.xz -C /usr/local/arm配置环境变量使系统能够找到交叉编译器echo export PATH$PATH:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin | sudo tee -a /etc/profile source /etc/profile验证交叉编译器是否安装成功arm-linux-gnueabihf-gcc -v如果看到类似下面的输出说明交叉编译器已经正确安装gcc version 4.9.4 (Linaro GCC 4.9-2017.01)2. 获取并配置U-Boot源码有了合适的开发环境和工具链后我们需要获取U-Boot源码并进行配置。对于imx6ull开发板建议使用NXP官方提供的U-Boot版本。首先创建一个工作目录并获取源码mkdir -p ~/workspace/imx6ull cd ~/workspace/imx6ull wget https://source.codeaurora.org/external/imx/uboot-imx/snapshot/uboot-imx-2016.03-2.1.0-g8b546e4.tar.bz2 tar -xvjf uboot-imx-2016.03-2.1.0-g8b546e4.tar.bz2 cd uboot-imx-2016.03-2.1.0-g8b546e4针对不同的imx6ull核心板配置U-Boot提供了多个defconfig文件。例如mx6ull_14x14_ddr256_nand_defconfig256MB DDR3 NAND Flash配置mx6ull_14x14_ddr512_emmc_defconfig512MB DDR3 eMMC配置根据你的开发板硬件配置选择合适的defconfig。这里以512MB DDR3 eMMC配置为例make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig为了简化后续的编译过程可以创建一个编译脚本build_uboot.sh#!/bin/bash make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- distclean make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- -j$(nproc)给脚本添加执行权限chmod x build_uboot.sh3. 编译U-Boot及常见问题解决执行编译脚本开始构建U-Boot./build_uboot.sh编译过程可能会遇到一些问题下面是一些常见问题及解决方案问题1缺少dtc设备树编译器/bin/sh: 1: dtc: not found解决方案sudo apt install -y device-tree-compiler问题2Python相关错误scripts/dtc/pylibfdt/_libfdt.c:2:20: fatal error: Python.h: No such file or directory解决方案sudo apt install -y python3-dev问题3openssl/bio.h缺失fatal error: openssl/bio.h: No such file or directory解决方案sudo apt install -y libssl-dev编译成功后会在当前目录下生成以下重要文件u-boot.bin原始的U-Boot二进制文件u-boot.imx添加了NXP i.MX特定头部信息的U-Boot镜像u-bootELF格式的可执行文件可以使用file命令验证生成的u-boot文件file u-boot正确输出应该显示u-boot: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped4. 烧写U-Boot到开发板编译完成后我们需要将生成的U-Boot镜像烧写到开发板上。对于imx6ull开发板常用的烧写方式有SD卡和eMMC两种。4.1 准备烧写工具我们需要使用imxdownload工具将U-Boot镜像烧写到SD卡。首先获取imxdownload工具cd ~/workspace/imx6ull wget https://github.com/albuer/imxdownload/archive/master.zip unzip master.zip cd imxdownload-master make sudo cp imxdownload /usr/local/bin/4.2 烧写到SD卡插入SD卡到电脑使用lsblk命令查看SD卡设备名通常是/dev/sdXX为字母lsblk确认SD卡设备名后假设为/dev/sdd执行烧写命令cd ~/workspace/imx6ull/uboot-imx-2016.03-2.1.0-g8b546e4 imxdownload u-boot.bin /dev/sdd注意确保指定正确的SD卡设备名错误的设备名可能导致数据丢失。烧写完成后将SD卡插入开发板设置启动模式为SD卡启动通常通过开发板上的拨码开关设置然后上电启动。4.3 通过串口查看输出连接开发板的串口到电脑使用串口终端工具如minicom、picocom或MobaXterm查看启动信息sudo apt install -y picocom picocom -b 115200 /dev/ttyUSB0正常启动后你应该能看到类似下面的U-Boot启动信息U-Boot 2016.03 (Mar 01 2023 - 15:30:45 0800) CPU: Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz) CPU: Industrial temperature grade (-40C to 105C) at 44C Reset cause: POR Board: MX6ULL 14x14 EVK I2C: ready DRAM: 512 MiB MMC: FSL_SDHC: 0, FSL_SDHC: 1 ...5. U-Boot常用命令与功能验证成功启动U-Boot后我们可以使用各种命令来验证系统功能和进行基本操作。以下是一些常用命令示例查看环境变量printenv设置并保存环境变量setenv bootdelay 5 saveenv内存操作命令md.b 0x80000000 10 # 查看内存内容 mm.b 0x80000000 # 修改内存内容 mw.l 0x80000000 0x12345678 10 # 填充内存SD卡/eMMC操作mmc dev 0 # 切换到SD卡 mmc dev 1 # 切换到eMMC mmc info # 查看当前MMC设备信息 mmc list # 列出所有MMC设备网络操作setenv ipaddr 192.168.1.100 setenv serverip 192.168.1.1 ping 192.168.1.1启动内核fatload mmc 0:1 0x80800000 zImage fatload mmc 0:1 0x83000000 imx6ull-14x14-evk.dtb bootz 0x80800000 - 0x830000006. 高级配置与优化对于实际项目开发我们可能需要对U-Boot进行一些定制化配置和优化。6.1 自定义环境变量可以通过修改include/configs/mx6ullevk.h文件来添加默认环境变量#define CONFIG_EXTRA_ENV_SETTINGS \ bootcmdmmc dev 0; fatload mmc 0:1 0x80800000 zImage; \ fatload mmc 0:1 0x83000000 imx6ull-14x14-evk.dtb; \ bootz 0x80800000 - 0x83000000\0 \ bootargsconsolettymxc0,115200 root/dev/mmcblk1p2 rootwait rw\06.2 添加自定义命令可以在cmd目录下添加自定义命令。例如创建一个简单的LED控制命令在cmd目录下创建led.c文件实现命令处理函数修改Makefile添加编译规则修改Kconfig添加配置选项6.3 优化启动速度可以通过以下方式优化U-Boot启动速度减少不必要的驱动初始化禁用详细调试输出优化环境变量加载预计算CRC校验值6.4 安全增强对于安全敏感的应用可以考虑启用HABHigh Assurance Boot验证加密U-Boot镜像禁用不必要的命令和功能设置密码保护7. 常见问题深度解析在实际开发过程中可能会遇到各种问题。下面是一些典型问题的深入分析和解决方案。7.1 DDR初始化失败症状U-Boot启动时卡在DDR初始化阶段。可能原因错误的DDR配置参数PCB布线问题导致信号完整性差电源不稳定解决方案检查board/freescale/mx6ull_14x14_evk目录下的DDR配置使用示波器检查DDR电源和时钟信号尝试降低DDR频率7.2 烧写后无法启动症状烧写U-Boot后开发板无任何反应。可能原因烧写工具参数错误SD卡分区或格式化问题启动模式设置不正确解决方案确认使用正确的imxdownload工具版本确保SD卡已正确分区第一个扇区为启动分区检查开发板启动模式拨码开关设置7.3 网络功能异常症状U-Boot无法ping通主机或下载文件。可能原因网络PHY芯片初始化失败环境变量设置错误硬件连接问题解决方案检查drivers/net/phy目录下的PHY驱动确认环境变量ipaddr、serverip设置正确使用mii info命令检查PHY状态7.4 环境变量无法保存症状使用saveenv命令后环境变量未持久化。可能原因存储设备未初始化环境变量分区未正确配置存储设备写保护解决方案检查环境变量存储设备配置CONFIG_ENV_IS_IN_MMC等确认存储设备可写检查include/configs/mx6ullevk.h中的环境变量设置8. 性能调优与实战技巧为了让U-Boot在imx6ull上发挥最佳性能以下是一些实用的调优技巧和经验分享。8.1 优化编译选项在configs/mx6ull_14x14_ddr512_emmc_defconfig中可以调整以下编译选项CONFIG_OPTIMIZE_INLININGy CONFIG_CC_OPTIMIZE_FOR_SIZEy或者直接修改Makefile中的编译标志PLATFORM_CPPFLAGS -O2 -fno-strict-aliasing8.2 减少U-Boot体积对于资源受限的系统可以采取以下措施减小U-Boot体积禁用不必要的功能make menuconfig然后禁用不需要的驱动和命令。使用LTOLink Time OptimizationCONFIG_LTOy移除调试信息CONFIG_DEBUGn8.3 加速启动过程通过分析U-Boot启动流程可以找到优化点测量各阶段耗时setenv trace on saveenv reset并行初始化修改代码使外设初始化并行化延迟初始化将非关键外设初始化推迟到内核阶段8.4 实用调试技巧使用JTAG调试配置OpenOCD连接J-Link或ST-Link调试器使用GDB进行单步调试串口调试增强#define DEBUG #include debug_uart.h内存检测mtest 0x80000000 0x800100008.5 生产环境建议对于量产环境建议使用经过充分测试的稳定版本启用所有必要的安全功能实现可靠的恢复机制记录详细的版本信息考虑使用A/B双系统设计9. 扩展应用与进阶开发掌握了基本的U-Boot编译和烧写后可以进一步探索更高级的应用场景。9.1 支持多种启动设备通过修改代码可以实现从多种设备启动的判断逻辑int board_late_init(void) { char *boot_device env_get(boot_device); if (!boot_device) { if (check_sd_card()) { env_set(boot_device, sd); } else if (check_emmc()) { env_set(boot_device, emmc); } else if (check_network()) { env_set(boot_device, net); } } return 0; }9.2 实现安全启动使用NXP的HABHigh Assurance Boot功能实现安全启动生成PKI树和数字证书使用CST工具签名U-Boot编程SRK哈希到efuse验证启动签名9.3 添加图形化界面可以集成简单的图形化界面用于系统配置启用CONFIG_VIDEO实现帧缓冲区驱动添加菜单系统支持触摸屏或按键输入9.4 实现OTA升级设计完整的OTA升级方案通过网络或USB获取新固件验证固件签名和完整性安全写入到备用分区更新启动标志并重启9.5 性能监控与调优添加系统性能监控功能CPU负载监测内存使用统计启动时间测量温度监控10. 资源推荐与社区支持为了更深入地学习和解决开发中遇到的问题以下是一些有价值的资源官方文档U-Boot官方文档NXP i.MX6ULL参考手册开发工具Linaro GCC工具链OpenOCDJ-Link软件社区支持U-Boot邮件列表NXP社区论坛Stack Overflow开发板支持正点原子阿尔法开发板资料野火i.MX6ULL开发板资料NXP官方评估板文档实用脚本与工具imxdownload专用烧写工具mfgtoolsNXP官方烧录工具uuuUniversal Update Utility在实际开发中遇到问题时可以按照以下步骤进行排查确认硬件连接正确检查电源稳定性验证时钟和复位信号分析串口调试输出使用示波器或逻辑分析仪检查关键信号查阅芯片参考手册和相关资料在社区寻求帮助通过本指南你应该已经掌握了在Ubuntu 20.04上为imx6ull开发板编译和烧写U-Boot的完整流程。从环境配置到源码编译从镜像烧写到功能验证每个步骤都包含了详细的操作说明和可能遇到的问题解决方案。无论是初学者还是有经验的开发者都能从中获得有价值的信息。