Linux 2.6系统的"/proc/kallsyms"文件对应着内核符号表,它记录了符号以及符号所在的内存地址。
模块可以使用如下宏导出符号到内核符号表:
EXPORT_SYMBOL(符号名);
EXPORT_SYMBOL_GPL(符号名); //只适用于包含GPL许可权的模块;
符号必须在模块文件的全局部分导出,不能在函数中导出,这是因为上述这两个宏将被扩展成一个特殊用途的声明,而该变量必须是全局的。
使用方法:
1.在模块函数或符号定义后使用EXPORT_SYMOL_GPL(符号名);
2.在调用的模块中使用extern声明与之对应;
3.必须保证被调用的符号所在模块已被加载;
举例说明下,比如我们要使用driver/char/pwm.c中的变量pwm_dev及函数pwm_set_duty_cycle(),如下所示:
struct pwm_dev pwm_dev = {
.id = 11,
.mux_offset = GPT11_MUX_OFFSET,
};
EXPORT_SYMBOL_GPL(pwm_dev);
int pwm_set_duty_cycle(struct pwm_dev *pd, u32 duty_cycle)
{
u32 new_tmar;
if (duty_cycle > 100)
return -EINVAL;
if (duty_cycle == 0) {
pwm_off(pd);
return 0;
}
new_tmar = (duty_cycle * pd->num_settings) / 100;
if (new_tmar < 1)
new_tmar = 1;
else if (new_tmar > pd->num_settings)
new_tmar = pd->num_settings;
pd->tmar = pd->tldr + new_tmar;
pwm_on(pd);
pd->current_val = duty_cycle;
return 0;
}
EXPORT_SYMBOL_GPL(pwm_set_duty_cycle);
如果我们在板级文件board-am3517evm.c中调用该函数,需要先声明再调用:
extern struct pwm_dev pwm_dev;
........
.......
.......
pwm_set_duty_cycle(&pwm_dev,0);