Linux驅動之匯出符號表
阿新 • • 發佈:2019-01-13
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檔案參考相關博文!