1 ncurses 库安装#
uboot 或 Linux 内核可以通过输入make menuconfig
来打开图形化配置界面,menuconfig
是一套图形化的配置工具,需要ncurses
库支持。sudo apt-get install build-essential
sudo 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_defconfig
make 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.114
saveenv
设置好以后就可以使用 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 menuconfig
Makefile.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”
这一行。