Linux驱动学习(一)--符号表
什么是符号表
- 主要指的是全局变量和函数
- Linux内核采用的是以模块化形式管理内核代码。内核中 的每个模块相互之间是相互独立的,也就是说A模块的全 局变量和函数,B模块是无法访问的
符号表位置
- Ubuntu Linux内核的全局符号表在:
/usr/src/linux-headers-xxxxx-generic/Module.symve
xxxxx表示内核版本,可以用命令uname -r查看
Module.symvers内容:
- 单独编译的内核的符号表在:
根目录下
符号表使用步骤
- 编译模块A,然后加载模块A,在模块A编译好后,在它的 当前目录会看到一个Module.symvers文件,这里存放的就是我们模块A导出的符号
- 将模块A编译生成的Module.symvers文件拷贝到模块B目录下,然后编译B模块
- 先加载A模块然后加载模块B
- 通过dmesg查看模块打印的信息
注意:加载的时候,必须先加载a模块,再加载b模块;卸载的时候,必须先卸载b模块,再卸载a模块
代码
helloa.c
/*
*healla.c
*Original Author: luoyunheng, 2024-02-17
*
*test of export out symbol
*
*/
#include<linux/init.h>
#include<linux/module.h>
MODULE_LICENSE("GPL");
static int a = 1314;
static void show(void)
{
printk("happy every day...a = %d\n", a);
}
static int helloa_init(void)
{
printk("helloa_init\n");
return 0;
}
static void helloa_exit(void)
{
printk("helloa_exit\n");
}
EXPORT_SYMBOL(a);
EXPORT_SYMBOL(show);
module_init(helloa_init);
module_exit(helloa_exit);
hellob.c
/*
*hellob.c
*Original Author: luoyunheng, 2025-01-28
*
* test of export out of symbol
*/
#include<linux/init.h>
#include<linux/module.h>
MODULE_LICENSE("GPL");
extern int a;
extern void show(void);
static int hellob_init(void)
{
printk("hellob_init, a=%d\n", a);
show();
return 0;
}
static void hellob_exit(void)
{
printk("hellob_exit\n");
return;
}
注意:在内核模块代码中,函数参数为空必须加上void,否则编译不过
makefile:
ifneq ($(KERNELRELEASE),)
obj-m:=hellob.o
else
KDIR :=/lib/modules/$(shell uname -r)/build
PWD :=$(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -f *.ko *.o *.mod.o *.symvers *.cmd *.mod.c *.order
endif
运行:
关于static
在内核模块中,将全局变量和符号表导出到Modules.symvers文件后,其它模块可访问;这区别于我们熟知的static只可在文件内部访问