为什么要在内核中调用模块的函数?
linux解决方案提供商在发布代码时,可能希望将某些核心代码以二进制(对于内核,就是ko文件)的模块发布,然后在内核中调用模块的函数,以保护其知识产权。
模块调用内核的函数是很容易的,在内核EXPORT_SYMBOL函数,并包含相关的头文件,直接调用即可。但反过来,在内核中调用模块的函数则不太容易。即使包含相关头文件,编译通过了,但是在链接的时候还是不能通过。
比如我们想在dev.c中调用nf_conntrack_core.c的函数,nf_conntrack_core.c是以模块的方式编译的。
解决办法是使用hook。
不直接调用模块的函数,在内核中定义一个hook和绑定函数,在模块加载时绑定hook到想调用的函数,模块卸载时将hook置为NULL。上述过程在模块中调用内核的函数,所以链接不会有问题。
内核中想调用模块的函数,如果hook为NULL,那么模块没有加载进来,直接跳过去。
示例代码如下:
-----kernel-----
extern void blog_bind(BlogHook_t rx_hook, BlogHook_t tx_hook,
BlogStop_t stop_hook);
typedef void (* BlogCTHook_t)(void);
extern void blogCt_bind(BlogCTHook_t blog_ct);
void blogCt_bind(BlogCTHook_t blog_ct)
{
blog_ctdump_hook_g = blog_ct;
}
EXPORT_SYMBOL(blog_bind); //不能少
-----module-----
void blog_conntrack_dump(void)
{
printk("moule function is called/n");
}
static int hello_init(void)
{
blog_bind(blog_conntrack_dump);
return 0;
}
static void hello_exit(void)
{
blog_bind((BlogCTHook_t)NULL);
printk("Goodbye!/n");
}
-----调用------
int blog_init(struct sk_buff* skb)
{
if(!blog_ctdump_hook_g)
return -1;
....
blog_ctdump_hook_g();
}