Linux驱动之导出符号表

Linux 2.6的“/proc/kallsyms”文件对应着内核符号表,它记录了符号以及符号所在的内存地址。

模块可以使用如下宏导出符号到内核符号表:

EXPORT_SYMBOL(符号名);

EXPORT_SYMBOL_GPL(符号名);

Module.symvers 存储了导出符号的信息

头文件

symbol.h源码:

#ifndef __SYMBOL_HEAD_H
#define __SYMBOL_HEAD_H

struct object {
	int val;
	int (*func)(void);
};


#endif

测试源码:

export.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include "../symbol.h"

MODULE_LICENSE("GPL");

int show(void)
{
	printk("show()...");
	return 0;
}

struct object obj = {
	.val = 100,
	.func = show,
};

EXPORT_SYMBOL_GPL(obj);

static int __init demo_init(void)
{
	printk("%s,%d\n", __func__, __LINE__);

	return 0;
}

static void __exit demo_exit(void)
{
	printk("%s,%d\n", __func__, __LINE__);
}

module_init(demo_init);
module_exit(demo_exit);

 1、先编译export.c ,生成符号表Module.symvers 拷贝到 used目录,再编译used.c

used.c源码:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include "../symbol.h"

MODULE_LICENSE("GPL");

extern struct object obj;

static int __init demo_init(void)
{
	printk("%s,%d\n", __func__, __LINE__);
	printk("val:%d\n", obj.val);

	obj.func();

	return 0;
}

static void __exit demo_exit(void)
{
	printk("%s,%d\n", __func__, __LINE__);
}

module_init(demo_init);
module_exit(demo_exit);

2、先加载 export.ko , 再加载 used.ko

3、先卸载 used, 再卸载 export

cat /proc/kallsyms | grep " o" // 查看符号表

相应的Makefile文件参考相关博文!

猜你喜欢

转载自blog.csdn.net/zxy131072/article/details/85223510