3. U-Boot配置系统
说到U-Boot的配置系统,我刚开始接触的时候也觉得挺绕的。说白了,它就是一套让你能「选功能、定参数」的机制。你想想看,一块开发板要支持NAND Flash,另一块要用eMMC,总不能每次都改源码吧?
U-Boot的配置系统,核心就三样东西:Kconfig、defconfig、menuconfig。这三兄弟配合起来,让你不用碰C代码,就能把U-Boot定制得服服帖帖。
3.1 Kconfig:配置的「骨架」
Kconfig是什么?它其实是一种配置描述语言。U-Boot里每个模块、每个驱动,都会有一个Kconfig文件。这个文件里定义了「有哪些选项可以配置」。
举个例子,你想知道某个驱动能不能被编译进U-Boot,就去翻它的Kconfig。比如NAND驱动的Kconfig里,会有类似这样的内容:
config NAND_SUNXI
bool "Support for Allwinner NAND controller"
depends on ARCH_SUNXI
help
Say Y here to enable support for the NAND controller
found on Allwinner SoCs.
这里每一行都有讲究:
- config NAND_SUNXI:这是配置项的名字,编译的时候会变成
CONFIG_NAND_SUNXI这个宏。 - bool:表示这是一个开关选项,要么Y(选中),要么空(不选)。
- depends on:依赖关系。只有
ARCH_SUNXI被选中了,这个选项才会出现。 - help:帮助信息,告诉你这个选项是干嘛的。
我个人习惯,拿到一块新板子,第一件事就是去board/和drivers/目录下扫一遍Kconfig。这样能快速摸清这个平台支持哪些外设。
select关键字,可以强制选中另一个选项。比如某个驱动依赖DMA,可以用select DMA自动把DMA打开。但小心别搞出循环依赖,我曾经就被这个坑过。
3.2 defconfig:板级的「配置快照」
defconfig文件,说白了就是一份「配置清单」。它记录了某块开发板的所有配置选项。U-Boot源码里,每个官方支持的板子都有一个对应的defconfig文件。
比如configs/orange_pi_zero_defconfig,打开看看:
CONFIG_ARM=y
CONFIG_ARCH_SUNXI=y
CONFIG_MACH_SUN8I_H3=y
CONFIG_DRAM_CLK=408
CONFIG_MMC=y
CONFIG_MMC_SUNXI=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
这里每一行都是一个配置项。注意看,CONFIG_DRAM_CLK=408这种是带数值的,不是简单的开关。
我在项目中遇到过一个问题:明明在menuconfig里配好了,编译出来却不生效。后来发现,是因为我改了.config文件,但没同步到defconfig里。记住,defconfig才是最终版本,.config只是临时文件。
make savedefconfig把当前配置保存回defconfig。否则下次make distclean后,你的配置就丢了。
3.3 menuconfig:图形化的配置界面
说实话,直接改defconfig文件挺累的。尤其是选项多的时候,记不住哪个依赖哪个。这时候menuconfig就派上用场了。
在U-Boot根目录下执行:
make menuconfig
你会看到一个蓝底白字的界面。上下键移动,回车进入子菜单,空格切换选项。嗯,操作起来有点像老式的BIOS设置界面。
menuconfig的好处是:
- 依赖关系自动处理:你选了一个选项,它依赖的选项会自动被选中。
- 搜索功能:按
/键,输入关键字,能快速定位到配置项。 - 实时查看帮助:选中一个选项,按
?就能看到它的帮助信息。
我曾经调试一个USB启动问题,在menuconfig里搜USB,把所有相关的选项都过了一遍。最后发现是CONFIG_USB_EHCI_HCD没开,导致USB控制器根本没初始化。
.config文件。然后make的时候,.config会被转换成include/autoconf.mk,最终变成C代码里的宏定义。
3.4 配置系统的完整流程
为了让你看得更清楚,我画了一张流程图:
流程其实很简单:
- Kconfig 定义了「有哪些选项」。
- defconfig 定义了「某块板子选了哪些」。
- 你可以用 menuconfig 临时调整配置,结果存到 .config。
- 编译时,.config 被转换成 autoconf.mk,供Makefile使用。
- 最后,用 savedefconfig 把当前配置写回defconfig,永久保存。
make menuconfig确认没问题,然后make savedefconfig,最后把生成的defconfig文件复制到configs/目录下。这样既保留了临时修改,又更新了板级配置。
嗯,配置系统这块,说白了就是「定义-选择-生成」三个步骤。Kconfig负责定义,defconfig和menuconfig负责选择,编译系统负责生成。搞懂了这三者的关系,U-Boot的配置对你来说就不再是黑盒了。
可可精品资料库