在内核中通过/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
/proc/kallsyms包含了内核中的函数符号(包括没有EXPORT_SYMBOL)、全局变量(用EXPORT_SYMBOL导出的全局变量)


将内核中的函数、全局变量、静态变量导出到/proc/kallsyms
---------------------------------------------------------------------------
./scripts/kallsyms

staticint all_symbols = 0;
==>
static intall_symbols = 1;

 

引入kallsyms
------------------------------------------------------------------------
在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


makemenuconfig
General setup --->  
   [*] Configure standard kernel features (for smallsystems)  --->
   [*]   Load allsymbols for debugging/ksymoops
  [*]    Include all symbols in kallsyms
  [*]    Do an extra kallsymspass  

配置CONFIG_KALLSYMS_ALL之后,就不需要修改all_symbol静态变量为1了

32bit addr  |--------------------|
                  |                    |
                  |                    |
                  ~                   ~
                  |                    |
                  |                    |
0xc05d 1dc0|--------------------| _end
                   |                        |
                   |                        |
                   |   BSS                |
                   |                        |
                   |                        |
0xc05a 4500|--------------------| __bss_start
                  |                    |
0xc05a 44e8|--------------------| _edata
                   |                        |
                   |                        |
                   |   DATA               |
                   |                        |
                   |                        |
0xc058 2000|--------------------| __data_start  init_thread_union
                  |                    | 
0xc058 1000|--------------------|  _etext  
                   |                        |
                   |rodata                |
                   |                        |
0xc056 d000|--------------------| __start_rodata
                  |                    |
                  |                    |
                  | Real text        |
                  |                    |
                  |                    |
0xc02a 6000|--------------------| _text        __init_end       TEXT  
                   |                        |
                   |Exit code and data | 这个section在内核完成初始化后
                   |                        |        会被释放掉
0xc002 30d4|--------------------| _einittext
                   |                        |
                   |Init code and data  |
                   |                        |
0xc000 8000|--------------------|<------------ __init_begin  _stext  
                 |                    |
0xc0000000|--------------------|

arch/arm/kernel/vmlinux.lds.S

 

kallsyms中間字母的意義 :

T  The symbol is in the text(code) section
D   The symbol is in theinitialized data section
R   The sysbol is in a read onlydata section
t   static
d   static
R   const
r   static const

 

注:
1. 文本段中的只读段均为变量
2. 文本段中的INIT断,可视为变量,因为命令中不会调用初始化函数,另外该区域在内核启动完成后,已经被bootmem释放了,所以该区域可能会被另作它用

 

 

64bit addr的例子

0000000000000000 Dirq_stack_union

0000000000000000 D__per_cpu_start

0000000000004000 Dgdt_page

0000000000005000 dexception_stacks

000000000000b000 dtlb_vector_offset

000000000000b080 Dxen_vcpu_info

000000000000b0c0 Dxen_vcpu

000000000000b0c8 didt_desc

000000000000b0d8 dxen_cr0_value

000000000000b0e0 Dxen_mc_irq_flags

000000000000b100 dmc_buffer

............

ffffffff81000000 Tstartup_64

ffffffff81000000 T_text

ffffffff810000b7 tident_complete

ffffffff81000100 Tsecondary_startup_64

ffffffff8100018a tbad_address

ffffffff81000190 T_stext

ffffffff81001000 Thypercall_page

ffffffff81002000 Tdo_one_initcall

ffffffff81002180 tdevt_from_partuuid

ffffffff81002260 tmatch_dev_by_uuid

ffffffff810022a0 Tname_to_dev_t

ffffffff81002570 Tpopulate_rootfs_wait

ffffffff81003000 tnative_read_cr4

ffffffff81003010 tnative_read_cr4_safe

ffffffff81003020 tnative_wbinvd

ffffffff81003030 tnative_read_msr_safe

ffffffff81003060 tnative_read_pmc

ffffffff81003080 tnative_store_gdt

ffffffff81003090 tnative_store_idt

ffffffff810030a0 txen_cpuid

.............

ffffffffa0001780 Tspi_print_msg [scsi_transport_spi]

ffffffffa0005560 d__this_module [scsi_transport_spi]

ffffffffa0000020 tspi_populate_sync_msg [scsi_transport_spi]

ffffffffa0003558 tcleanup_module [scsi_transport_spi]

ffffffffa0001cc0 Tspi_display_xfer_agreement [scsi_transport_spi]

ffffffffa0001470 Tspi_release_transport [scsi_transport_spi]

ffffffffa0000000 tspi_populate_width_msg [scsi_transport_spi]

ffffffffa00004d0 Tspi_schedule_dv_device [scsi_transport_spi]

ffffffffa0000050 tspi_populate_ppr_msg [scsi_transport_spi]

ffffffffa0003490 Tspi_attach_transport [scsi_transport_spi]

ffffffffa0001d20 Tspi_dv_device [scsi_transport_spi]

另外64位Linux系統只用了40位尋址空間

內存不足或內存中不活躍的數據 用到swap

虛擬地址空間:32位OS為每個進程都分配了一個4GB的虛擬地址空間

你可能感兴趣的:(在内核中通过/proc/kallsyms获得符号的地址)