文章目录
在前两章中我们知道 uboot 可以通过 mx6ull_luatao_emmc_defconfig 来配置,或者通过文件 mx6ull_luatao_emmc.h 来配置 uboot。还有另外一种配置 uboot 的方法,就是图形化配置,以前的 uboot 是不支持图形化配置,只有 Linux 内核才支持图形化配置。不过不知道从什么时候开始,uboot 也支持图形化配置了,
一、U-Boot图形化配置体验
1.图像界面依赖
uboot 或 Linux 内核可以通过输入“make menuconfig”来打开图形化配置界面,menuconfig是一套图形化的配置工具,需要 ncurses 库支持。ncurses 库提供了一系列的 API 函数供调用者生成基于文本的图形界面,因此需要先在 Ubuntu 中安装 ncurses 库,命令如下
sudo apt-get install build-essential
sudo apt-get install libncurses5-dev
menuconfig 重点会用到两个文件:.config 和 Kconfig,.config 文件前面已经说了,这个文件保存着 uboot 的配置项,使用 menuconfig 配置完 uboot 以后肯定要更新.config 文件。Kconfig文件是图形界面的描述文件,也就是描述界面应该有什么内容,很多目录下都会有 Kconfig 文件。
2.图像界面操作
在打开图形化配置界面之前,要先使用“make xxx_defconfig”对 uboot 进行一次默认配置,只需要一次即可。如果使用“make clean”清理了工程的话就那就需要重新使用“make xxx_defconfig”再对 uboot 进行一次配置。进入 uboot 根目录,输入如下命令
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_luatao_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
进入图像化配置界面
通过键盘上的“↑”和“↓”键来选择要配置的菜单,按下“Enter”键进入子菜单。菜单中高亮的字母就是此菜单的热键,在键盘上按下此高亮字母对应的键可以快速选中对应的菜单。
选中子菜单以后按下“Y”键就会将相应的代码编译进 Uboot 中,菜单前面变为“< * >”。
按下“N”键不编译相应的代码,
按下“M”键就会将相应的代码编译为模块,菜单前面变为“< M >”。
按两下“Esc”键退出,也就是返回到上一级,
按下“?”键查看此菜单的帮助信息,
按下“/”键打开搜索框,可以在搜索框输入要搜索的内容。
在配置界面下方会有五个按钮,这五个按钮的功能如下:
:选中按钮,和“Enter”键的功能相同,负责选中并进入某个菜单。
:退出按钮,和按两下“Esc”键功能相同,退出当前菜单,返回到上一级。
:帮助按钮,查看选中菜单的帮助信息。
:保存按钮,保存修改后的配置文件。
:加载按钮,加载指定的配置文件。
3.使能dns
我们就以如何使能 dns 命令为例,讲解一下如何通过图形化界面来配置 uboot。进入“Command line interface —>”这个配置项,此配置项用于配置 uboot 的命令,进入以后如图
选择“Network commands—>”,进入网络相关命令配置项,
uboot 中有很多和网络有关的命令,比如 bootp、tftpboot、dhcp 等等。
选中 dns,然后按下键盘上的“Y”键,此时 dns 前面的“[ ]”变成了“[ * ]”
每个选项有 3 种编译选项:
编译进 uboot 中(也就是编译进 u-boot.bin 中)、
取消编译(也就是不编译这个功能模块)、
编译为模块。
按下“Y”键表示编译进 uboot 中,此时“[ ]”变成了“[ * ]”;
按下“N”表示不编译,“[ ]”默认表示不编译;
有些功能模块是支持编译为模块的,这个一般在 Linux 内核里面很常用,uboot 下面不使用,如果要将某个功能编译为模块,那就按下“M”,此时“[ ]”就会变为“< M >”。
细心的朋友应该会发现,在 mx6ull_luatao_emmc.h 里面我们配置使能了 dhcp 和 ping 命令,但是在图 中 dhcp 和 ping 前面的“[ ]”并不是“[ * ]”,也就是说不编译 dhcp 和 ping命令,这不是冲突了吗?实际情况是 dhcp 和 ping 命令是会编译的。之所以在图中没有体现出来时因为我们是直接在 mx6ull_luatao_emmc.h 中定义的宏 CONFIG_CMD_PING 和CONFIG_CMD_DHCP,而 menuconfig 是通过读取.config 文件来判断使能了哪些功能,.config里面并没有宏CONFIG_CMD_PING和CONFIG_CMD_DHCP,所以menuconfig就会识别出错。
按两下esc返回上一级界面
如果修改了文件会在退出的时候提示是否保存,选择是。
至此,我们就完成了通过图形界面使能了 uboot 的 dns 命令,打开.config文件,会发现多了“CONFIG_CMD_DNS=y”这一行,
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4
编译完成以后烧写到 SD 卡中,重启开发板进入 uboot 命令模式,输入“?”查看是否有“dns”命令,一般肯定有的。
使用 dns 命令来查看一下百度官网“www.baidu.com”的 IP 地址。
要先设置一下 dns 服务器的 IP 地址,也就是设置环境变量 dnsip 的值,命令如下:
setenv dnsip 114.114.114.114
saveenv
设置好以后就可以使用 dns 命令查看百度官网的 IP 地址了,输入命令
dns www.baidu.com
二、menuconfig图形化配置原理
1.make menuconfig过程分析
当输入 make menuconfig 以后会匹配到顶层 Makefile 的如下代码
其中 build=-f ./scripts/Makefile.build obj,将 477行的规则展开就是:
@ make -f ./scripts/Makefile.build obj=scripts/kconfig menuconfig
Makefile.build 会读取 scripts/kconfig/Makefile 中的内容,在 scripts/kconfig/Makefile 中可以找到如下代码:
其中obj= scripts/kconfig,silent是设置静默编译的,在这里可以忽略不计,Kconfig=Kconfig,
因此扩展以后就是:
menuconfig: scripts/kconfig/mconf
scripts/kconfig/mconf Kconfig
目标 menuconfig 依赖 scripts/kconfig/mconf,因此scripts/kconfig/mconf.c 这个文件会被编译,生成 mconf 这个可执行文件。目标 menuconfig 对应的规则为 scripts/kconfig/mconf Kconfig,也就是说 mconf 会调用 uboot 根目录下的 Kconfig 文件开始构建图形配置界面。
2.Kconfig语法简介
接下来简单学习一下 Kconfig 的语法。因为后面学习 Linux 驱动开发的时候可能会涉及到修改 Kconfig,对于 Kconfig 语法我们不需要太深入的去研究,
关于 Kconfig的详细语法介绍,可以参考 linux 内核源码(不知为何 uboot 源码中没有这个文件)中的文件Documentation/kbuild/kconfig-language.txt,本节我们大概了解其原理即可。
打开 uboot 根目录下的Kconfig,这个Kconfig文件就是顶层Kconfig,我们就以这个文件为例来简单学习一下Kconfig语法。
1.mainmenu
顾名思义 mainmenu 就是主菜单,也就是输入“make menuconfig”以后打开的默认界面,在顶层 Kconfig 中有如下代码
mainmenu "U-Boot $UBOOTVERSION Configuration"
上述代码就是定义了一个名为“U-Boot $UBOOTVERSION Configuration”的主菜单,其中UBOOTVERSION=2016.03,因此主菜单名为“U-Boot 2016.03 Configuration”
2.调用其他目录下的 Kconfig
和 makefile 一样,Kconfig 也可以调用其他子目录中的 Kconfig 文件,调用方法如下:
source "xxx/Kconfig" //xxx 为具体的目录名,相对路径
Kconfig 文件调用了很多其他子目录下的 Kcofig 文件,这些子目录下的 Kconfig 文件在主菜单中生成各自的菜单项。
3.menu/endmenu 条目
menu 用于生成菜单,endmenu 就是菜单结束标志,这两个一般是成对出现的。
第 14行的“menu “General setup””表示子菜单“General setup”。
在“General setup”菜单上面还有 “Architecture select (ARM architecture)”和“ARM architecture”这两个子菜单,但是在顶层 Kconfig 中并没有看到这两个子菜单对应的 menu/endmenu 代码块,那这两个子菜单是怎么来的呢?这两个子菜单就是 arch/Kconfig 文件生成的。包括主界面中的“Boot timing”、“Console recording”等等这些子菜单,都是分别由顶层Kconfig 所调用的 common/Kconfig、cmd/Kconfig 等这些子 Kconfig 文件来创建的。
4.config 条目
顶层 Kconfig 中的“General setup”子菜单内容如下
在 menu/endmenu 代码块中有大量的“config xxxx”的代码块,也就是 config 条目。config 条目就是“General setup”菜单的具体配置项,如图 所示:
我 们 以 “ config LOCALVERSION ” 和 “ config LOCALVERSION_AUTO”这两个为例来分析一下 config 配置项的语法
假如我们使能了 LOCALVERSION_AUTO这个功能,那么就会下.config 文件中生成 CONFIG_LOCALVERSION_AUTO,由此可知,.config 文件中的“CONFIG_xxx” (xxx 就是具体的配置项名字)就是 Kconfig 文件中 config 关键字后面的配置项名字加上“CONFIG_”前缀。
config 关键字下面的这几行是配置项属性,属性里面描述了配置项的类型、输入提示、依赖关系、帮助信息和默认值等
第 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”就是这个配置项在图形界面上的显示出来的标题。
help 表示帮助信息,告诉我们配置项的含义,当我们按下“h”或“?”弹出来的帮助界面就是 help 的内容。
“default y”表示 CONFIG_LOCALVERSION_AUTO 的默认值就是 y,所以这一行默认会被选中。
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”这四个也会被选中。
6.choice/endchoice
在 arch/Kconfig 文件中有如下代码:
choice/endchoice 代码段定义了一组可选择项,将多个类似的配置项组合在一起,供用户单选或者多选。以从 ARC、ARM、AVR32 等这些架构中选择,这里是单选
第 12 行的 prompt 给出这个choice/endchoice 段的提示信息为“Architecture select”。
7.menuconfig
menuconfig 和 menu 很类似,但是 menuconfig 是个带选项的菜单,其一般用法为
第 1 行,定义了一个可选的菜单 MODULES,只有选中了 MODULES 第 3~5 行 if 到 endif之间的内容才会显示。在顶层 Kconfig 中有如下代码:
第 74~99 行使用 menuconfig 实现了一个菜单,路径如下:
General setup
-> Configure standard U-Boot features (expert users) —>
前面有“[ ]”说明这个菜单是可选的,当选中这个菜单以后就可以
进入到子选项中,也就是示例代码 34.2.2.9 中的第 83~99 行所描述的菜单,
8.comment
comment 用 于 注 释 , 也 就 是 在 图 形 化 界 面 中 显 示 一 行 注 释 , 打 开 文 件drivers/mtd/nand/Kconfig,有如下所示代码:
第 81 行使用 comment 标注了一行注释,注释内容为:“Generic NAND options”,这行注释
在配置项 NAND_ARASAN 的下面。在图形化配置界面中按照如下路径打开:
-> Device Drivers
-> NAND Device Support
9.source
source 用于读取另一个 Kconfig,比如:source “arch/Kconfig”
三、添加自定义菜单
图形化配置工具的主要工作就是在.config 下面生成前缀为“CONFIG_”的变量,这些变量一般都要值,为 y,m 或 n,在 uboot 源码里面会根据这些变量来决定编译哪个文件。本小节我们就来学习一下如何添加自己的自定义菜单,自定义菜单要求如下:
①、在主界面中添加一个名为“My test menu”,此菜单内部有一个配置项。
②、配置项为“MY_TESTCONFIG”,此配置项处于菜单“My test menu”中。
③、配置项的为变量类型为 bool,默认值为 y。
④、配置项菜单名字为“This is my test config”。
⑤、配置项的帮助内容为“This is a empty config, just for tset!”。
打开顶层 Kconfig,在最后面加入如下代码:
menu "My test menu"
config MY_TESTCONFIG
bool "This is my test config"
default y
help
This is a empty config, just for test!
endmenu # my test menu
执行
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
主菜单最后面出现了一个名为“My test menu”的子菜单,这个就是
我们上面添加进来的子菜单。进入此子菜单
按H打开帮助文档
帮助信息也正确。配置项 MY_TESTCONFIG 默认也是被选中的,
因此在.config 文件中肯定会有“CONFIG_MY_TESTCONFIG=y”这一行
我们在主菜单添加自己的自定义菜单就成功了,