4. 配置与编译

说实话,很多刚接触嵌入式Linux的朋友,一上来就被U-Boot的配置系统搞懵了。什么defconfig、menuconfig,还有那一堆编译出来的文件,看着就头大。别急,今天我就带你把这套流程捋清楚。

我自己刚入行那会儿,第一次编译U-Boot,make完发现生成了好几个.bin文件,完全不知道哪个该烧到板子上。后来踩过几次坑,才真正搞明白这套配置编译系统的设计逻辑。

配置三板斧:从默认配置到个性化定制

U-Boot的配置流程,说白了就三步。我习惯叫它「三板斧」。

第一板斧:make xxx_defconfig

这一步是加载板级默认配置。每个开发板厂商都会提供一个基础配置,存在configs/目录下。

# 以我常用的qemu虚拟板为例
make qemu_arm_defconfig

# 如果是你的真实板子,比如某款i.MX6ULL开发板
make mx6ull_14x14_evk_defconfig

执行完这条命令,U-Boot会把对应的默认配置写入.config文件。这个.config就是后续编译的依据。

我的小技巧: 如果你不确定板子对应哪个defconfig,可以这样搜:ls configs/ | grep -i "你的芯片型号"。我在项目里经常这么干,比翻手册快多了。

第二板斧:make menuconfig

这一步是图形化配置界面。说白了,就是给你一个菜单,让你勾选需要的功能。

make menuconfig

执行后会弹出这样一个界面:

U-Boot Configuration Arrow keys navigate the menu. <Enter> selects submenus ... [*] ARM architecture [ ] Boot media [*] Command line interface [*] Network support [*] Device Drivers [*] File systems [ ] Environment Select Exit Help [*] = built-in [ ] = excluded <M> = module Press <?> for keyboard shortcuts

在这个界面里,你可以:

  • 用方向键上下移动光标
  • 按空格键勾选/取消功能
  • 按Enter进入子菜单
  • 按?查看帮助
注意: 我曾经犯过一个低级错误——在menuconfig里改完配置后直接关终端,没保存。结果下次编译还是用的旧配置。记住,改完后一定要选「Save」退出。

第三板斧:make

配置搞定,接下来就是编译了。直接敲make就行。

# 单线程编译(适合调试)
make

# 多线程编译(推荐,快很多)
make -j4   # 4核编译
make -j8   # 8核编译

我个人习惯用-j参数,但要注意:如果你在调试某个驱动,最好单线程编译,这样错误信息不会乱掉。

编译产物分析:到底生成了什么?

编译完成后,在源码根目录下会生成一堆文件。新手最容易搞混的就是这几个:

文件名 大小(典型值) 用途
u-boot.bin ~500KB 纯二进制镜像,直接烧录到SPI Flash或SD卡
u-boot.img ~520KB 带U-Boot头部信息的镜像,用于网络启动
u-boot.srec ~1.5MB Motorola S-record格式,用于串口烧录
u-boot.map ~200KB 符号映射表,调试时看函数地址用
核心区别: u-boot.bin是「裸」的二进制,从0地址开始执行。u-boot.img在.bin前面加了一个64字节的头部,包含镜像类型、加载地址、校验和等信息。网络启动时,服务器需要知道这个镜像该加载到内存的哪个位置,所以必须用.img格式。

一个完整的配置编译实战

咱们来走一遍完整流程。假设你手头有一块基于Allwinner H3的板子:

# 1. 清理之前的编译产物(如果有)
make distclean

# 2. 加载板级默认配置
make orangepi_pc_defconfig

# 3. 个性化配置(比如我要开启网络启动支持)
make menuconfig
# 进入 Networking support → 勾选 TFTP boot
# 进入 Command line interface → 勾选 Network commands

# 4. 保存退出,开始编译
make -j4

# 5. 查看生成的镜像
ls -lh u-boot.bin u-boot.img

嗯,这里要注意一点:make distclean会删除所有配置和编译产物。如果你只是改配置,用make clean就够了,它只删编译产物,保留.config。

避坑指南:我踩过的三个坑

这些年编译U-Boot,我至少在这三个地方栽过跟头:

  1. 交叉编译器版本不对 —— 我曾经用gcc 7.3编译一个为gcc 4.9设计的U-Boot,结果链接阶段各种报错。后来查了半天才发现是工具链版本太新了。建议用板子厂商推荐的版本。
  2. .config被意外覆盖 —— 如果你在make menuconfig之后又执行了一次make xxx_defconfig,新配置会覆盖你手动改的内容。我习惯在改完配置后,先备份一下.config。
  3. 烧录了错误的镜像 —— 有次我把u-boot.img当成u-boot.bin烧进了SPI Flash,结果板子起不来。因为SPI Flash是从0地址开始执行,不需要头部信息。而u-boot.img的头部会占用前64字节,导致执行流错乱。
我的经验: 如果你不确定该烧哪个文件,先看板子的启动方式。SPI Flash/NOR Flash用u-boot.bin,NAND Flash用u-boot.img,SD卡启动也是u-boot.bin。网络启动则必须用u-boot.img。

配置系统的核心逻辑

最后,我用一张图总结一下U-Boot配置编译的完整流程:

make xxx_defconfig 加载默认配置 make menuconfig 个性化定制 make 编译 输出产物 u-boot.bin SPI Flash / SD卡 u-boot.img 网络启动 / NAND u-boot.srec 串口烧录

这张图把整个流程串起来了。你想想看,从默认配置到个性化定制,再到编译输出,每一步都有明确的产物。搞清楚了这些,以后不管换什么板子,这套流程都能复用。

好了,配置编译这块就聊到这儿。记住,多动手试几次,踩过坑才能真正记住。下次咱们聊聊怎么把这些镜像烧到板子里去。

可可精品资料库