notify通知编程+export_symbols建立输出符号

本文深入探讨Linux内核中的Notify通知机制,介绍其工作原理和应用实例。通过五个步骤,详细讲解如何在驱动程序中实现Notify机制,包括初始化、注册、注销、实现call_chain函数及调用自定义函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:Linux内核中的notify通知机制,类似于QT中的事件通知机制,在需要的时刻发送信号,就会引发对应的处理函数执行。Linux内核中的notify提供了核心层,建立通信机制只需使用核心的接口函数实现。对于该机制的实现原理,编写驱动程序不需要过多分析,通过分析,最终这个机制执行过程最终涉及到内嵌汇编代码。

为驱动程序建立一个notify分五步进行:

1、初始化一个notify机制的头(HEAD)

2、实现自定义的注册函数,在函数中调用notify核心层提供的注册接口函数

3、实现自定义的注销函数,在函数中调用notify核心层提供的注销接口函数

4、实现自定义的call_chain函数,在函数中调用notify核心层提供的call_chain接口函数

5、在驱动代码中初始化一个notify项目,完成2、3、4步,在适当的地方调用自定义的call_chain函数

实现的一个例子:

1、exprot_symbols把notify对立为一个模块

#include <linux/notifier.h>
#include <linux/module.h>

static BLOCKING_NOTIFIER_HEAD(pyl_notify);

int pyl_register_notifier(struct notifier_block* nb){
	return blocking_notifier_chain_register(&pyl_notify,nb);
}
EXPORT_SYMBOL(pyl_register_notifier);

int pyl_unregister_notifier(struct notifier_block* nb){
	return blocking_notifier_chain_unregister(&pyl_notify,nb);
}
EXPORT_SYMBOL(pyl_unregister_notifier);

/*
	val:参数
	v:数据指针
*/
int pyl_notifier_call_chain(unsigned long val, void *v){
	return blocking_notifier_call_chain(&pyl_notify,val,v);
}
EXPORT_SYMBOL(pyl_notifier_call_chain);

MODULE_LICENSE("GPL");

2、调用export_symbols导出的函数符号,不过要在文件中声明一下。

#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/semaphore.h>
#include <linux/device.h>
#include <linux/kdev_t.h>

int pyl_register_notifier(struct notifier_block* nb);
int pyl_unregister_notifier(struct notifier_block* nb);
int pyl_notifier_call_chain(unsigned long val, void *v);

struct class* pyl_class;

typedef struct pyl2019{
	struct cdev* pyl_dev;
	dev_t  pyl_t;
	struct semaphore pyl_sem;//原子操作
}pyl_chrdev; 

pyl_chrdev* pyl_c=NULL;

static int for_pyl_notify_callBack(struct notifier_block *nb, unsigned long val, void *v){
	printk(KERN_INFO"\n i am a notifier \n");
	return 0;
}

static struct notifier_block pyl_notify={
	.notifier_call=for_pyl_notify_callBack,
};

int notify_open(struct inode *node, struct file *fil){
	pyl_notifier_call_chain(0,NULL);
	return 0;
}
int notify_release(struct inode *node, struct file *fil){
	int ret;
	ret=pyl_unregister_notifier(&pyl_notify);
	return ret;
}

static struct file_operations pyl_fops={
	.owner=THIS_MODULE,
	.open=notify_open,
	.release=notify_release,
};
	
static int __init pyl_init(void){
	int ret;
	pyl_c=(pyl_chrdev*)kmalloc(sizeof(pyl_chrdev),GFP_KERNEL);
	if(!pyl_c){
		goto kmalloc_err;
	}
	sema_init(&pyl_c->pyl_sem,1);
	ret=alloc_chrdev_region(&pyl_c->pyl_t,0,1,"pyl");
	pyl_c->pyl_dev = cdev_alloc();
	if(!pyl_c->pyl_dev){
		goto alloc_err;
	}
	cdev_init(pyl_c->pyl_dev,&pyl_fops);
	ret=cdev_add(pyl_c->pyl_dev,pyl_c->pyl_t, 1);
	if(ret<0){
		goto err;
	}
	pyl_class = class_create(THIS_MODULE, "pyl");
	device_create(pyl_class,NULL,MKDEV(pyl_c->pyl_t,0), NULL, "pyloooooo");
	printk(KERN_DEBUG"init OK \n");

	pyl_register_notifier(&pyl_notify);
	
	return 0;
err:
	cdev_del(pyl_c->pyl_dev);
alloc_err:
	unregister_chrdev_region(pyl_c->pyl_t,1);
	kfree(pyl_c);
kmalloc_err:
	return -1;
}

static void __exit pyl_exit(void){
	cdev_del(pyl_c->pyl_dev);
	unregister_chrdev_region(pyl_c->pyl_t,1);
	device_destroy(pyl_class,MKDEV(pyl_c->pyl_t,0));
	class_destroy(pyl_class);
	kfree(pyl_c);
}

MODULE_LICENSE("GPL");
module_init(pyl_init);
module_exit(pyl_exit);

上面的驱动代码的功能是,在初始化函数中注册一个通知链,在应用程序打开该设备驱动程序时,就发送notifier信号,执行call_chain回调函数。在1中可以看到有相关函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值