第4章 U-Boot源码结构:目录树解析
说实话,我第一次打开U-Boot源码目录时,头都大了。密密麻麻的文件夹,感觉像走进了一个迷宫。但干这行十几年了,我慢慢摸清了它的套路。今天我就带你把这个迷宫走一遍。
4.1 顶层目录:一眼看穿全局
U-Boot的顶层目录,说白了就几个核心文件夹。我个人习惯先看board/、cpu/、drivers/和common/这四个。为什么?因为它们直接决定了你的板子能不能跑起来。
| 目录 | 作用 | 我的经验 |
|---|---|---|
| board/ | 板级相关代码 | 每个板子一个子目录,比如board/samsung/ |
| cpu/ | CPU架构相关 | ARM、x86、RISC-V都在这里 |
| drivers/ | 外设驱动 | 串口、网卡、Flash...应有尽有 |
| common/ | 通用功能 | 命令解析、环境变量等核心逻辑 |
核心要点:移植U-Boot时,你主要改的就是board/和include/configs/下的文件。其他目录基本不用动。
4.2 board/目录:你的板子在这里安家
board/目录下每个子目录代表一个具体的板子。比如你要移植到某款i.MX6ULL的板子上,就会看到board/freescale/mx6ull_xxx/这样的路径。
这个目录里通常包含:
- board.c:板级初始化代码,比如GPIO配置、时钟设置
- Kconfig:板级的配置选项
- Makefile:编译规则
我的习惯:拿到一块新板子,我第一件事就是去board/目录下找一个最接近的参考板,复制一份再改。这样能省下至少一半的时间。
4.3 cpu/目录:芯片的“身份证”
cpu/目录存放的是CPU架构相关的代码。ARM、x86、MIPS、RISC-V...每种架构都有自己的子目录。
举个例子,ARM架构下你会看到:
- start.S:CPU启动的第一段代码,汇编写的
- cpu.c:CPU初始化函数
- interrupts.c:中断处理
嗯,这里要注意:start.S是U-Boot的入口点。我当年调试一块板子时,发现系统死活跑不起来,最后定位到是start.S里某个寄存器的值配错了。那感觉,就像在草堆里找一根针。
4.4 drivers/目录:外设驱动的“大超市”
drivers/目录下分门别类地放着各种外设驱动。串口、网卡、I2C、SPI、Flash、MMC...你需要的驱动基本都能在这里找到。
常见的子目录:
- serial/:串口驱动
- net/:网卡驱动
- spi/:SPI总线驱动
- mmc/:SD卡/eMMC驱动
- mtd/:NAND Flash驱动
避坑指南:我曾经在移植网卡驱动时,直接用了参考板子的驱动文件,结果死活ping不通。后来发现是PHY芯片的地址不一样。所以,驱动文件可以复用,但硬件配置一定要核对清楚。
4.5 common/目录:U-Boot的“大脑”
common/目录里放的是U-Boot的核心功能代码。比如:
- command/:各种命令的实现(bootm、ping、tftp...)
- env/:环境变量管理
- autoboot.c:自动启动逻辑
- console.c:控制台输入输出
说白了,你在U-Boot命令行里敲的每个命令,背后都是common/目录里的代码在干活。
4.6 Kconfig与Makefile:构建系统的“骨架”
U-Boot使用Kconfig/Makefile构建系统,跟Linux内核一模一样。你想想看,这其实是个好事——如果你熟悉Linux内核的配置方式,那U-Boot对你来说就轻车熟路了。
Kconfig的作用:
- 定义配置选项(比如CONFIG_CMD_PING)
- 管理选项之间的依赖关系
- 生成.config文件
Makefile的作用:
- 根据.config决定编译哪些文件
- 管理编译规则和链接顺序
- 生成最终的u-boot.bin
配置流程:
make xxx_defconfig # 选择板级默认配置
make menuconfig # 图形化配置(可选)
make # 编译
4.7 配置头文件机制:板子的“身份证”
每个板子都有一个对应的配置头文件,放在include/configs/目录下。比如include/configs/mx6ull_xxx.h。
这个文件里定义了板子的所有硬件参数:
- DDR大小和时序
- Flash分区布局
- 网卡MAC地址
- 串口波特率
- 环境变量存储位置
我的经验:配置头文件是移植过程中最常修改的文件。我建议你先把DDR参数和串口参数配好,因为这两样搞定了,U-Boot就能跑起来,后面的事就好办了。
4.8 知识体系结构图
下面这张图展示了U-Boot源码的核心结构关系。我画这张图时,特意把board/和include/configs/标红了,因为这两个是你移植时最需要关注的地方。
这张图你看懂了吗?从上往下看,顶层目录下面四个核心目录各司其职。board/和include/configs/是移植的主战场,Kconfig/Makefile负责把代码串起来,最终生成u-boot.bin。
总结一下:U-Boot的源码结构其实不复杂。你只要记住:board/管板子、cpu/管芯片、drivers/管外设、common/管功能、include/configs/管配置。把这五个点抓住了,移植工作就成功了一半。