1 ncurses 库安装#
uboot 或 Linux 内核可以通过输入make menuconfig来打开图形化配置界面,menuconfig是一套图形化的配置工具,需要ncurses库支持。sudo apt-get install build-essentialsudo apt-get install libncurses5-dev
#
menuconfig 重点会用到两个文件:.config 和 Kconfig,.config 文件前面已经说了,这个文件保存着 uboot 的配置项,使用 menuconfig 配置完 uboot 以后会更新.config 文件。Kconfig文件是图形界面的描述文件,也就是描述界面应该有什么内容,很多目录下都会有Kconfig文件。make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_alientek_emmc_defconfigmake ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
通过键盘上的“↑”和“↓”键来选择要配置的菜单,按下“Enter”键进入子菜单。菜单中高亮的字母就是此菜单的热键,在键盘上按下此高亮字母对应的键可以快速选中对应的菜单。选中子菜单以后按下“Y”键就会将相应的代码编译进 Uboot 中,菜单前面变为“< * >”。按下“N”键不编译相应的代码,按下“M”键就会将相应的代码编译为模块,菜单前面变为“< M >”。按两下“Esc”键退出,也就是返回到上一级,按下“?”键查看此菜单的帮助信息,按下“/”键打开搜索框,可以在搜索框输入要搜索的内容。
在配置界面下方会有五个按钮,这五个按钮的功能如下:
1 | <Select>:选中按钮,和“Enter”键的功能相同,负责选中并进入某个菜单。 |
就以如何使能dns命令为例,讲解一下如何通过图形化界面来配置 uboot。进入“Command line interface --->”这个配置项:
选择“Network commands --->”,进入网络相关命令配置项:
可以看出,uboot 中有很多和网络有关的命令,比如bootp、tftpboot、dhcp等等。选中 dns,然后按下键盘上的“Y”键,此时dns前面的“[ ]”变成了“[ * ]” :
细心的朋友应该会发现,在mx6ull_alientek_emmc.h里面我们配置使能了 dhcp 和ping命令,但是在上图中的“[ ]”并不是“[ * ]”,也就是说不编译dhcp和 ping命令,这不是冲突了吗?实际情况是 dhcp 和 ping 命令是会编译的。之所以在上图中没有体现出来时因为我们是直接在mx6ull_alientek_emmc.h中定义的宏CONFIG_CMD_PING和CONFIG_CMD_DHCP,而 menuconfig 是通过读取.config 文件来判断使能了哪些功能,.config里面并没有宏CONFIG_CMD_PING和CONFIG_CMD_DHCP,因此menuconfig不会选中这两项。
总结下:配置选项来自2个地方,一个是mx6ull_alientek_emmc.h,一个是.config
选中 dns,然后按下“H”或者“?”键可以打开dns命令的帮助提示信息:
选择dns命令以后,按两下 ESC 键(按两下ESC键相当于返回上一层),退出当前配置项,进入到上一层配置项,输入Y保存修改后的配置到.config。
再打开.config,会发现多了“CONFIG_CMD_DNS=y”这一行:
再次编译:make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16
烧录uboot进sd卡,开机从sd卡启动,进入uboot命令行后,输入help或者?就可以看到uboot支持了dns命令。
测试:先将板子连接能上外网的路由器,要先设置一下dns服务器的 IP 地址,也就是设置环境变量 dnsip 的值:setenv dnsip 114.114.114.114saveenv
设置好以后就可以使用 dns 命令查看百度官网的 IP 地址了:dns www.baidu.com
可以看到dns解析命令功能正常。
#
#
同defconfig一样,make menuconfig 也会匹配到顶层 Makefile。
Uboot顶层Makefile解析-1. defconfig过程分析 - fuzidage - 博客园 (cnblogs.com)
uboot-编译defconfig分析 | Hexo (fuzidage.github.io)

其中 build=-f ./scripts/Makefile.build obj, 展开后:make -f ./scripts/Makefile.build obj=scripts/kconfig menuconfigMakefile.build 会读取scripts/kconfig/Makefile中的内容,在scripts/kconfig/Makefile中可以找到如下代码:
其中obj= scripts/kconfig,silent是设置静默编译的,在这里可以忽略不计,Kconfig=Kconfig,因此扩展以后就是:
scripts/kconfig/mconf.c 这个文件会被编译,生成 mconf 这个可执行文件。mconf 会调用 uboot 根目录下的 Kconfig 文件开始构建图形配置界面。
3.1.1 Kconfig 语法简介#
#
输入make menuconfig以后打开的默认界面就是mainmenu,在顶层 Kconfig 中有如下代码:
我们的uboot是UBOOTVERSION=2016.03,如下:
3.1.1.2 子Kconfig#
Kconfig 也可以调用其他子目录中的Kconfig文件,调用方法如下:source "xxx/Kconfig"
顶层Kconfig中,调用了很多子Kconfig:
#
menu 用于生成菜单,endmenu 就是菜单结束标志。在顶层Kconfig 中有如下代码:
体现在主菜单界面如下所示:
在“General setup”菜单上面还有 “Architecture select (ARM architecture)”和“ARM architecture”这两个子菜单,但是在顶层 Kconfig 中并没有看到这两个子菜单对应的menu/endmenu 代码块,那这两个子菜单是怎么来的呢?这两个子菜单就是arch/Kconfig文件生成的。包括主界面中的“Boot timing”、“Console recording”等等这些子菜单,都是分别由顶层Kconfig 所调用的 common/Kconfig、cmd/Kconfig 等这些子Kconfig文件来创建的。
3.1.1.4 config条目#
顶层Kconfig中的“General setup”子菜单内容如下:
1 | 14 menu "General setup" |
可以看到有大量的“config xxxx”的代码块,也就是config条目。“General setup”菜单的config条目具体配置项如下:
“config LOCALVERSION”对应着第一个配置项,“config LOCALVERSION_AUTO”对应着 第 二 个 配 置 项。
① 第 16 和 26 行,这两行都以 config 关键字开头,后面跟着 LOCALVERSION 和LOCALVERSION_AUTO,这两个就是配置项名字。假如我们使能了 LOCALVERSION_AUTO这个功能,那么就会下.config 文件中生成 CONFIG_LOCALVERSION_AUTO。
②config关键字下面的这几行是配置项属性,1724 行是44 行是 LOCALVERSION 的属性,27 LOCALVERSION_AUTO 的属性。
③ 属性里面描述了配置项的类型、输入提示、依赖关系、帮助信息和默认值等。第 17 行的string是变量类型,也就“CONFIG_ LOCALVERSION”的变量类型。可以为:bool、tristate、string、hex 和 int,一共 5 种。最常用的是 bool、tristate 和 string 这三种,bool 类型有两种值:y 和 n,当为 y 的时候表示使能这个配置项,当为 n 的时候就禁止这个配置项。tristate 类型有三种值:y、m 和 n,其中 y 和 n 的涵义与 bool 类型一样,m 表示将这个配置项编译为模块。string 为字符串类型,所以 LOCALVERSION 是个字符串变量,用来存储本地字符串,选中以后即可输入用户定义的本地版本号,如下图:
string 后面的“Local version - append to U-Boot release”就是这个配置项在图形界面上的显示出来的标题。
④ 第 18 行,help 表示帮助信息,告诉我们配置项的含义,当我们按下“h”或“?”弹出来的帮助界面就是 help 的内容。
⑤ 第 27 行,说明“CONFIG_LOCALVERSION_AUTO”是个bool 类型,可以通过按下 Y 或N 键来使能或者禁止 CONFIG_LOCALVERSION_AUTO。
⑥ 第 28 行,“default y”表示 CONFIG_LOCALVERSION_AUTO 的默认值就是 y,所以这一行默认会被选中。
3.1.1.5 depends on 和 select#
打开 arch/Kconfig 文件,在里面有这如下代码:
第 9 行,“depends on”说明“SYS_GENERIC_BOARD”项依赖于“HAVE_GENERIC_BOARD”,也就是说“HAVE_GENERIC_BOARD”被选中以后“SYS_GENERIC_BOARD”才能被选中。
第 17~20 行,“select”表示方向依赖,当选中“ARC”以后,“HAVE_PRIVATE_LIBGCC”、“HAVE_GENERIC_BOARD”、“SYS_GENERIC_BOARD”和“SUPPORT_OF_CONTROL”这四个也会被选中。
3.1.1.6 choice/endchoice#
在arch/Kconfig文件中有如下代码:
1 | 11 choice |
choice/endchoice 代码段定义了一组可选择项,将多个类似的配置项组合在一起,供用户单选或者多选。该示例就是选择处理器架构,可以从ARC、ARM、AVR32等这些架构中选择,这里是单选。在 uboot 图形配置界面上选择“Architecture select”,进入以后如下图:
第 12 行的prompt给出这个choice/endchoice 段的提示信息为“Architecture select”。
#
menuconfig 和 menu 很类似,但是 menuconfig 是个带选项的菜单,如顶层Kconfig中的“General setup”中的列表中有一项menuconfig EXPERT:
结果如下:
可以看到,前面有“[ ]”说明这个菜单是可选的,当选中这个菜单以后就可以进入到子选项中:
如果不选择“Configure standard U-Boot features (expert users)”,那么所描述的菜单就不会显示出来,进去以后是空白的。
3.1.1.8 comment#
comment用于注释, 也就是在图形化界面中显示一行注释。例如drivers/mtd/nand/Kconfig中:
1 | 74 config NAND_ARASAN |
第 81 行使用comment标注了一行注释,注释内容为:“Generic NAND options”,这行注释在配置项 NAND_ARASAN 的下面。
在配置项“Configure Arasan Nand”下面有一行注释,注释内容为“*** Generic NAND options ***”:
#
接下来自定义一个菜单进行练习,自定义菜单要求如下:
①、在主界面中添加一个名为“My test menu”,此菜单内部有一个配置项。
②、配置项为“MY_TESTCONFIG”,此配置项处于菜单“My test menu”中。
③、配置项的为变量类型为 bool,默认值为 y。
④、配置项菜单名字为“This is my test config”
⑤、配置项的帮助内容为“This is a empty config, just for tset!”。
在顶层 Kconfig,在最后面加入如下代码:
1 | 1 menu "My test menu" |
再次执行make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig:
可以看出,主菜单最后面出现了一个名为“My test menu”的子菜单,这个就是上面添加进来的子菜单。进入此子菜单:
可以看出,配置项也添加成功,按H查看帮助信息:
保存退出,打开.config文件:
配置项MY_TESTCONFIG默认也是被选中的,因此在.config 文件中肯定会有“CONFIG_MY_TESTCONFIG=y”这一行。