内核符号表是表示公共的访问的函数和变量。类似于应用程序的全局函数和全局变量。
模块被装入内核后,他所导出的任何符号都会变成内核符号表的一部分。可以通过/proc/kallsyms查看。
内核中常常使用模块的层叠,如每个usb输入设备模块都层叠在usbcore和input模块上。
为了避免命令空间的污染,需要用宏导出模块符号:
EXPORT_SYMBOL(name);
EXPORT_SYMBOL_GPL(name);
比如下面的例子,编写两个模块,aaa.ko bbb.ko .aaa需要访问bbb中的导出函数
//aaa.c #include <linux/init.h> #include <linux/module.h> #include "bbb.h" extern int glob_num; MODULE_LICENSE("GPL"); static __init int aaa(void) { led_on(); printk("glob = %d\n", glob_num); return 0; } static __exit void bbb(void) { led_off(); } module_init(aaa); module_exit(bbb);
//bbb.c #include <linux/module.h> #include "bbb.h" MODULE_LICENSE("GPL"); int glob_num = 123; EXPORT_SYMBOL(glob_num); void led_on(void) { printk("%s %d\n", __func__, __LINE__); } EXPORT_SYMBOL(led_on); void led_off(void) { printk("%s %d\n", __func__, __LINE__); } EXPORT_SYMBOL(led_off);
#ifndef _BBB_H_ //bbb.h #define _BBB_H_ void led_on(void); void led_off(void); #endif // _BBB_H_
#makefile obj-m = aaa.o bbb.o #KERN = /share/arm/linux-3.2 KERN = /lib/modules/`uname -r`/build/ all: make -C $(KERN) M=`pwd` modules clean: make -C $(KERN) M=`pwd` modules clean rm -rf modules.order
以上例子make后生成aaa.ko 与bbb.ko两个模块,由于aaa.ko需要调用bbb.ko符号和变量,所以必须先装载bbb.ko,才能装载aaa.ko
符号导入全局符号表都是使用上面的方式。