内核源码树的目录下都有两个文件Kconfig(2.4版本是Config.in)和Makefile。分布到各目录的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文件相关的内核配置菜单。在内核配置make menuconfig(或xconfig等)时,从Kconfig中读出菜单,用户选择后保存到.config的内核配置文件中。在内核编译时,主Makefile调用这个.config,就知道了用户的选择。
每个菜单都有一个关键字标识,最常见的就是config
语法:
config symbol
symbol是一个新的标记的菜单项,options是在这个新的菜单项下的属性和选项
其中options部分有:
1、类型定义:
每个config菜单项都要有类型定义,bool布尔类型、 tristate三态:内建、模块、移除 string字符串、 hex十六进制、 integer整型
例如config HELLO_MODULE
bool “hello test module”
bool类型的只能选中或不选中,tristate类型的菜单项多了编译成内核模块的选项,如果选择编译成内核模块,则会在.config中生成一个CONFIG_HELLO_MODULE=m的配置,如果选择内建,就是直接编译成内核影响,就会在.config中生成一个CONFIG_HELLO_MODULE=y的配置.
2、依赖型定义depends on或requires
指此菜单的出现与否依赖于另一个定义
config HELLO_MODULE
bool “hello test module”
depends on ARCH_PXA
这个例子表明HELLO_MODULE这个菜单项只对XScale处理器有效。
3、帮助性定义
只是增加帮助用关键字help或者—help—
以下为个人观点,欢迎指正和提出不同意见 : )
编译出现“undefined reference”
出现这种问题的意思就是该函数没有被定义,我的分析是以下几种情况:
- 该函数真的没有实现,所以没有地方调用
该函数存在,但是没有被编译,即,xx.o二进制文件没有出现。
2.1 Makefile里面没有加入
obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128-board.o类似的语句,造成了没有真正去编译该.c文件。
2.2Makefile里面有宏定义限制,但是在configs的xxx_defconfig里面却没有定义该宏定义,如CONFIG_PWM=y等没有写上。
2.3Kconfig里面有关宏定义的内容没有加入config symbol或者加了但是没有配置正确。如
config ROCKCHIP_BROM_HELPER
bool “SPL returns to bootrom”
default y if ROCKCHIP_RK3128config SPL_MMC_SUPPORT
default y if !ROCKCHIP_BROM_HELPER
上面列出来的就是该宏定义的配置,用spl的时候返回到bootrom
如果定义 ROCKCHIP_RK3128,就使ROCKCHIP_BROM_HELPER=y
没有定义ROCKCHIP_BROM_HELPER,那么SPL_MMC_SUPPORT=y。已经编译,但是仍然出现undefined reference to ,这就可以直接定位到Kconfig和configs/xxx_defconfig上面了,基本上就是在这里出错了。
思考为什么会有这样的判断呢?这从根本上来看是有没有开宏定义所决定的。做个假设,如果都能编译成功,那么uboot文件下会出现一个u-boot.cfg的文件,打开它,会豁然顿悟:
.#define CONFIG_LOCALVERSION_AUTO 1
.#define CONFIG_REGULATOR_PWM 1
.#define CONFIG_SYS_SDRAM_BASE 0
.#define CONFIG_IMAGE_FORMAT_LEGACY
.#define CONFIG_SYS_BOOT_RAMDISK_HIGH
.#define CONFIG_NET_TFTP_VARS 1
.#define CONFIG_USE_PRIVATE_LIBGCC 1
.#define CONFIG_USE_TINY_PRINTF 1
……(其中一段)
原来宏定义都在这里面了。那么这么多的宏定义是从哪里来的呢?
从我做的一部分验证来推断,从三个方面来:
1.configs/xxx_defconfig里面是不是定义了该宏定义
CONFIG_REGULATOR_PWM=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_RAM=y
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_BASE=0x20068000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART_SHIFT=2
2.Kconfig里面的config symbol 有没有定义该宏定义以及congfig下面的select、depends on、default关键字有没有选中,或者有没有依赖关系。
3.默认值,这点是猜想的,估计和kconfig的default(缺省)也是有一定的关系。就是如果没有定义的话,有的会默认成一个值或者一个状态。比如CONFIG_SPL和CONFIG_SUPPORT_SPL的值,当kconfig里面没有配置,去configs/xxx_defconfig里面配置,这时候是无效的。有部分宏定义在configs/xxx_defconfig里面配置就是无效的,不要问我为什么,因为我也不确定,我自己也是猜的,至于我猜的是什么原因,你猜呀。