4、U-Boot的编译与配置:.config、make menuconfig、设备树编译

好,咱们接着往下走。上一章聊完了U-Boot的启动流程,这一章我带你看看实际动手时最关键的一步——配置和编译。说白了,U-Boot不是拿来就能用的,你得先告诉它:你要跑在哪个板子上,用哪些驱动,开哪些功能。这个过程,就是通过 .configmake menuconfig 来完成的。

4.1 .config:U-Boot的“灵魂配置文件”

你想想看,一个U-Boot要支持几百种开发板,代码里全是条件编译。那它怎么知道该编译哪一部分?答案就是 .config 文件。

这个文件本质上是一个键值对列表。每一行都是一个配置选项,比如:

CONFIG_ARM=y
CONFIG_TARGET_MYBOARD=y
CONFIG_BAUDRATE=115200
CONFIG_CMD_NAND=y

这里的 y 表示“编译进内核”,m 表示“编译成模块”(U-Boot里很少用),空着就是不编译。我个人习惯,拿到一个新板子,第一件事就是 make distclean,然后 make xxx_defconfig,生成一个基础的 .config

避坑指南: 我曾经在项目里直接手动修改 .config 文件,结果漏了一个依赖选项,编译出来的 U-Boot 死活起不来。后来排查了半天,发现是某个驱动依赖的 DMA 没开。所以,能用 menuconfig 就别手改,除非你非常清楚自己在做什么。

4.2 make menuconfig:图形化的配置利器

手动改 .config 太容易出错了。所以U-Boot提供了 make menuconfig 这个神器。它基于ncurses库,给你一个终端里的图形界面。

运行它之前,确保你已经安装了 libncurses-dev。否则会报错:

sudo apt-get install libncurses-dev

然后进入U-Boot源码目录,执行:

make menuconfig

你会看到一个分层的菜单。上下键移动,回车进入子菜单,空格切换选项状态。嗯,这里要注意:[*] 表示编译进内核,[ ] 表示不编译,<M> 在U-Boot里很少见。

我一般会重点检查这几个地方:

  • Board Selection:确认板子型号选对了
  • Device Drivers:串口、网卡、Flash、MMC这些必须的驱动
  • Command Line Interface:你需要的命令,比如 tftpnandfatload
  • Boot options:启动参数、内核加载地址

配置完成后,按 Exit 保存,它会自动更新 .config 文件。这时候你再 make,编译出来的就是为你量身定做的U-Boot了。

核心要点: menuconfig 的本质是帮你生成正确的 .config 文件。它比手写更安全,因为它会检查依赖关系。比如你选了某个驱动,它会自动帮你选上它依赖的时钟、GPIO等选项。

4.3 设备树编译:从 .dts 到 .dtb

好,配置搞定了,接下来是设备树。设备树(Device Tree)是描述硬件信息的文件,U-Boot和内核都靠它来知道板子上有什么外设。

设备树的源文件是 .dts(Device Tree Source),编译后生成 .dtb(Device Tree Blob)。U-Boot里自带了很多 .dts 文件,放在 arch/arm/dts/ 目录下。

编译设备树的命令很简单:

make dtbs

或者单独编译某个文件:

make arch/arm/dts/myboard.dtb

它会调用 dtc(Device Tree Compiler)工具,把文本格式的 .dts 编译成二进制 .dtb。这个 .dtb 文件会被U-Boot在启动时加载到内存里,然后传递给Linux内核。

我记得有一次,客户说网卡不工作。我排查了半天,发现是设备树里网卡的 reg 地址写错了。你想想看,地址差一个字节,整个外设都访问不到。从那以后,我每次改设备树都会用 dtc -I dtb -O dts 反编译一下,确认二进制文件没问题。

注意事项: 设备树的编译依赖 dtc 工具。如果你的系统没有,可以安装 device-tree-compiler 包。另外,U-Boot和内核的设备树语法略有不同,别混用。

4.4 整体流程:一张图看懂

说了这么多,我画个流程图帮你理清思路。从源码到可运行的U-Boot,中间经历了配置、编译、设备树编译三个关键步骤。

U-Boot 编译与配置核心流程 U-Boot 源码 make menuconfig 生成 .config make 编译 u-boot.bin 设备树 .dts 文件 arch/arm/dts/ make dtbs 生成 .dtb 文件 最终产物 u-boot.bin + 设备树.dtb 配置阶段决定“编译什么” 设备树描述“硬件长什么样” 两者缺一不可

4.5 实战中的小技巧

最后,分享几个我常用的命令组合,能帮你省不少时间:

命令 作用 使用场景
make distclean 彻底清理所有编译产物 切换板子或遇到奇怪错误时
make xxx_defconfig 加载板子的默认配置 第一次配置新板子
make menuconfig 图形化修改配置 微调功能、添加驱动
make -j4 多线程编译,加快速度 日常编译,根据CPU核心数调整
make dtbs 只编译设备树 修改了 .dts 后快速验证
我的习惯: 每次修改配置后,我会先 make savedefconfig,把当前配置精简保存为 defconfig 文件。这样下次换板子或重装环境时,直接 make defconfig 就能恢复,不用再重新点一遍 menuconfig。

好了,这一章的内容就到这。配置和编译是U-Boot开发的基础,你只要把 .configmenuconfig、设备树这三块搞明白,后面遇到任何板子都能快速上手。


公众号:蓝海资料掘金营,微信deep3321