ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

BOOT与U-Boot本质区别:启动流程、固件层级与嵌入式开发避坑指南

BOOT与U-Boot本质区别:启动流程、固件层级与嵌入式开发避坑指南 1. 别再混淆了BOOT 是个泛称UBOOT 是个具体程序刚入嵌入式开发那会儿我被“BOOT”和“UBOOT”这两个词绕得团团转。面试官问“你们板子怎么启动的”我说“走 UBOOT 啊。”他接着问“那 BOOT 呢”我愣了一下脱口而出“BOOT 就是 UBOOT 吧”——当场被礼貌微笑终结了面试。后来在产线调试一块 i.MX6ULL 开发板时又因为把“BOOT 模式引脚配置”和“UBOOT 环境变量设置”混为一谈硬是花了三天才让板子从 SD 卡正常加载内核。这让我彻底明白BOOT 和 UBOOT 根本不是同一维度的概念前者是启动行为的统称后者是实现该行为的一个具体软件实体。很多人之所以搞不清是因为日常交流中大量使用了不严谨的简称。比如工程师说“烧写 BOOT”实际指的是烧写 UBOOT 的二进制镜像说“改 BOOT 参数”往往是指修改 UBOOT 的bootargs环境变量而“BOOT 失败”可能指代从硬件上电复位、ROM 代码执行、FSBL 加载、UBOOT 初始化、内核解压到根文件系统挂载全过程中的任意一环故障。这种语义压缩在团队内部能提效但对新人或跨领域协作却是巨大陷阱。更麻烦的是网络热词进一步加剧了混淆。搜索“boot 配置电路”结果里混着 STM32 的 BOOT0/BOOT1 引脚接法、Zynq 的 PS-PL 启动模式跳线、甚至 BIOS 中的 Secure Boot 设置点开“spring boot 教程”看到的全是 Java Web 框架内容——这里的 “Boot” 只是 Spring 官方起的一个品牌名和嵌入式启动毫无关系。同理“win11 虚拟机出现 boot 错误”本质是 Windows Boot Manager属于 EFI 固件层与虚拟化平台的兼容问题而“petalinux-package --boot”命令里的--boot参数特指将 FSBLFirst Stage Boot Loader、U-Boot、设备树等打包进 BOOT.BIN 文件供 Zynq SoC 的 ROM Code 加载。所有这些“boot”共享同一个英文单词却分属硬件电路设计、固件协议栈、操作系统引导、应用框架命名四个完全不同的技术层级。所以我们首先要建立一个清晰的认知坐标系BOOT全小写泛指是一个动词性概念描述“设备从断电状态恢复到可运行用户程序”的整个过程包含硬件初始化、固件加载、引导链传递、操作系统接管等阶段。它没有源码没有版本号只有一套被芯片厂商定义好的启动流程规范如 ARMv7 的 BootROM 流程、ARMv8-A 的 ARM Trusted Firmware 启动序列。U-Boot带连字符专有名词是一个开源的、可移植的、功能完整的 Bootloader 软件项目由 DENX Software Engineering 维护遵循 GPL 协议。它不是唯一选择还有 Barebox、Das U-Boot 的轻量分支、ARM 官方的 TF-A但因其成熟度、文档完善度和社区支持广度成为绝大多数 ARM/Linux 嵌入式项目的事实标准。它的核心价值在于把芯片厂商定义的冷冰冰的 BOOT 流程变成开发者可读、可调、可扩展的 C 语言工程。这个根本区别决定了你后续所有操作的逻辑起点当你在原理图上画 BOOT 引脚时你是在和芯片数据手册对话当你在终端里敲setenv bootcmd run load_kernel; bootz时你是在和 U-Boot 的命令行交互当你用mkimage工具生成 uImage 时你是在为 U-Boot 提供它能识别的镜像格式而当你在 Linux 内核里看到CONFIG_ARM_APPENDED_DTBy这个选项时你其实是在告诉内核“别担心 DTB 位置U-Boot 已经把它追加在 zImage 后面了”。提示判断当前语境中 “boot” 指代什么最可靠的方法是看它紧邻的修饰词。出现 “引脚”、“电路”、“模式”、“sequence”、“ROM”、“Secure Boot” 等词基本指向硬件/固件层出现 “环境变量”、“命令行”、“make menuconfig”、“board config”、“defconfig” 等词则 100% 指向 U-Boot 软件层。2. 启动链条拆解从上电瞬间到 shell 提示符的七步穿越要真正理解 BOOT 和 UBOOT 的关系必须亲手拆解一次完整的启动链条。我以正点原子 i.MX6ULL 开发板EMMC 启动为例结合其官方 SDK 和 U-Boot v2020.04 版本还原从按下电源键到出现提示符的完整路径。这不是理论推演而是我在调试一块反复卡在 “Starting kernel ...” 的板子时用逻辑分析仪抓取 UART0 波形、配合 JTAG 单步跟踪 ROM Code 所验证的真实流程。2.1 第一阶段SoC 内部 ROM Code不可修改的硬件逻辑i.MX6ULL 上电后CPU 核心并不直接执行用户代码而是由片上 ROM 中固化的一段微码接管。这段代码是 NXP 在芯片流片时就写死的开发者无法修改其唯一任务就是根据 BOOT_MODE[1:0] 引脚的状态决定从哪个外部介质加载下一阶段引导程序。这个引脚组合对应关系在《i.MX6ULL Reference Manual》第8章 “System Boot” 中有精确表格BOOT_MODE[1:0]启动设备加载地址说明0b10eMMC/SD Card0x00907000最常用从 eMMC 分区 0BOOT 分区读取0b01NAND Flash0x00907000需要额外配置 GPMI 控制器0b00SPI NOR Flash0x00907000依赖 QSPI 控制器初始化0b11USB Download-进入串口下载模式用于首次烧录关键点在于ROM Code 不认识文件系统它只做“裸设备扇区读取”。它会从 eMMC 的 Block 0 开始连续读取 1024 个扇区512KB并将数据拷贝到内部 SRAM地址 0x00907000中。然后跳转到该地址执行——这就要求你烧写的第一个镜像必须是能被 ROM Code 直接执行的、位置无关的二进制代码。这个镜像就是第二阶段的主角。2.2 第二阶段SPLSecondary Program LoaderU-Boot 的精简前哨U-Boot 本身体积庞大编译后常超 1MB而 i.MX6ULL 的内部 SRAM 仅 128KBROM Code 无法一次性加载完整 U-Boot。因此U-Boot 社区引入了 SPL 机制一个极度精简的、只包含最基本驱动如 UART、eMMC Host Controller的 C 语言程序。它的编译目标是生成一个不超过 100KB 的二进制文件专门用来完成两件事初始化最小硬件环境时钟、DDR、eMMC从 eMMC 的特定分区通常是分区 1即 boot 分区读取完整的 U-Boot 主镜像u-boot-dtb.imx到 DDR 中。SPL 的源码位于 U-Boot 源码树的spl/目录下其构建过程由顶层 Makefile 自动触发。当你执行make mx6ull_14x14_ddr512m_emmc_defconfig make时Makefile 会先编译 SPL再用mkimage工具将其与主 U-Boot 镜像合并生成最终的u-boot-dtb.imx文件。这个.imx后缀正是 i.MX 系列专用的镜像格式它在 U-Boot 二进制头部添加了 NXP 定义的 IVTImage Vector Table结构其中包含了入口地址、DCDDevice Configuration Data表指针等关键信息供 ROM Code 解析。注意SPL 并非 U-Boot 独有。ARM 架构下TF-ATrusted Firmware-A也采用类似的 BL1/BL2 分层设计。SPL 的存在本质上是软件工程对硬件资源限制的妥协它把“加载器”和“引导器”的职责做了物理分离。2.3 第三阶段U-Boot 主程序可定制的引导中枢当 SPL 成功将u-boot-dtb.imx加载到 DDR例如 0x87800000并跳转执行后真正的 U-Boot 主程序才开始运行。此时它已拥有完整的内存空间、串口输出能力、eMMC 访问权限。它的初始化流程遵循严格的顺序可在arch/arm/lib/crt0.S和common/board_r.c中追踪板级初始化board_init_f设置 CPU 模式、关闭看门狗、初始化 DDR 控制器此步若失败板子会直接黑屏无任何输出重定位relocate_code将自身代码从加载地址拷贝到链接地址Link Address这是为了支持位置无关代码PIC向绝对地址代码的转换板级后期初始化board_init_r初始化网卡、USB、LCD、NAND 等外设驱动加载环境变量从 eMMC 的uboot.env分区或 FAT 分区读取解析bootcmd环境变量。这个阶段完成后U-Boot 就进入了交互式命令行状态屏幕上打印出U-Boot 2020.04 (Oct 12 2023 - 14:22:32 0800)和提示符。此时你输入的每一个命令都是在 U-Boot 的 Shell 解释器中执行的它背后调用的是common/cmd_*.c中定义的具体函数。2.4 第四阶段内核加载与移交U-Boot 的核心使命U-Boot 的终极目标是把控制权安全、可靠地交给 Linux 内核。这个过程绝非简单跳转而是一系列精密的参数协商与状态准备加载内核镜像通过fatload mmc 0:1 ${loadaddr} zImage命令将 eMMC 分区 1 中的zImage压缩的内核加载到内存地址${loadaddr}通常为 0x80800000加载设备树通过fatload mmc 0:1 ${fdt_addr} imx6ull-atom.dtb命令将设备树二进制文件DTB加载到${fdt_addr}通常为 0x83000000设置启动参数执行setenv bootargs consolettymxc0,115200 root/dev/mmcblk1p2 rootwait rw将内核启动参数写入环境变量执行跳转调用bootz ${loadaddr} - ${fdt_addr}命令。该命令会解压zImage到临时缓冲区将设备树 BlobDTB的物理地址写入 R2 寄存器将内核启动参数bootargs的物理地址写入 R1 寄存器将 CPU ID通常是 0写入 R0 寄存器最终执行mov pc, #0x80800000跳转到解压后的内核入口。这里的关键是寄存器约定R0/R1/R2这是 ARM Linux 内核 ABIApplication Binary Interface强制规定的。U-Boot 必须严格遵守否则内核无法正确解析启动信息。这也是为什么bootz命令比裸go命令更安全——go只是无条件跳转不处理任何参数传递。2.5 后续阶段内核接管与用户空间启动脱离 U-Boot 管辖一旦bootz执行成功CPU 控制权就永久移交给了 Linux 内核。U-Boot 的使命至此终结其占用的内存除保留给内核的bootm_low区域外会被内核回收。内核会解析 DTB枚举所有硬件设备初始化中断控制器、时钟子系统、内存管理单元MMU挂载根文件系统root/dev/mmcblk1p2执行/sbin/init或systemd启动用户空间进程。此时你在串口看到的Starting kernel ...之后的日志全部来自 Linux 内核和 init 进程与 U-Boot 再无任何关系。如果你在内核日志中看到Failed to find /chosen node那说明 U-Boot 加载的 DTB 文件损坏或地址错误如果看到VFS: Cannot open root device mmcblk1p2则可能是bootargs中的root参数写错或者 eMMC 分区表未正确创建。实测心得在调试启动失败时务必分阶段隔离问题。先确认 ROM Code 是否工作看 UART 是否有初始乱码或固定字符串再确认 SPL 是否成功看是否有 “SPL” 字样或 eMMC 初始化日志最后才排查 U-Boot 主程序。我曾遇到一块板子UART 输出始终是乱码最后发现是晶振频率配置错误导致 UART 波特率偏差过大而非 U-Boot 代码问题。3. U-Boot 的核心能力不只是“加载内核”更是嵌入式系统的瑞士军刀很多初学者认为 U-Boot 的作用仅限于“把内核拉起来”这严重低估了它的工程价值。在我参与的工业网关项目中U-Boot 承担了远超传统引导程序的职责它实质上是嵌入式设备的“第一道固件操作系统”。其核心能力可归纳为三大类硬件抽象层、固件服务层、安全可信层。3.1 硬件抽象层统一接口屏蔽芯片差异ARM 架构芯片型号繁多i.MX、RK、Allwinner、Exynos每家的寄存器布局、时钟树、外设控制器都不同。如果每个 Linux 内核都要为每款芯片重写底层驱动维护成本将不可想象。U-Boot 的解决方案是在自身内部实现一套完备的、与芯片无关的硬件抽象接口HAI。开发者只需针对新芯片编写drivers/目录下的具体驱动如drivers/mmc/imx_esdhc.cU-Boot 的上层命令如mmc read和启动流程如board_init_f就能自动调用它们。以 eMMC 访问为例在 i.MX6ULL 上U-Boot 调用imx_esdhc_init()函数操作ESDHC寄存器组在 Rockchip RK3399 上它调用rockchip_mmc_init()操作SDMMC寄存器组但对外暴露的命令行接口完全一致mmc dev 0、mmc info、mmc read 0x81000000 0x100 0x200。这种设计带来的好处是惊人的。当我们需要将一个基于 i.MX6ULL 的固件方案快速迁移到 RK3399 平台时只需替换configs/下的 defconfig 文件、更新board/rockchip/rk3399/下的板级代码U-Boot 的绝大部分命令、环境变量、启动脚本都能无缝复用。Linux 内核的设备树DTB同样受益于此——U-Boot 加载 DTB 后内核只需解析标准的compatible字符串无需关心底层寄存器如何操作。3.2 固件服务层为产品功能提供底层支撑U-Boot 的命令行不仅是调试工具更是产品功能的载体。在我们交付的某款智能电表中U-Boot 被深度定制提供了以下生产必需功能固件在线升级FOTA通过tftpboot命令从服务器下载新版本 U-Boot 或内核用sf probe sf update将其写入 SPI NOR Flash 的指定扇区并更新环境变量bootcmd指向新镜像。整个过程无需拆机一条命令即可完成。硬件自检BIST在bootdelay倒计时期间自动执行ping 192.168.1.1检测网卡、i2c probe检测传感器总线、mmcinfo检测 eMMC 健康度。任一失败则停止启动进入 recovery 模式。安全启动Secure Boot集成 NXP 的 HABHigh Assurance Boot库对加载的 U-Boot、内核、DTB 进行签名验证。只有通过公钥验证的镜像才能被执行防止恶意固件注入。这些功能的实现都依赖于 U-Boot 的模块化架构。例如 FOTA 功能核心是common/cmd_net.c网络协议栈、drivers/mtd/spi-nor.cSPI Flash 驱动、tools/mkimage.c镜像签名工具三个模块的协同。你可以选择性地启用或禁用它们通过CONFIG_CMD_TFTP、CONFIG_CMD_SF、CONFIG_HAB等宏来控制。3.3 安全可信层构建可信执行环境的基石随着物联网设备安全要求提升U-Boot 已从单纯的引导程序演变为可信执行环境TEE的启动锚点。在最新版 U-Bootv2023.04中CONFIG_TEE选项允许其作为 OP-TEEOpen Portable Trusted Execution Environment的加载器。其启动流程变为ROM Code → SPL → U-Boot → [OP-TEE OS] → Linux KernelU-Boot 在此过程中负责为 OP-TEE 分配独立的内存区域通过mem...参数预留将 OP-TEE 的二进制镜像tee.bin从存储设备加载到指定地址设置 ATAGS 或 Device Tree向 Linux 内核声明 TEE 的存在和通信接口如/dev/tee0通过 SMCSecure Monitor Call指令触发 TrustZone 切换将控制权移交给 OP-TEE。这意味着U-Boot 不再是“单线程”的引导者而是协调多个安全域的“调度中心”。它确保了从硬件信任根ROM Code到应用层Linux的完整信任链Chain of Trust。这也是为什么 NXP、ST 等芯片厂商会将 U-Boot 的安全启动补丁直接贡献给上游主线因为它已成为行业事实标准。关键经验U-Boot 的强大源于其“可裁剪性”。一个最小化的 U-Boot仅含printenv、setenv、bootz命令可以压缩到 200KB 以内而一个功能完备的工业级 U-Boot含网络、USB、LCD、加密则可能超过 2MB。你的裁剪策略应严格匹配产品需求。例如一款仅需本地 OTA 的设备完全可以禁用CONFIG_CMD_NET节省宝贵的 Flash 空间。4. 实战避坑指南那些让你熬夜到凌晨三点的 U-Boot 坑纸上得来终觉浅绝知此事要躬行。U-Boot 的坑往往藏在最不起眼的细节里。下面是我和团队踩过的、最具代表性的五个深坑每一个都附带了完整的排查链路和根因分析希望能帮你避开这些“时间黑洞”。4.1 坑位一环境变量bootcmd执行后卡死串口无任何输出现象U-Boot 启动后正常打印提示符手动输入run bootcmd能成功启动内核但设置bootdelay3后倒计时结束自动执行bootcmd却在Starting kernel ...后彻底静默串口无任何后续日志。排查链路第一步确认是否真卡在 U-Boot在bootcmd末尾添加echo bootcmd finished;重新烧写。结果发现echo语句并未打印证明卡在bootz命令内部而非内核。第二步检查bootz的参数有效性手动执行bootz ${loadaddr} - ${fdt_addr}观察是否卡死。结果相同排除bootcmd字符串解析问题。第三步验证内存地址冲突查看bootz命令源码common/cmd_bootm.c发现其内部会将内核解压到loadaddr 0x8000地址。而我们的loadaddr0x80800000解压目标为0x80808000。检查arch/arm/dts/imx6ull-atom.dtb发现memory80000000节点的reg属性为0x80000000 0x20000000512MB看似足够。但继续深挖发现CONFIG_SYS_SDRAM_BASE0x80000000而CONFIG_SYS_INIT_SP_ADDR0x80000000 0x1000栈顶CONFIG_SYS_TEXT_BASE0x87800000U-Boot 代码基址。0x80808000正好落在 U-Boot 数据段.data和 BSS 段之间当内核解压覆盖此区域时U-Boot 的全局变量被破坏导致后续跳转异常。根因与修复U-Boot 的bootz命令默认解压地址计算逻辑未考虑用户自定义的内存布局。解决方案是显式指定解压地址# 修改 bootcmd setenv bootcmd fatload mmc 0:1 0x80800000 zImage; fatload mmc 0:1 0x83000000 imx6ull-atom.dtb; bootz 0x80800000 0x80800000 0x83000000 # 注意第三个参数是 initrd 地址此处为空但必须占位第二个参数是解压地址与 loadaddr 相同 saveenv或者在include/configs/mx6ull_14x14_ddr512m_emmc.h中将CONFIG_SYS_LOAD_ADDR改为0x81000000确保解压空间充足。4.2 坑位二tftpboot下载失败提示Timeout或No server found现象在 U-Boot 命令行执行tftpboot 0x81000000 uImage等待数秒后返回TFTP error: timeout。排查链路第一步确认物理连接与 IP 配置执行ping 192.168.1.100TFTP 服务器 IP发现能通。执行ipaddr显示192.168.1.10serverip192.168.1.100netmask255.255.255.0网络参数正确。第二步检查 TFTP 服务器状态在 Ubuntu 主机上执行sudo systemctl status tftpd-hpa显示active (running)。ls /var/lib/tftpboot/uImage文件存在且权限为644。第三步抓包分析网络行为在主机上用tcpdump -i eth0 port 69抓包发现 U-Boot 发送了RRQRead Request报文但主机未回复OACKOption Acknowledgement。对比正常工作的开发板抓包发现正常报文中RRQ的blksize选项为1024而故障板为512。根因与修复U-Boot 的net/tftp.c中TFTP_BLOCK_SIZE宏默认为512但某些 TFTP 服务器如tftpd-hpa对blksize选项敏感要求必须为1024或1468MTU-IP/TCP header。解决方案是在include/configs/mx6ull_14x14_ddr512m_emmc.h中添加#define CONFIG_TFTP_BLOCKSIZE 1024或者在 U-Boot 命令行中执行setenv tftpblocksize 1024; saveenv。4.3 坑位三saveenv后重启环境变量恢复为默认值现象执行setenv ipaddr 192.168.1.20; saveenv提示Saving Environment to MMC... OK但重启后printenv ipaddr仍显示192.168.1.10。排查链路第一步确认环境变量存储位置查看CONFIG_ENV_IS_IN_MMC是否定义。是。再查CONFIG_SYS_MMC_ENV_DEV0CONFIG_ENV_OFFSET0x80000512KB 偏移。第二步检查 eMMC 分区布局执行mmc dev 0后mmc part发现 eMMC 有 4 个分区0BOOT、1boot、2rootfs、3user。CONFIG_ENV_OFFSET是相对于 eMMC 设备起始地址的偏移而非分区起始地址。0x80000对应第 0 个扇区Block 0之后的 256 个扇区这恰好是 BOOT 分区的末尾区域。第三步验证写入操作执行mmc write 0x81000000 0x100 0x1向 Block 0x100 写入 1 个扇区再mmc read 0x81000000 0x100 0x1读回发现数据一致。证明 eMMC 写入功能正常。根因与修复问题出在CONFIG_ENV_OFFSET的单位理解错误。U-Boot 的mmc write命令中地址参数是字节地址而CONFIG_ENV_OFFSET宏定义的值是扇区Sector地址每个扇区为 512 字节。0x80000字节 0x100扇区。但CONFIG_ENV_OFFSET应该是0x100而不是0x80000修正方法在mx6ull_14x14_ddr512m_emmc.h中将#define CONFIG_ENV_OFFSET 0x80000改为#define CONFIG_ENV_OFFSET 0x100。提示U-Boot 源码中所有CONFIG_ENV_*相关宏其数值单位均为扇区sector这是最容易混淆的点。4.4 坑位四bootz启动后内核 panic提示Unable to handle kernel NULL pointer dereference现象U-Boot 成功打印Starting kernel ...但内核立即崩溃串口输出Unable to handle kernel NULL pointer dereference at virtual address 00000000。排查链路第一步检查设备树兼容性执行fdt addr ${fdt_addr}; fdt print /compatible输出imx6ull-14x14-evk。而内核配置中CONFIG_SOC_IMX6ULLyCONFIG_MACH_IMX6ULLEVKy匹配。第二步检查内核镜像完整性在主机上用file zImage检查显示zImage: Linux kernel ARM boot executable zImage (little-endian)格式正确。第三步检查内存映射冲突查看内核启动日志开头发现Memory: 484MB 484MB total但dmesg | grep Memory显示Memory: 484MB 484MB total。再看cat /proc/meminfo | head -5发现MemTotal: 475120 kB约 464MB。少了约 20MB。根因与修复内核启动时会预留一部分内存给 DMA 缓冲区、CMAContiguous Memory Allocator等。CONFIG_CMA_SIZE_MBYTES16预留了 16MB加上其他开销正好是 20MB。但这不是 panic 的原因。继续看 panic 日志前一行OF: fdt: Machine model: Freescale i.MX6 UltraLite Lite 14x14 EVK。model字符串中出现了空格和特殊字符。检查arch/arm/boot/dts/imx6ull-atom.dtb发现model i.MX6ULL-Atom Board而内核的of_flat_dt_match_machine()函数在解析model字符串时对空格处理不当。解决方案将设备树中的model改为无空格字符串如model imx6ull-atom重新编译 DTB 并烧写。4.5 坑位五make menuconfig中找不到CONFIG_CMD_USB选项现象想在 U-Boot 中启用 USB 存储支持执行make menuconfig在Command line interface-USB commands下找不到USB Storage support选项。排查链路第一步确认 USB 驱动是否启用在menuconfig中进入Device Drivers-USB Support发现Support for Host-side USB未勾选。勾选后USB Storage support选项才出现在Command line interface下。第二步检查板级配置依赖查看configs/mx6ull_14x14_ddr512m_emmc_defconfig发现其中没有CONFIG_USBy、CONFIG_USB_STORAGEy等宏。这是因为 U-Boot 的 Kconfig 系统有严格的依赖关系CONFIG_CMD_USB依赖CONFIG_USB而CONFIG_USB又依赖CONFIG_DM_USBDriver Model for USB。根因与修复U-Boot 的配置系统是分层的。defconfig文件只定义顶层宏底层驱动依赖需手动开启。正确做法是在menuconfig中依次开启Device Drivers-USB Support-Support for Host-side USB(CONFIG_USB)然后开启Device Drivers-USB Support-USB Mass Storage support(CONFIG_USB_STORAGE)最后开启Command line interface-USB commands-USB Storage support(CONFIG_CMD_USB)。或者直接在defconfig文件中添加以下三行CONFIG_USBy CONFIG_USB_STORAGEy CONFIG_CMD_USBy经验总结U-Boot 的 Kconfig 依赖关系比 Linux 内核更隐蔽。当你在menuconfig中找不到某个选项时不要急于搜索先检查其父级菜单是否已启用。一个常见的技巧是在menuconfig中按/键搜索CONFIG_CMD_USB它会告诉你该选项的完整路径和依赖项。5. 选型与演进U-Boot 还是 TF-A未来嵌入式启动的走向当你的项目走到架构选型阶段一个无法回避的问题是在 ARM64 平台上是继续沿用成熟的 U-Boot还是转向 ARM 官方推荐的 TF-ATrusted Firmware-A这不是一个简单的“新 vs 旧”问题而是涉及安全等级、开发成本、生态兼容性的综合决策。我以参与的两个真实项目为例为你剖析其适用边界。5.1 U-Boot 的不可替代性面向通用 Linux 的成熟生态在我们为某大型能源集团开发的边缘计算网关项目中硬件平台是 NXP i.MX8MQCortex-A53 Cortex-M4。项目需求非常典型运行标准 LinuxYocto Pok
返回列表