为了能够在不同的硬件架构上(差异主要是CPU,DDR,FLASH等)进行适配运行,Uboot采用宏来控制编译时代码块的选择。
Uboot早期是通过手动编辑一个config文件来完配置的,但是手动编辑属于开放式操作,容易引入错误,所以从v2014.10-rc1开始,移植了Linux Kernel的Kconfig配置系统,让用户可以轻松的在界面上完成配置的选择和定义,极大提高了工作效率。
本文通过对Uboot的配置流程和Kconfig配置系统的讲解,让你知道配置是怎么生效的以及如何修改和增加配置选项。
注意!!!Uboot规定所有的宏都使用CONFIG_作为前缀,各种关于宏的配置以及转换也是基于CONFIG_完成的,如果新增配置选项,需要遵守该规则。
Uboot配置流程(以sandbox为例)
1.生成初始配置文件.config
当启动一个Kconfig配置界面的时候,每个配置选项的初始值有两个来源,一个是Kconfig文件中通过关键字default描述的,还有一个是当前目录下的.config文件,后者覆盖前者。
因为我们的新硬件架构并不是完全不同的,所以基本上可以以一个已经适配好的已有硬件作为基础来调整配置,比如我们这里选择的是sandbox_defconfig作为基础来生成.config文件:
1 |
|
实际上,.config文件是由宿主机编译出来的conf程序读取./configs/sandbox_defconfig文件和各级Kconfig文件后生成的,我们可以看到.config中的配置项明显比./configs/sandbox_defconfig更多,那是因为还包含了各级目录下的Kconfig文件中的配置选项和默认值。
2. 修改配置文件并更新.config
如果需要根据自己新的硬件架构调整配置选项的值,就需要启动配置界面:
1 |
|
menuconfig只是配置界面可选的一种,还有其他选择,比如xconfig(基于QT)、gconfig(基于GTK+)、nconfig(基于ncurses)以及config(基于行字符)。
make help中关于配置界面介绍如下:
1 |
|
因为是通过简单的键盘选中/编辑操作,而且规定了依赖关系,从而避免了不合理配置的引入,极大的保证了配置的可靠性。
3.生成配置相关文件
前面两步只是完成了.config文件,打开.config文件你会发现格式如下:
1 |
|
熟悉C语言的都知道,这并不是C的宏,.config必须转化为相关的头文件才能在编译时生效,make cfg可以完成这个工作。
1 |
|
使用NO_SDL=1,因为我们是在终端上运行的,不需要使用SDL引擎来显示界面和处理键盘输入。
所有需要平台适配的源码都包含了common.h这个头文件,那这个头文件和.config是怎么发生关系的呢?我们看看包含关系图,如下:
1 |
|
通过上述的自动生成和头文件包含关系可以看出,.config中的配置最终会在common.h得以体现,这样就完成了配置的导入和宏编译的控制。
Kconfig语法说明
配置选项的设置和相互之间的依赖关系是通过各层级的Kconfig文件来进行描述的,Kconfig有自己的语法结构,用于表达菜单入口,配置选项以及依赖关系等。
根目录下的Kconfig文件内容如下:
1 |
|
我们结合menuconfig的图以及上面的Kconfig文件内容,来简单说下Kconfig的语法使用。
1.菜单入口
1 |
|
mainmenu为主菜单入口,就是配置界面最顶部显示的内容。后面的字符串为主菜单入口名称,可以可以使用$引用环境变量。
1 |
|
menu为子菜单入口,通过关键字menu和endmenu来覆盖所有的配置选项,这两个关键字中间的所有配置选项都是通过这个界面上的子菜单入口进入后进行选择和编辑的。
menuconfig同样是子菜单入口的关键字,和menu不一样的是,它定义的菜单入口可以被选择,然后可以通过if endif来把依赖于这个菜单入口的配置选项罗列出来,比如:
1 |
|
2.配置选项
1 |
|
Kconfig使用关键字cofnig来定义配置选项,后面通过不同的关键字来定义配置属性,如下:
- tristate、bool、hex、int、string
- 配置选项类型
- 语法: tristate/bool/hex/int/string
- 后面如果紧跟“自定义提示符”,就可以省去prompt关键字描述
- prompt
- 配置选项提示语句
- 语法:prompt “自定义提示语句”
- default
- 后面的值会作为配置选项的默认值
- depend on
- 向前依赖
- 表示该配置选项是否可用是依赖于其他的配置选项的。
- select
- 向后依赖
- 表示该配置选项的选择会导致其他配置选项被自动选择。
- 界面中使用”{ }” 或者 “- -“来表示
- option: env表示从环境变量中获取这个配置选项的值。
- 语法:option env=”ENV_NAME”
- range: 设置配置选项的合法取值范围,针对int和hex类型
- 语法:”range” <最小值> <最大值>最大值>最小值>
- help or —help—
- 帮助文档
- 语法: 关键字下面开始直到空行都是帮助说明的内容
3.多选一
Kconfig使用关键字choice和endchoice来组织一个选择列表,只能选中其中一个。
语法如下:
1 |
|
4.包含其他Kconfig文件
可以使用source关键字来包含其他Kconfig文件,相当于C语言的include。
语法:source “kconfig_file”