linux内核通信

发布时间 2023-10-24 23:28:47作者: skyycj

符号导出

EXPORT_SYMBOL()
EXPORT_SYMBOL标签内定义的函数对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用。

2. 使用方法

加入B中调用A中导出函数

[1] 在模块A中c文件或者头文件中使用EXPORT_SYMBOL(xxxx) 导出函数.
有些需要添加编译选项 -DEXPORT_SYMTAB.

[2] 在模块B中用 "extern" 申明函数(如, extern int xxxx);
申明以后就能够直接使用导出的函数了。

另外:在导出函数以后,可以使用 cat proc/kallsyms来查看所有的导出符号,其中属性为t的标识是不能被调用的,所以如果导出符号是t类型,那么无法直接被其他模块使用。

通知链表简介

大多数内核子系统都是相互独立的,因此某个子系统可能对其它子系统产生的事件感兴趣。为了满足这个需求,也即是让某个子系统在发生某个事件时通知其它的子系统,Linux内核提供了通知链的机制。通知链表只能够在内核的子系统之间使用,而不能够在内核与用户空间之间进行事件的通知。
通知链表是一个函数链表,链表上的每一个节点都注册了一个函数。当某个事情发生时,链表上所有节点对应的函数就会被执行。所以对于通知链表来说有一个通知方与一个接收方。在通知这个事件时所运行的函数由被通知方决定,实际上也即是被通知方注册了某个函数,在发生某个事件时这些函数就得到执行。其实和系统调用signal的思想差不多。

2.通知链表数据结构

通知链表的节点类型为notifier_block,其定义如下:

struct notifier_block
{
int (*notifier_call)(struct notifier_block *self, unsigned long, void *);
struct notifier_block *next;
int priority;
};
其中最重要的就是notifier_call这个函数指针,表示了这个节点所对应的要运行的那个函数。next指向下一个节点,即当前事件发生时还要继续执行的那些节点。

5.示例

在这里,写了一个简单的通知链表的代码。

实际上,整个通知链的编写也就两个过程:
首先是定义自己的通知链的头节点,并将要执行的函数注册到自己的通知链中。
其次则是由另外的子系统来通知这个链,让其上面注册的函数运行。

我这里将第一个过程分成了两步来写,第一步是定义了头节点和一些自定义的注册函数(针对该头节点的),第二步则是使用自定义的注册函数注册了一些通知链节点。分别在代码buildchain.c与regchain.c中。
发送通知信息的代码为notify.c。

代码1 buildchain.c
它的作用是自定义一个通知链表test_chain,然后再自定义两个函数分别向这个通知链中加入或删除节点,最后再定义一个函数通知这个test_chain链。

中断处理通知:驱动可以使用通知链来注册中断处理程序,以便在中断事件发生时通知其他驱动。


系统重启通知:驱动可以使用通知链来注册系统重启事件,以便在系统重启时通知其他驱动,以便它们可以适当地响应。 总的来说,通知链是Linux内核中一个非常有用的机制,它可以帮助驱动开发人员在驱动之间建立有效的通信和协调,从而提高系统的可靠性和性能。