CONFIG_IKCONFIGCONFIG_IKCONFIG_PROC这种选项出现在“Generalsetup(通常设置)”菜单中,会让完整的内核配置状态包含到内核中,并可通过/proc访问。大多数内核开发者清楚地晓得自己所使用的配置,因而并不须要这两个选项(会促使内核变大)。但是,假若读者要调试的内核是由其他人构建的,则上述选项会比较有用。
首先这两个配置的坐落(init/Kconfig):
Generalsetup-->Kernel.configsupport(对应CONFIG_IKCONFIG)[*]Enableaccessto.configthrough/proc/config.gz(对应CONFIG_IKCONFIG_PROC)
假如要内核保存内核的配置,必须先选择Kernel.configsupport,这个选项作用是让内核在编译的时侯将.config文件做gz压缩后将其转换为一个放置于只读数据段的大字符字段“staticconstcharkernel_config_data”中最后通过config.o联接进内核。
若果在这个基础上选择了“[*]Enableaccessto.configthrough/proc/config.gz”就在保持内核配置到链表的基础上,提供一个用户空间读取这个字段的procfs文件插口。实现这个功能的是由内核的kernel/Makefile和kernel/configs.c共同完成的。下边详尽解析一下:
首先我们看一下kernel/Makefile有关部份:
......obj-$(CONFIG_IKCONFIG)+=configs.o-------------------------------------(1)......$(obj)/configs.o:$(obj)/config_data.h----------------------------------(2)#config_data.hcontainsthesameinformationasikconfig.hbutgzipped.#Infofromconfig_datacanbeextractedfrom/proc/config*targets+=config_data.gz$(obj)/config_data.gz:$(KCONFIG_CONFIG)FORCE--------------------------(4)$(callif_changed,gzip)quiet_cmd_ikconfiggz=IKCFG$@cmd_ikconfiggz=(echo"staticconstcharkernel_config_data[]__used=MAGIC_START";cat$$@----------------------------------(5)targets+=config_data.h$(obj)/config_data.h:$(obj)/config_data.gzFORCE-----------------------(3)$(callif_changed,ikconfiggz)
(1)假如配置了CONFIG_IKCONFIG就要生产configs.o文件
(2)configs.o文件依赖$(obj)/config_data.h文件,蕴涵的生成条件是通过configs.c文件编译生成。而在configs.c文件中包含了$(obj)/config_data.h文件。
(3)$(obj)/config_data.h文件的生成依赖$(obj)/config_data.gz,并强制每次编译都重新生成$(obj)/config_data.h文件(FORCE)。这个文件的生成规则是(5)
(4)$(obj)/config_data.gz文件的生成依赖$(KCONFIG_CONFIG)(也就是内核配置文件.config),并强制每次编译都重新生成$(obj)/config_data.gz(FORCE)。这个文件的生成是通过将.config执行gzip压缩生成的。
(5)这儿虽然就是执行一个shell指令,将$(obj)/config_data.gz文件中的数据通过内核工具程序scripts/bin2c装入一个名为“kernel_config_data”的字符链表中,并以MAGIC_START(宏:"IKCFG_ST")开头,MAGIC_END(宏:"IKCFG_ED")结尾。
最后这个configs.o文件会被联接进内核,假如你的内核中配置了CONFIG_KALLSYMS,这么你就可以在/proc/kallsyms中见到“kernel_config_data”这个符号。
假如你配置了CONFIG_IKCONFIG_PROC,这么configs.c中的procfs文件系统插口模块都会被编译进去,虽然就是实现了对这个字符链表的读取和定位的功能。
里面的生产过程介绍完了,如今用一个图来总结一下过程:
里面介绍了内核映像中内核配合信息的生成linux 内核配置文件,接出来就看要怎么获取了。从里面的介绍中虽然不能看出获取的方式有两种:
1、在运行时通过/proc/config.gz获取:
在控制台输入命令:cat/proc/config.gz|gzip-d>(你要保存配置的文件名)
这个方式简单,而且也有他的局限性,首先必须配置CONFIG_IKCONFIG_PROC,其次必须在系统运行时进行获取。
2、可以直接通过编译好的内核映像:vmlinux、zImage、uImage等直接获取
这个方式虽然也十分简单linux主机,内核黑客们早已帮我们做好了提取工具了:scripts/extract-ikconfig。使用上去超简单:
(假如是交叉编译linux培训学校,那就在宿主机)输入如下命令:(内核源码路径)scripts/extract-ikconfig(内核映像路径)>(你要保存配置的文件名)
这个工具对于gz压缩方法是支持一贯不错,从2.6.37开始支持bzip2、lzma和lzo压缩方法linux 内核配置文件,从2.6.39开始支持xz压缩方法。这种从内核的gitlog中可以看出。
3、从内核逻辑地址空间提取:
从里面的的生成介绍中我们可以晓得,配置文件的压缩文件或许就在内核映像的只读数据段中。假如内核在运行的时侯,虽然数据在内核逻辑地址空间中可以找到。方式概况如下:
(1)通过/proc/kallsyms找到“kernel_config_data”这个符号对应的内核逻辑地址
(2)通过/dev/kmem和前面得到的逻辑地址获取数据。压缩文件数据就在:"IKCFG_ST"与"IKCFG_ED"之间。
这个步骤须要自己写一小段的C代码,可以参考devkmem的代码(《对于驱动调试有用的两个小工具(devmem2、devkmem)》)