Linux内核符号表

一,什么是符号(Symbols)?
    什么是Symbol?  其实就是kernel中的变量(Variable Name)或函数名称(Function Name)
    这样可以方便程序员在写程序时可以直接参照这一份Symbol的索引文件,找到所需要的kernel信息,这一份Symbol的索引文件又称为kernel symbol table。
    
二,内核符号表(Kernel Symbol Table)?

2.1)定义
内核符号表,就是在内核的内部函数或变量中,可供外部引用的函数和变量的符号表。
其实说白了就是一个索引文件,它存在的目的就是让外部软件可以知道kernel文件内部实际分配的位置。

2.2)所在文件
编译内核时,System.map文件用于存放内核符号表信息。
(System.map文件位于/或者/boot、/usr/src/linux/下)

2.3)文件的生成
符号表是所有内核符号及其对应地址的一个列表,随着每次内核的编译,就会产生一个新的对应System.map文件,当内核运行出错时,通过System.map中的符号表解析,就可以查到一个地址值对应的变量名。System.map文件记录了所有代码的运行地址(所有函数和变量)。
【内核并不使用符号名。它是通过变量或函数的地址(指针)来使用变量或函数的。其实内核连System.map文件都不使用,只是生成用于调试用的。】

2.4)system.map文件的格式

   线性地址           类型        符号
ffffffff81002590       t        create_dev
ffffffff81009c00       T       show_regs

其中,类型 若是小写字母则表示局部引用, 若是大写字母则表示全局引用(外部). 

2.5)内核符号表的存在意义
1)把内核的符号地址,转化为程序猿可以看懂的符号名称
内核符号表就是为程序员通过符号来访问程序体的对应地址(指针),建立了一个动态的,可变更的映射表格。
例如:
内核不会使用符号名create_dev,而会使用ffffffff81002590来引用这个变量。但程序猿们更喜欢符号名create_dev这样直观的名字。
所以就需要这么一个对应关系表。这个类似于网络里的DNS,没有谁愿意去记那没规律的IP地址,而记个网址就好记多了。

2)转换之后,就可以更方便的调试内核代码
对于系统的oop消息、或者通过gdb的调试消息,都需要根据该对照表,将内核熟悉的函数地址转化为用户熟悉的函数名称,便于用户进行故障定位、运行监控。
而内核本身并不真正使用System.map,而只是用于做调试用。


2.6)内核符号表存储位置

2.6.1) System.map

磁盘中真实存在的文件,存储内核中静态编译的函数和变量地址,每个新编译内核对应一个System.map文件,当klogd输出内核消息时,会通过/boot/System.map来将函数、变量地址转换为名称,方便用户理解。该文件对应不同的编译内核有对应的实现文件。

2.6.2 )/proc/kallsyms
内核启动时候创建,供oops时定位错误,文件大小总为0,包含当前内核导出的、可供使用的变量或者函数;它只是内核数据的简单表示形式。

2.7)System.map 和 /proc/kallsyms 区别

二者相似点:

都是内核函数、变量的符号表,结构一致;对于可导出的内核变量、函数,其运行时在物理内存中的位置是一样的。


二者区别
两者侧重点不同,
(1)System.map文件面向内核,对于内核中的没有导出的变量或者函数名,比如kthread_create_list链表头指针,也有其相应的内核地址,该文件一般是只读的、固定大小的,没有动态添加模块中的变量、函数名
(2)而kallsyms在内核启动过程中创建,并实时更新,反映的是系统的当前最新情况,其内部也包含内核或者是已加载模块导出的函数、变量名称。
所以和System.map文件有差别,kallsyms文件动态变化,大小不固定。

总结就是:
System.map文件较单纯,是在用户一开始编译就产生的固定文件,不会因为任何原因更改,除非被换掉。
/proc/kallsyms是一个在启动时由Linux kernel实时产生的文件当系统有任何变更时,它就会马上做出修正
因为这是动态的信息,当用户新增或删除一个module,都会自动做实时的修正(/proc下的都是这一类型的文件)
       
2.8)分类
Linux内核的符号表位于两个部分。
2.8.1)首先是内核的静态部分,也就是内核文件映像vmlinuz部分的符号表,对应于/proc/kallsyms和System.map这两个文件。
2.8.2)还有一部分则是Linux可配置模块部分的符号表。

2.9)形成过程

  Linux内核符号表/proc/kallsyms的形成过程

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

要在一个内核中启用 kallsyms 功能,必须用进行内核配置,make menuconfig设置 CONFIG_KALLSYMS 选项为y; 如果你要在 kallsyms 中包含全部符号信息,必须设置 CONFIG_KALLSYMS_ALL 为y。


三,导出符号表
驱动程序中,如果该驱动程序中有被其他内核代码调用的部分,可以用EXPORT_SYMBOL导出到内核符号表中。

附:
内核符号表类型

符号类型

名称

说明

A

Absolute

符号的值是绝对值,并且在进一步链接过程中不会被改变

B

BSS

符号在未初始化数据区或区(section)中,即在BSS段中

C

Common

符号是公共的。公共符号是未初始化的数据。在链接时,多个公共符号可能具有同一名称。如果该符号定义在其他地方,则公共符号被看作是未定义的引用

D

Data

符号在已初始化数据区中

G

Global

符号是在小对象已初始化数据区中的符号。某些目标文件的格式允许对小数据对象(例如一个全局整型变量)可进行更有效的访问

I

Inderect

符号是对另一个符号的间接引用

N

Debugging

符号是一个调试符号

R

Read only

符号在一个只读数据区中

S

Small

符号是小对象未初始化数据区中的符号

T

Text

符号是代码区中的符号

U

Undefined

符号是外部的,并且其值为0(未定义)

-

Stabs

符号是a.out目标文件中的一个stab符号,用于保存调试信息

?

Unknown

符号的类型未知,或者与具体文件格式有关


  
   

参考网址:
http://www.blogbus.com/wanderer-zjhit-logs/172382425.html
http://www.360doc.com/content/14/0218/09/2613145_353425431.shtml
http://blog.chinaunix.net/uid-24148050-id-95497.html
http://book.51cto.com/art/200903/117056.htm
  • 10
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
买书时赠送的电子稿,代码示例丰富,非常不错!全书分三个文件打包。 linuxdriver_code_tool |-- 03 | `-- 2.6内核升级工具 | |-- device-mapper-1.00.19-2.i386.rpm | |-- lvm2-2.00.25-1.01.i386.rpm | |-- mkinitrd-4.2.0.3.tar.tar | |-- module-init-tools-3.2.2.tar.bz2 | `-- modutils-2.4.5-1.src.rpm |-- 04 | |-- 内核模块参数范例 | | `-- book.c | |-- 内核模块导出符号 | | `-- export_symb.c | `-- 最简单的内核模块 | `-- hello.c |-- 05 | `-- udev源代码 | `-- udev-114.tar.gz |-- 06 | |-- globalmem驱动 | | `-- globalmem.c | `-- 包含2个globalmem设备的驱动 | `-- globalmem_two.c |-- 07 | `-- 含并发控制的globalmem驱动 | `-- globalmem_lock.c |-- 08 | |-- globalfifo驱动 | | `-- globalfifo.c | `-- poll应用程序范例 | `-- pollmonitor.c |-- 09 | |-- 异步通知应用程序范例 | | `-- asyncmonitor.c | `-- 支持异步通知的globalfifo | `-- globalfifo_async.c |-- 10 | |-- S3C2410实时钟驱动 | | `-- s3c2410-rtc.c | `-- 秒设备驱动与应用程序 | |-- second.c | `-- second_test.c |-- 11 | |-- DMA范例 | | |-- 3c505.c | | |-- 3c505.h | | `-- dma.h | `-- 静态映射范例 | `-- mach-smdk2440.c |-- 12 | |-- NVRAM驱动 | | `-- generic_nvram.c | |-- 触摸屏驱动 | | |-- 作为input设备 | | | |-- s3c2410_ts.c | | | `-- s3c2410_ts.h | | `-- 作为普通字符设备 | | `-- s3c2410-ts.c | |-- 看门狗驱动 | | `-- s3c2410_wdt.c | `-- 平台设备 | `-- devs.c |-- 13 | |-- IDE驱动 | | |-- ide-disk.c | | `-- ide-h8300.c | `-- RAMDISK驱动 | `-- rd.c |-- 14 | |-- S3C2410串口驱动 | | |-- regs-gpio.h | | |-- regs-serial.h | | `-- s3c2410.c | `-- 串口核心层 | |-- serial_core.c | `-- serial_core.h |-- 15 | |-- S3C2410 I2C主机驱动 | | |-- i2c-s3c2410.c | | |-- iic.h | | |-- regs-gpio.h | | `-- regs-iic.h | `-- SAA711x I2C设备驱动 | `-- saa711x.c |-- 16 | `-- CS8900以太网设备驱动 | |-- cs89x0.c | `-- cs89x0.h |-- 17 | |-- ALSA工具及库 | | |-- alsa-driver-1.0.15.tar.bz2 | | |-- alsa-firmware-1.0.15.tar.bz2 | | |-- alsa-lib-1.0.15.tar.bz2 | | |--

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值