1. 程式人生 > >Linux驅動之匯出符號表

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檔案參考相關博文!