形成过程---------------------------------------------------------------------------
./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 static
int all_symbols = 0;==>static int
all_symbols = 1;
引入kallsyms------------------------------------------------------------------------在2.6内核中,为了更好地调试内核,引入了kallsyms。kallsyms抽取了内核用到的所有函数地址(全局的、静态的)和非栈数据变量地址,生成一个数据块,作为只读数据链接进kernel image,相当于内核中存了一个System.map。需要配置CONFIG_KALLSYMS.configCONFIG_KALLSYMS=yCONFIG_KALLSYMS_ALL=y
符号表中包括所有的变量(包括没有用EXPORT_SYMBOL导出的变量)CONFIG_KALLSYMS_EXTRA_PASS=y make
menuconfigGeneral setup --->[*] Configure standard kernel features (for small
systems) --->[*] Load all
symbols for debugging/ksymoops[*] Include all symbols in kallsyms[*] Do an extra kallsyms
pass
配置CONFIG_KALLSYMS_ALL之后,就不需要修改all_symbol静态变量为1了
32bit addr
|--------------------|| || |~ ~| || |0xc05d 1dc0|--------------------|_end|
||
|| BSS ||
||
|0xc05a 4500|--------------------|__bss_start| |0xc05a 44e8|--------------------|_edata|
||
|| DATA ||
||
|0xc058 2000|--------------------|__data_startinit_thread_union| |0xc058 1000|--------------------|_etext|
||
rodata ||
|0xc056 d000|--------------------|__start_rodata| || || Real text || || |0xc02a 6000|--------------------|_text__init_endTEXT|
||
Exit code and data |这个section在内核完成初始化后|
|
会被释放掉0xc002 30d4|--------------------|_einittext|
||
Init code and data ||
|0xc000 8000|--------------------|
|0xc000
0000|--------------------|
arch/arm/kernel/vmlinux.lds.S
kallsyms中間字母的意義:
T The symbol is in the text(code) section
D The symbol is in the
initialized data section
R The sysbol is in a read only
data section
t static
d static
R const
r static const
注:
1. 文本段中的只读段均为变量2. 文本段中的INIT断,可视为变量,因为命令中不会调用初始化函数,另外该区域在内核启动完成后,已经被bootmem释放了,所以该区域可能会被另作它用
64bit addr
的例子
0000000000000000 D
irq_stack_union
0000000000000000 D
__per_cpu_start
0000000000004000 D
gdt_page
0000000000005000 d
exception_stacks
000000000000b000 d
tlb_vector_offset
000000000000b080 D
xen_vcpu_info
000000000000b0c0 D
xen_vcpu
000000000000b0c8 d
idt_desc
000000000000b0d8 d
xen_cr0_value
000000000000b0e0 D
xen_mc_irq_flags
000000000000b100 d
mc_buffer
............
ffffffff81000000 T
startup_64
ffffffff81000000 T
_text
ffffffff810000b7 t
ident_complete
ffffffff81000100 T
secondary_startup_64
ffffffff8100018a t
bad_address
ffffffff81000190 T
_stext
ffffffff81001000 T
hypercall_page
ffffffff81002000 T
do_one_initcall
ffffffff81002180 t
devt_from_partuuid
ffffffff81002260 t
match_dev_by_uuid
ffffffff810022a0 T
name_to_dev_t
ffffffff81002570 T
populate_rootfs_wait
ffffffff81003000 t
native_read_cr4
ffffffff81003010 t
native_read_cr4_safe
ffffffff81003020 t
native_wbinvd
ffffffff81003030 t
native_read_msr_safe
ffffffff81003060 t
native_read_pmc
ffffffff81003080 t
native_store_gdt
ffffffff81003090 t
native_store_idt
ffffffff810030a0 t
xen_cpuid
.............
ffffffffa0001780 T
spi_print_msg [scsi_transport_spi]
ffffffffa0005560 d
__this_module [scsi_transport_spi]
ffffffffa0000020 t
spi_populate_sync_msg [scsi_transport_spi]
ffffffffa0003558 t
cleanup_module [scsi_transport_spi]
ffffffffa0001cc0 T
spi_display_xfer_agreement [scsi_transport_spi]
ffffffffa0001470 T
spi_release_transport [scsi_transport_spi]
ffffffffa0000000 t
spi_populate_width_msg [scsi_transport_spi]
ffffffffa00004d0 T
spi_schedule_dv_device [scsi_transport_spi]
ffffffffa0000050 t
spi_populate_ppr_msg [scsi_transport_spi]
ffffffffa0003490 T
spi_attach_transport [scsi_transport_spi]
ffffffffa0001d20 T
spi_dv_device [scsi_transport_spi]
另外64位Linux系統只用了40位尋址空間
內存不足或內存中不活躍的數據 用到swap
虛擬地址空間:32位OS為每個進程都分配了一個4GB的虛擬地址空間