1、形成过程
Linux内核符号表/proc/kallsyms的形成过程
./scripts/kallsyms.c负责生成System.map
./kernel/kallsyms.c负责生成/proc/kallsyms
./scripts/kallsyms.c解析vmlinux(.tmp_vmlinux)生成kallsyms.S(.tmp_kallsyms.S),然后内核编译过程中将kallsyms.S(内核符号表)编入内核镜像uImage
内核启动后./kernel/kallsyms.c解析uImage形成/proc/kallsyms
2、内核配置
在2.6内核中,为了更好地调试内核,引入了kallsyms。kallsyms抽取了内核用到的所有函数地址(全局的、静态的)和非栈数据变量地址,生成一个数据块,作为只读数据链接进kernel image,相当于内核中存了一个System.map。需要配置CONFIG_KALLSYMS
.config
CONFIG_KALLSYMS=y 符号表中包含所有的函数
CONFIG_KALLSYMS_ALL=y 符号表中包括所有的变量(包括没有用EXPORT_SYMBOL导出的变量)
CONFIG_KALLSYMS_EXTRA_PASS=y
make menuconfig
General setup --->
[*] Configure standard kernel features (for small systems) --->
[*] Load all symbols for debugging/ksymoops (选中此项,才有/proc/kallsyms接口文件, oops问题,选中此选项即可,子选项可以忽略)
[*] Include all symbols in kallsyms
[*] Do an extra kallsyms pass
3、作用
在2.6版的内核中,为了更方便的调试内核代码,开发者考虑将内核代码中所有函数以及所有非栈变量的地址抽取出来,形成是一个简单的数据块(data blob:符号和地址对应),并将此链接进 vmlinux 中去。如此,在需要的时候,内核就可以将符号地址信息以及符号名称都显示出来,方便开发者对内核代码的调试。完成这一地址抽取+数据快组织封装功能的相关子系统就称之为 kallsyms。反之,如果没有 kallsyms 的帮助,内核只能将十六进制的符号地址呈现给外界,因为它能理解的只有符号地址,而并不包括人类可读的符号名称。
经常使用 Windows 的人都知道所谓的蓝屏是怎么回事,那是系统出了致命问题,而不能继续运行下去而show出的一个蓝色屏。那么对 Linux 来说,也会有致命错误的出现,如果这种错误使得Linux不可继续运行,那么Linux就会显示类似下面这样的屏幕内容(以运行在PowerPC架构下的Linux来举例,其他架构也差不多)以dump出出现错误那时刻的系统状态。这种现象就是所谓的Oops,也就Linux下的蓝屏。
上面出现的Oops消息中,显示了出错时的CPU各寄存器的值,以及以 "Call trace:" 一行开始的C函数调用栈。注意其中除了显示在中括号内的地址,还显示了函数的名称,这就是受助于 kallsyms 的结果,否则它只能显示地址信息。要在一个内核中启用 kallsyms 功能,你必须设置 CONFIG_KALLSYMS 选项为y;如果你要在 kallsyms 中包含全部符号信息,必须设置 CONFIG_KALLSYMS_ALL 为y。