U-Boot 图形化配置及其原理

news2024/12/23 8:12:28

目录

  • U-Boot 图形化配置体验
  • menuconfig 图形化配置原理
    • make menuconfig 过程分析
    • Kconfig 语法简介
  • 添加自定义菜单

在前两章中我们知道uboot 可以通过mx6ull_alientek_emmc_defconfig 来配置,或者通过文件mx6ull_alientek_emmc.h 来配置uboot。还有另外一种配置uboot 的方法,就是图形化配置,以前的uboot 是不支持图形化配置,只有Linux 内核才支持图形化配置。不过不知道从什么时候开始,uboot 也支持图形化配置了,本章我们就来学习一下如何通过图形化配置uboot,并且学习一下图形化配置的原理,因为后面学习Linux 驱动开发的时候可能要修改图形配置文件。

U-Boot 图形化配置体验

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 文件。
在打开图形化配置界面之前,要先使用“make xxx_defconfig”对uboot 进行一次默认配置,只需要一次即可。如果使用“make clean”清理了工程的话就那就需要重新使用“make xxx_defconfig”再对uboot 进行一次配置。进入uboot 根目录,输入如下命令:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_alientek_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

如果已经在uboot 的顶层Makefile 中定义了ARCH 和CROSS_COMPILE 的值,那么上述命令可以简化为:

make mx6ull_alientek_emmc_defconfig
make menuconfig

打开后的图形化界面如图34.1.1 所示:

在这里插入图片描述
图34.1.1 uboot 图形化配置界面

图34.1.1 就是主界面,主界面上方的英文就是简单的操作说明,操作方法如下:
通过键盘上的“↑”和“↓”键来选择要配置的菜单,按下“Enter”键进入子菜单。菜单中高亮的字母就是此菜单的热键,在键盘上按下此高亮字母对应的键可以快速选中对应的菜单。
选中子菜单以后按下“Y”键就会将相应的代码编译进Uboot 中,菜单前面变为“< * >”。按下“N”键不编译相应的代码,按下“M”键就会将相应的代码编译为模块,菜单前面变为“< M >”。
按两下“Esc”键退出,也就是返回到上一级,按下“?”键查看此菜单的帮助信息,按下“/”键打开搜索框,可以在搜索框输入要搜索的内容。
在配置界面下方会有五个按钮,这五个按钮的功能如下:
:选中按钮,和“Enter”键的功能相同,负责选中并进入某个菜单。
:退出按钮,和按两下“Esc”键功能相同,退出当前菜单,返回到上一级。
:帮助按钮,查看选中菜单的帮助信息。
:保存按钮,保存修改后的配置文件。
:加载按钮,加载指定的配置文件。
在图34.1.1 中共有13 个配置主配置项,通过键盘上的上下键调节配置项。后面跟着“—>”
表示此配置项是有子配置项的,按下回车键就可以进入子配置项。
我们就以如何使能dns 命令为例,讲解一下如何通过图形化界面来配置uboot。进入
“Command line interface —>”这个配置项,此配置项用于配置uboot 的命令,进入以后如图34.1.2 所示:

在这里插入图片描述
图34.1.2 Command line interface 配置项

从图34.1.2 可以看出,有很多配置项,这些配置项也有子配置项,选择“Network commands—>”,进入网络相关命令配置项,如图34.1.3 所示:

在这里插入图片描述
图34.1.3 Network commands 配置项

从图34.1.3 可以看出,uboot 中有很多和网络有关的命令,比如bootp、tftpboot、dhcp 等等。选中dns,然后按下键盘上的“Y”键,此时dns 前面的“[ ]”变成了“[ * ]”,如图34.1.4所示:
在这里插入图片描述
图34.1.4 选中dns 命令

每个选项有3 种编译选项:编译进uboot 中(也就是编译进u-boot.bin 中)、取消编译(也就是不编译这个功能模块)、编译为模块。按下“Y”键表示编译进uboot 中,此时“[ ]”变成了“[ * ]”;
按下“N”表示不编译,“[ ]”默认表示不编译;有些功能模块是支持编译为模块的,这个一般在Linux 内核里面很常用,uboot 下面不使用,如果要将某个功能编译为模块,那就按下“M”,此时“[ ]”就会变为“< M >”。

细心的朋友应该会发现,在mx6ull_alientek_emmc.h 里面我们配置使能了dhcp 和ping 命令,但是在图34.1.3 中dhcp 和ping 前面的“[ ]”并不是“[ * ]”,也就是说不编译dhcp 和ping命令,这不是冲突了吗?实际情况是dhcp 和ping 命令是会编译的。之所以在图34.1.3 中没有体现出来时因为我们是直接在mx6ull_alientek_emmc.h 中定义的宏CONFIG_CMD_PING 和CONFIG_CMD_DHCP,而menuconfig 是通过读取.config 文件来判断使能了哪些能,.config里面并没有宏CONFIG_CMD_PING 和CONFIG_CMD_DHCP,所以menuconfig 就会识别出错。

选中dns,然后按下“H”或者“?”键可以打开dns 命令的提示信息,如图34.1.5 所示:

在这里插入图片描述
图34.1.5 dns 命令提示信息

按两下ESC 键即可退出提示界面,相当于返回上一层。选择dns 命令以后,按两下ESC 键(按两下ESC 键相当于返回上一层),退出当前配置项,进入到上一层配置项。如果没有要修改的就按两下ESC 键,退出到主配界面,如果也没有其他要修改的,那就再次按两下ESC 键退出menuconfig 配置界面。如果修改过配置的话,在退出主界面的时候会有如图34.1.6 所示提示:

在这里插入图片描述
图34.1.6 是否保存新的配置文件对话框

图34.1.6 询问是否保存新的配置文件,通过键盘的←或→键来选择“Yes”项,然后按下键盘上的回车键确认保存。至此,我们就完成了通过图形界面使能了uboot 的dns 命令,打开.config文件,会发现多了“CONFIG_CMD_DNS=y”这一行,如图34.1.7 中的323 行所示:

在这里插入图片描述
图34.1.7 .config 文件

使用如下命令编译uboot:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j16

千万不能使用如下命令:

./mx6ull_alientek_emmc.sh

因为mx6ull_alientek_emmc.sh 在编译之前会清理工程,会删除掉.config 文件!通过图形化界面配置所有配置项都会被删除,结果就是竹篮打水一场空。
编译完成以后烧写到SD 卡中,重启开发板进入uboot 命令模式,输入“?”查看是否有“dns”命令,一般肯定有的。使用dns 命令来查看一下百度官网“www.baidu.com”的IP 地址。
注意!如果要与外部互联网通信,比如百度官网,这个时候要保证开发板能访问到外部互联网。如果你的开发板和电脑直接用网线连接的,那么肯定无法连接到外部网络,这个时候dns命令查看百度官网也会失败!所以开发板一定要连接到路由器上,而且要保证你的路由器能访问外网,比如手机连接到这个路由器上以后可以正常访问互联网。
要先设置一下dns 服务器的IP 地址,也就是设置环境变量dnsip 的值,命令如下:

setenv dnsip 114.114.114.114
saveenv

设置好以后就可以使用dns 命令查看百度官网的IP 地址了,输入命令:

dns www.baidu.com

结果如图34.1.8 所示:

在这里插入图片描述
图34.1.78dns 命令

从图34.1.7 可以看出,“www.baidu.com”的IP 地址为14.215.177.38,说明dns 命令工作正常。这个就是通过图形化命令来配置uboot,一般用来使能一些命令还是很方便的,这样就不需要到处找命令的配置宏是什么,然后在到配置文件里面去定义。

menuconfig 图形化配置原理

make menuconfig 过程分析

当输入make menuconfig 以后会匹配到顶层Makefile 的如下代码:

示例代码34.2.1.1 顶层Makefile 代码段
489 %config: scripts_basic outputmakefile FORCE
490 $(Q)$(MAKE) $(build)=scripts/kconfig $@

这个在31.3.13 小节已经详细的讲解过了,其中build=-f ./scripts/Makefile.build obj,将490行的规则展开就是:

@ make -f ./scripts/Makefile.build obj=scripts/kconfig menuconfig

Makefile.build 会读取scripts/kconfig/Makefile 中的内容,在scripts/kconfig/Makefile 中可以找到如下代码:

示例代码34.2.1.2 scripts/kconfig/Makefile 代码段
36 menuconfig: $(obj)/mconf
37 $< $(silent) $(Kconfig)

其中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 文件开始构建图形配置界面。

Kconfig 语法简介

上一小节我们已经知道了scripts/kconfig/mconf 会调用uboot 根目录下的Kconfig 文件开始构建图形化配置界面,接下来简单学习一下Kconfig 的语法。因为后面学习Linux 驱动开发的时候可能会涉及到修改Kconfig,对于Kconfig 语法我们不需要太深入的去研究,关于Kconfig的详细语法介绍,可以参考linux 内核源码(不知为何uboot 源码中没有这个文件)中的文件Documentation/kbuild/kconfig-language.txt,本节我们大概了解其原理即可。打开uboot 根目录下的Kconfig,这个Kconfig 文件就是顶层Kconfig,我们就以这个文件为例来简单学习一下Kconfig语法。
1、mainmenu
顾名思义mainmenu 就是主菜单,也就是输入“make menuconfig”以后打开的默认界面,在顶层Kconfig 中有如下代码:

示例代码34.2.2.1 顶层Kconfig 代码段
5 mainmenu "U-Boot $UBOOTVERSION Configuration"

上述代码就是定义了一个名为“U-Boot $UBOOTVERSION Configuration”的主菜单,其中
UBOOTVERSION=2016.03,因此主菜单名为“U-Boot 2016.03 Configuration”,如图34.2.2.1 所示:

在这里插入图片描述
图34.2.2.1 主菜单名字

2、调用其他目录下的Kconfig 文件
和makefile 一样,Kconfig 也可以调用其他子目录中的Kconfig 文件,调用方法如下:

source "xxx/Kconfig" //xxx 为具体的目录名,相对路径

在顶层Kconfig 中有如下代码:

示例代码34.2.2.2 顶层Kconfig 代码段
12 source "arch/Kconfig"
......
225
226 source "common/Kconfig"
227
228 source "cmd/Kconfig"
229
230 source "dts/Kconfig"
231
232 source "net/Kconfig"
233
234 source "drivers/Kconfig"
235
236 source "fs/Kconfig"
237
238 source "lib/Kconfig"
239
240 source "test/Kconfig"

从示例代码34.2.2.2 中可以看出,顶层Kconfig 文件调用了很多其他子目录下的Kcofig 文件,这些子目录下的Kconfig 文件在主菜单中生成各自的菜单项。
3、menu/endmenu 条目
menu 用于生成菜单,endmenu 就是菜单结束标志,这两个一般是成对出现的。在顶层Kconfig 中有如下代码:

示例代码34.2.2.3 顶层Kconfig 代码段
14 menu "General setup"
15
16 config LOCALVERSION
17 string "Local version - append to U-Boot release"
18 help
19 Append an extra string to the end of your U-Boot version.
20 This will show up on your boot log, for example.
21 The string you set here will be appended after the contents of
22 any files with a filename matching localversion* in your
23 object and source tree, in that order. Your total string can
24 be a maximum of 64 characters.
25
......
100 endmenu # General setup
101
102 menu "Boot images"
103
104 config SUPPORT_SPL
105 bool
106
......
224 endmenu # Boot images

示例代码34.2.2.3 中有两个menu/endmenu 代码块,这两个代码块就是两个子菜单,第14行的“menu “General setup””表示子菜单“General setup”。第102 行的“menu “Boot images””表示子菜单“Boot images”。体现在主菜单界面中就如图34.2.2.2 所示:

在这里插入图片描述
图34.2.2.2 子菜单

在“General setup”菜单上面还有“Architecture select (ARM architecture)”和“ARM architecture ”这两个子菜单,但是在顶层Kconfig 中并没有看到这两个子菜单对应的menu/endmenu 代码块,那这两个子菜单是怎么来的呢?这两个子菜单就是arch/Kconfig 文件生成的。包括主界面中的“Boot timing”、“Console recording”等等这些子菜单,都是分别由顶层Kconfig 所调用的common/Kconfig、cmd/Kconfig 等这些子Kconfig 文件来创建的。
3、config 条目
顶层Kconfig 中的“General setup”子菜单内容如下:

示例代码34.2.2.4 顶层Kconfig 代码段
14 menu "General setup"
15
16 config LOCALVERSION
17 string "Local version - append to U-Boot release"
18 help
19 Append an extra string to the end of your U-Boot version.
20 This will show up on your boot log, for example.
21 The string you set here will be appended after the contents of
22 any files with a filename matching localversion* in your
23 object and source tree, in that order. Your total string can
24 be a maximum of 64 characters.
25
26 config LOCALVERSION_AUTO
27 bool "Automatically append version information to the version string"
28 default y
29 help
......
45
46 config CC_OPTIMIZE_FOR_SIZE
47 bool "Optimize for size"
48 default y
49 help
......
54
55 config SYS_MALLOC_F
56 bool "Enable malloc() pool before relocation"
57 default y if DM
58 help
......
63
64 config SYS_MALLOC_F_LEN
65 hex "Size of malloc() pool before relocation"
66 depends on SYS_MALLOC_F
67 default 0x400
68 help
......
73
74 menuconfig EXPERT
75 bool "Configure standard U-Boot features (expert users)"
76 default y
77 help
......
82
83 if EXPERT
84 config SYS_MALLOC_CLEAR_ON_INIT
85 bool "Init with zeros the memory reserved for malloc (slow)"
86 default y
87 help
......
99 endif
100 endmenu # General setup

可以看出,在menu/endmenu 代码块中有大量的“config xxxx”的代码块,也就是config 条目。config 条目就是“General setup”菜单的具体配置项,如图34.2.2.3 所示:

在这里插入图片描述
图34.2.2.3 General setup 配置项

“config LOCALVERSION”对应着第一个配置项,“config LOCALVERSION_AUTO”对应着第二个配置项,以此类推。我们以“config LOCALVERSION ”和“config LOCALVERSION_AUTO”这两个为例来分析一下config 配置项的语法:

示例代码34.2.2.5 顶层Kconfig 代码段
16 config LOCALVERSION
17 string "Local version - append to U-Boot release"
18 help
19 Append an extra string to the end of your U-Boot version.
......
24 be a maximum of 64 characters.
25
26 config LOCALVERSION_AUTO
27 bool "Automatically append version information to the version string"
28 default y
29 help
30 This will try to automatically determine if the current tree is a
31 release tree by looking for git tags that belong to the current
......
43
44 which is done within the script "scripts/setlocalversion".)

第16 和26 行,这两行都以config 关键字开头,后面跟着LOCALVERSION 和
LOCALVERSION_AUTO,这两个就是配置项名字。假如我们使能了LOCALVERSION_AUTO
这个功能,那么就会下.config 文件中生成CONFIG_LOCALVERSION_AUTO,这个在上一小节讲解如何使能dns 命令的时候讲过了。由此可知,.config 文件中的“CONFIG_xxx”(xxx 就是具体的配置项名字)就是Kconfig 文件中config 关键字后面的配置项名字加上“CONFIG_”前缀。
config 关键字下面的这几行是配置项属性,17~ 24 行是LOCALVERSION 的属性,27~44 行
是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 是个字符串变量,用来存储本地字符串,选中以后即可输入用户定义的本地版本号,如图34.2.2.4 所示:

在这里插入图片描述
图34.2.2.4 本地版本号配置

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,所以这一行默认会被选中。
4、depends on 和select
打开arch/Kconfig 文件,在里面有这如下代码:

示例代码34.2.2.6 arch/Kconfig 代码段
7 config SYS_GENERIC_BOARD
8 bool
9 depends on HAVE_GENERIC_BOARD
10
11 choice
12 prompt "Architecture select"
13 default SANDBOX
14
15 config ARC
16 bool "ARC architecture"
17 select HAVE_PRIVATE_LIBGCC
18 select HAVE_GENERIC_BOARD
19 select SYS_GENERIC_BOARD
20 select SUPPORT_OF_CONTROL

第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”这四个也会被选中。
4、choice/endchoice
在arch/Kconfig 文件中有如下代码:

示例代码34.2.2.7 arch/Kconfig 代码段
11 choice
12 prompt "Architecture select"
13 default SANDBOX
14
15 config ARC
16 bool "ARC architecture"
......
21
22 config ARM
23 bool "ARM architecture"
......
29
30 config AVR32
31 bool "AVR32 architecture"
......
35
36 config BLACKFIN
37 bool "Blackfin architecture"
......
40
41 config M68K
42 bool "M68000 architecture"
......
117
118 endchoice

choice/endchoice 代码段定义了一组可选择项,将多个类似的配置项组合在一起,供用户单选或者多选。示例代码34.2.2.7 就是选择处理器架构,可以从ARC、ARM、AVR32 等这些架构中选择,这里是单选。在uboot 图形配置界面上选择“Architecture select”,进入以后如图34.2.2.5所示:

在这里插入图片描述
图34.2.2.5 架构选择界面

可以在图34.2.2.5 中通过移动光标来选择所使用的CPU 架构。第12 行的prompt 给出这个choice/endchoice 段的提示信息为“Architecture select”。
5、menuconfig
menuconfig 和menu 很类似,但是menuconfig 是个带选项的菜单,其一般用法为:

示例代码34.2.2.8 menuconfig 用法
1 menuconfig MODULES
2 bool "菜单"
3 if MODULES
4 ...
5 endif # MODULES

第1 行,定义了一个可选的菜单MODULES,只有选中了MODULES 第3~5 行if 到endif之间的内容才会显示。在顶层Kconfig 中有如下代码:

示例代码34.2.2.9 顶层Kconfig 代码段
14 menu "General setup"
......
74 menuconfig EXPERT
75 bool "Configure standard U-Boot features (expert users)"
76 default y
77 help
78 This option allows certain base U-Boot options and settings
79 to be disabled or tweaked. This is for specialized
80 environments which can tolerate a "non-standard" U-Boot.
81 Only use this if you really know what you are doing.
82
83 if EXPERT
84 config SYS_MALLOC_CLEAR_ON_INIT
85 bool "Init with zeros the memory reserved for malloc (slow)"
86 default y
87 help
88 This setting is enabled by default. The reserved malloc
89 memory is initialized with zeros, so first malloc calls
......
98 should be replaced by calloc - if expects zeroed memory.
99 endif
100 endmenu # General setup

第74~99 行使用menuconfig 实现了一个菜单,路径如下:

General setup
	-> Configure standard U-Boot features (expert users) --->

如图34.2.2.6 所示:

在这里插入图片描述
图34.2.2.6 菜单Configure standard U-Boot features (expert users)

从图34.2.2.6 可以看到,前面有“[ ]”说明这个菜单是可选的,当选中这个菜单以后就可以进入到子选项中,也就是示例代码34.2.2.9 中的第83~99 行所描述的菜单,如图34.2.2.7 所示:

在这里插入图片描述
图34.2.2.7 菜单Init with zeros the memory reserved for malloc (slow)

如果不选择“Configure standard U-Boot features (expert users)”,那么示例代码34.2.2.9 中的第83~99 行所描述的菜单就不会显示出来,进去以后是空白的。
6、comment
comment 用于注释,也就是在图形化界面中显示一行注释,打开文件drivers/mtd/nand/Kconfig,有如下所示代码:

示例代码34.2.2.10 drivers/mtd/nand/Kconfig 代码段
74 config NAND_ARASAN
75 bool "Configure Arasan Nand"
76 help
......
80
81 comment "Generic NAND options"

第81 行使用comment 标注了一行注释,注释内容为:“Generic NAND options”,这行注释在配置项NAND_ARASAN 的下面。在图形化配置界面中按照如下路径打开:

-> Device Drivers
-> NAND Device Support

结果如图34.2.2.8 所示:

在这里插入图片描述
图34.2.2.8 注释“Generic NAND options”

从图34.2.2.8 可以看出,在配置项“Configure Arasan Nand”下面有一行注释,注释内容为
“*** Generic NAND options ***”。
7、source
source 用于读取另一个Kconfig,比如:

source "arch/Kconfig"

这个在前面已经讲过了。
Kconfig 语法就讲解到这里,基本上常用的语法就是这些,因为uboot 相比Linux 内核要小很多,所以配置项也要少很多,所以建议大家使用uboot 来学习Kconfig。一般不会修改uboot中的Kconfig 文件,甚至都不会使用uboot 的图形化界面配置工具,本小节学习Kconfig 的目的主要还是为了Linux 内核作准备。

添加自定义菜单

图形化配置工具的主要工作就是在.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,在最后面加入如下代码:

示例代码34.3.1 自定义菜单
1 menu "My test menu"
2
3 config MY_TESTCONFIG
4 bool "This is my test config"
5 default y
6 help
7 This is a empty config, just for test!
8
9 endmenu # my test menu

添加完成以后打开图形化配置界面,如图34.3.1 所示:

在这里插入图片描述
图34.3.1 主界面

从图34.3.1 可以看出,主菜单最后面出现了一个名为“My test menu”的子菜单,这个就是我们上面添加进来的子菜单。进入此子菜单,如图34.3.2 所示:

在这里插入图片描述
图34.3.2 “My test menu”子菜单

从图34.3.2 可以看出,配置项添加成功,选中“This is my test config”配置项,然后按下“H”键打开帮助文档,如图34.3.3 所示:

在这里插入图片描述
图34.3.3 帮助信息

从图34.3.3 可以看出,帮助信息也正确。配置项MY_TESTCONFIG 默认也是被选中的,因此在.config 文件中肯定会有“CONFIG_MY_TESTCONFIG=y”这一行,如图34.3.4 所示:

在这里插入图片描述
图34.3.4 .config 文件

至此,我们在主菜单添加自己的自定义菜单就成功了,以后大家如果去半导体原厂工作的话,如果要编写Linux 驱动,那么很有可能需要你来修改甚至编写Kconfig 文件。Kconfig 语法其实不难,重要的点就是34.2.2 小节中的那几个,最主要的是记住:Kconfig 文件的最终目的就是在.config 文件中生成以“CONFIG_”开头的变量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1199887.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

理解快速排序

理解快速排序 首先了解以下快速排序 快速排序&#xff08;QuickSort&#xff09;是一种常用的排序算法&#xff0c;属于比较排序算法的一种。它是由英国计算机科学家Tony Hoare于1960年提出的&#xff0c;是一种分而治之&#xff08;divide and conquer&#xff09;的算法。 …

systemd-timesyncd

介绍 systemd-timesyncd 是一个用于跨网络同步系统时钟的守护服务。它实现了一个 SNTP 客户端。与NTP的复杂实现相比&#xff0c;这个服务简单的多&#xff0c;它只专注于从远程服务器查询然后同步到本地时钟。除非你打算为客户端提供 NTP 服务器或者连接本地硬件时钟&#xff…

Keras实现图注意力模型GAT

简介&#xff1a;本文实现了一个GAT图注意力机制的网络层&#xff0c;可以在Keras中像调用Dense网络层、Input网络层一样直接搭积木进行网络组合。 一&#xff0c;基本展示 如下图所示&#xff0c;我们输入邻接矩阵和节点特征矩阵之后&#xff0c;可以直接调用myGraphAttention…

第90步 深度学习图像分割:U-Net建模

基于WIN10的64位系统演示 一、写在前面 从这一期开始&#xff0c;我们杀个回马枪&#xff0c;继续学习深度学习图像分割系列&#xff0c;以为4090上岗了。 图像分割是计算机视觉的一个重要任务&#xff0c;目的是将数字图像分割成多个部分或区域&#xff0c;这些部分通常对应…

大话IEC104 规约

2. iec104 协议的帧结构 iec104 基于TCP/IP 传输&#xff0c;是一个应用层协议&#xff0c; 其帧结构被称为 APDU&#xff0c;APDU 一般由 APCI 和 ASDU组成。 2.1 APDU (Application Protocol Data Unit) APDU 被称为应用协议数据单元&#xff0c;也就是一个iec104 的协议帧…

详解—搜索二叉树

一.二叉搜索树 1.1概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值 它的…

Android修行手册 - 可变参数中星号什么作用(冷知识)

点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&…

No183.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

【MySQL系列】 第一章 · MySQL概述

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

Visual Studio 2019 写 Unity 脚本时,烦人又离谱的自动补全!

Visual Studio 2019 写 Unity 脚本时&#xff0c;逆天又离谱的自动补全&#xff01; 血压高升的原因 写脚本的时候&#xff0c;智能提示有哪些函数可以使用&#xff0c;是非常棒的一件事情&#xff0c;有助于游戏开发者编写和检查自己的脚本代码。 但是&#xff01; 我想输入…

Leetcode—2469.温度转换【简单】

2023每日刷题&#xff08;二十六&#xff09; Leetcode—2469.温度转换 实现代码 /*** Note: The returned array must be malloced, assume caller calls free().*/ double* convertTemperature(double celsius, int* returnSize) {double* ans (double *)malloc(sizeof(do…

Leetcode—107.二叉树的层序遍历II【中等】

2023每日刷题&#xff08;二十七&#xff09; Leetcode—107.二叉树的层序遍历II 实现代码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullpt…

Radius是什么意思? 安当加密

Radius是什么意思&#xff1f; RADIUS&#xff08;Remote Authentication Dial In User Service&#xff09;是一种远程用户拨号认证系统&#xff0c;它由RFC 2865和RFC 2866定义&#xff0c;是应用最广泛的AAA&#xff08;Authentication、Authorization、Accounting&#xf…

【编程语言发展史】Python的起源和发展历史

目录 Python的起源 Python的发展历史 Python的生态系统和应用领域 Python的社区和发展模式 Python的未来趋势和挑战 Python是一门广受欢迎的高级编程语言&#xff0c;其起源和发展历史自20世纪末至今&#xff0c;经历了多个版本的迭代和社区的广泛参与。以下是关于Python的…

C 语言函数

C 语言函数 在本教程中&#xff0c;将向您介绍C语言编程中的函数&#xff08;用户定义函数和标准库函数&#xff09;。此外&#xff0c;您还将学习为什么在编程中使用函数。 函数是执行特定任务的代码块。 假设您需要创建程序来创建一个圆并为其着色。您可以创建两个函数来解…

goroutine调度模型 调度策略

文章目录 背景 协程线程与协程的对比线程&#xff08;Thread&#xff09;协程&#xff08;Coroutine&#xff09; 运作线程模型 goroutine调度模型与演进过程G-M模型G-P-M模型抢占式调度器其他优化 调度策略队列轮转系统调用工作量窃取抢占式调度GOMAXPROCS 对性能的影响 Go在语…

459. 重复的子字符串

459. 重复的子字符串 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;__459重复的子字符串_枚举__459重复的子字符串_字符串匹配__459重复的子字符串_KMP算法__459重复的子字符串_优化的KMP算法 错误经验吸取 原题链接&#xff1a; 459. …

C 用户定义函数

C 用户定义函数 在本教程中&#xff0c;您将借助示例学习在C语言编程中创建用户定义的函数。 函数是执行特定任务的代码块。 C允许您根据需要定义函数。这些函数称为用户定义函数。例如&#xff1a; 假设您需要创建一个圆并根据半径和颜色为其着色。您可以创建两个函数来解…

No182.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

C语言数据结构-----双向链表增删查改的代码实现

文章目录 1.初始化双链表2.创建链表节点3.打印链表4.尾插5.尾删6.头插7.头删8.在pos之前插入8.1 在pos之前插入(改造头插)8.2 在pos之前插入(改造尾插) 9.删除pos位置9.1 删除pos位置(改造尾删)9.1 删除pos位置(改造头删) 10.查找11.毁灭 链接: 顺序表(动态顺序表增删查改的代码…