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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章