内核符号表是表示公共的访问的函数和变量。类似于应用程序的全局函数和全局变量。
模块被装入内核后,他所导出的任何符号都会变成内核符号表的一部分。可以通过/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
符号导入全局符号表都是使用上面的方式。