linux内核symbol_get,模块机制 – Linux内核API __symbol_get

__symbol_get函数功能描述:该函数的功能是根据给定的内核符号名symbol,获得该符号的内存地址,找到其所在的内核模块,并将该模块的引用计数加1。

__symbol_get文件包含

#include

__symbol_get函数定义

在内核源码中的位置:linux-3.19.3/kernel/module.c

函数定义格式:

void *__symbol_get(const char *symbol)

__symbol_get输入参数说明

symbol:字符串常量,代表内核符号名。

__symbol_get返回参数说明

返回一个void类型指针,其值代表内核符号symbol的地址。如果不存在内核符号symbol,则返回NULL。

__symbol_get实例解析

编写测试文件:__symbol_get.c

头文件及全局变量声明如下:

#include

#include

MODULE_LICENSE("GPL");

static int __init __symbol_get_init(void);

static void __exit __symbol_get_exit(void);

模块初始化函数:

int __init __symbol_get_init(void)

{

const char * symbol_name ;

void * addr;

symbol_name = "symbol_A"; //内核符号名为“symbol_A”

addr = __symbol_get( symbol_name );

if( addr ! = NULL )

printk("the address of %s is: %lx\n", symbol_name, (unsigned long)addr);

else

printk("%s isn't found\n", symbol_name);

symbol_name = "symbol_0"; //内核符号名为“symbol_0”

addr = __symbol_get( symbol_name );

if( addr ! = NULL )

printk("the address of %s is: %lx\n", symbol_name, (unsigned long)addr);

else

printk("%s isn't found\n", symbol_name);

return 0;

}

模块退出函数:

void __exit __symbol_get_exit(void)

{

printk("module exit ok! \n");

}

模块初始化及退出函数调用:

module_init(__symbol_get_init);

module_exit(__symbol_get_exit);

实例运行结果及分析:

在向内核中插入__symbol_get.ko模块之前,需要先将test_module.ko模块插入内核中,test_module.c文件参照find_symbol()函数一节。执行命令lsmod查看内核当前模块,结果如图所示。可以看到模块test_module已经在内核中,并且被使用6次。一个内核模块第一次被插入一般使用次数是0。

6f1bb623ed6e5bdf7295f34c5683109a.png

编译模块,执行命令insmod __symbol_get.ko插入模块,然后执行命令dmesg -c,会出现如图A所示的结果。

763c6eeaa1756d4aed05fddbdf8ac355.png

在向内核中插入__symbol_get.ko模块之后,再次执行命令lsmod查看内核当前模块,结果如图所示。可以看到模块__symbol_get模块已经在内核中,而此时test_module模块已被使用7次,增加了一次,在__symbol_get模块中有使用test_module模块中的symbol_A,所以次数增加。

e88bb0b5dc272df202266b2cbbb4320b.png

结果分析:

在Linux内核中,内核空间中的每一个函数的每一个变量都会有对应的符号,这部分符号也可称作内核符号,内核使用变量和函数的地址(指针)来访问对应的变量和函数。内核符号表提供了变量和函数符号名到地址的映射。

在测试程序中试图通过__symbol_get()函数获得内核符号“symbol_A”和“symbol_0”的内存地址,由图A显示的信息可知,内核符号“symbol_A”的内存地址为0xffffffffa0311000,而“symbol_0”则未找到相应的内存地址,这是因为它在内核符号表中不存在。

虚拟文件系统proc的kallsyms列出了对所有内核符号的相关描述,这里输出关于内核符号“symbol_A”和“symbol_0”的相关信息如图所示。

1eba4adf8f8e14c8bcbb0e0afe8a62fa.png

从上图中第五行可以看到在kallsyms文件中存在内核符号“symbol_A”,且其对应的内存地址为0xffffffffa0311000(第一列),与图A中输出结果一致。而未找到关于内核符号“symbol_0”的信息,说明该内核符号不存在,所以通过__symbol_get( )函数也找不到其内存地址,即addr = NULL。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值