CONFIG_KALLSYMS_ALL

内核配置

在2.6内核中,为了更好地调试内核,引入了kallsyms。kallsyms抽取了内核用到的所有函数地址(全局的、静态的)和非栈数据变量地址,生成一个数据块,作为只读数据链接进kernel image,相当于内核中存了一个System.map。
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)  --->
        (选中此项,才有/proc/kallsyms接口文件, oops问题,选中此选项即可,子选项可以忽略)
        [*]   Load all symbols for debugging/ksymoops 
              [*]   Include all symbols in kallsyms
              [*]   Do an extra kallsyms pass  

这样当系统出现oops的时候打印的信息就不是数字了,而是对应的符号信息。

Call Trace:
[] sys_delete_module+0x191/0x1ce
[] do_page_fault+0x189/0x51d
[] syscall_call+0x7/0xb


System.map与kallsyms

./scripts/kallsyms.c生成System.map
./scripts/kallsyms.c解析vmlinux(.tmp_vmlinux)生成kallsyms.S(.tmp_kallsyms.S),然后内核编译过程中将kallsyms.S(内核符号表)编入内核镜像uImage
内核启动后,kernel/kallsyms.c解析uImage形成/proc/kallsyms


/proc/kallsyms

cat /proc/kallsyms
000000000000a018 D per_cpu__xen_vcpu
000000000000a020 D per_cpu__xen_vcpu_info
000000000000a060 d per_cpu__mc_buffer
000000000000b570 D per_cpu__xen_mc_irq_flags
000000000000b578 D per_cpu__xen_cr3
000000000000b580 D per_cpu__xen_current_cr3
000000000000b5a0 d per_cpu__xen_runstate
000000000000b5e0 d per_cpu__xen_runstate_snapshot
000000000000b610 d per_cpu__xen_residual_stolen

第一列为符号地址,第二列为类型,第三列为符号名。如果发现符号地址均为0,那是因为系统保护。使用root权限查看即可。
第二列的类型:有的符号是大写的,有的是小写。大写的符号是全局的。
b 符号在未初始化数据区(BSS)
c 普通符号,是未初始化区域
d 符号在初始化数据区
g 符号针对小object,在初始化数据区
i 非直接引用其他符号的符号
n 调试符号
r 符号在只读数据区
s 符号针对小object,在未初始化数据区
t 符号在代码段
u 符号未定义

部分转自:旅途@KryptosX » linux内核符号表kallsyms简介


kallsyms_lookup_name

驱动代码中可以通过kallsyms_lookup_name寻找对应的symbol,如,

#ifdef CONFIG_KALLSYMS_ALL
        __boot_cpu_mode_sym = (void *)kallsyms_lookup_name("__boot_cpu_mode");
#else
        __boot_cpu_mode_sym = resolve_symbol("__boot_cpu_mode");
#endif

你可能感兴趣的:(linux驱动)