Linux下的uevent

本文解析了Linux中uevent节点的实现机制,通过深入研究device_add函数和 uevent操作,展示了如何在设备创建时自定义信息发送,以及power_supply_changed_work和kobject_uevent如何通过netlink广播传递状态变化。同时,探讨了sysfs中的kset和ktype示例,包括自定义属性和sysfs操作,以及应用层如何监听这些uevent消息。

查找linux的uevent节点(find /sys -name uevent),大概有1000多个,那这些节点是怎么实现的呢。

 

 drivers/base/core.c

有如下代码,每创建一个device,都会创建一个event节点

static ssize_t uevent_show(struct device *dev, struct device_attribute *attr,char *buf)
{
	...
	retval = kset->uevent_ops->uevent(kset, &dev->kobj, env);
	...	
}

static ssize_t uevent_store(struct device *dev, struct device_attribute *attr,const char *buf, size_t count)
{
	
}
static DEVICE_ATTR_RW(uevent);

int device_add(struct device *dev)
{
	...
	device_create_file(dev, &dev_attr_uevent);
	...
}

来个demo看下

#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>

static struct class *demo_class;
static struct cdev demo_cdev;
dev_t demo_number = 0;
int demo_open (struct inode *inode, struct file *filp)
{
    return 0;
}

static  struct file_operations demo_nod_fops =
{
    .owner = THIS_MODULE,
    .open  = demo_open,
};

int demo_uevent(struct device *dev, struct kobj_uevent_env *env)
{
	int ret = 0;
	char *p="aaa";
	char *q="bbb";

	ret = add_uevent_var(env, "demo_NAME=%s",p);
	ret = add_uevent_var(env, "demo_NAME=%s",q);

	return ret;
}

static int __init example_init(void)
{
    	int ret;

	demo_number=MKDEV(0,0);
	ret=alloc_chrdev_region(&demo_number,0,1,"6");
	if(ret<0)
	{
		printk("alloc chardev region err\n");
	 	return ret;
	}
	cdev_init(&demo_cdev,&demo_nod_fops);
	demo_cdev.owner=THIS_MODULE;
	ret=cdev_add(&demo_cdev,demo_number,1);
	if(ret<0)
	{
		printk("add demo cdev err!\n");
		return ret;
	}
	demo_class=class_create(THIS_MODULE,"demo");
	if(IS_ERR(demo_class))
	{
		printk("create demo class err!\n");
		return -1;
	}
	device_create(demo_class,NULL,demo_number,NULL,"66"); 
	demo_class->dev_uevent = demo_uevent;
	return 0;
}

static void __exit example_exit(void)
{
	cdev_del(&demo_cdev);
	device_destroy(demo_class,demo_number);
	unregister_chrdev_region(demo_number, 1);
   	class_destroy(demo_class);
}

module_init(example_init);
module_exit(example_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Greg 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值