内核设备模型之为kobject添加属性文件

本文介绍Linux内核中kobject模型的属性文件操作方法,包括如何创建、读取及写入属性文件,并通过示例代码展示了具体实现过程。

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

内核设备模型之为kobject添加属性文件

//为内核对象添加属性文件
//如何通过文件系统配置内核空间的kobject的属性
//对属性文件操作 
struct kobj_type    *ktype;

struct kobj_type {
    void (*release)(struct kobject *kobj);
    const struct sysfs_ops *sysfs_ops;  //属性操作
    struct attribute **default_attrs;
    const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
    const void *(*namespace)(struct kobject *kobj);
};

struct sysfs_ops {
    ssize_t (*show)(struct kobject *, struct attribute *,char *);
    ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
};
struct sysfs_ops 定义一组对内核struct attribute 操作的函数

struct attribute {
    const char      *name; //名字
    struct module       *owner;
    mode_t          mode; //属性 
};
sysfs_create_file  //create an attribute file for an object.
int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
//添加属性文件 
//例子:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kobject.h>

static struct kobject * parent = NULL;
static struct kobject * child = NULL;

static struct attribute child_attr = {
    .name = "child_attr",
    .mode = S_IRUSR,
};

static int __init kobject_test_init(void)
{
     printk(KERN_INFO "%s\n",__FUNCTION__);

     parent = kobject_create_and_add("pa_obj",NULL);
     child = kobject_create_and_add("pb_obj",parent);

     sysfs_create_file(child, &child_attr); //添加一个文件

     return 0;
}

static void __exit kobject_test_exit(void)
{
     printk(KERN_INFO "%s\n",__FUNCTION__);

     sysfs_remove_file(child, &child_attr); //删除文件

     kobject_del(child);
     kobject_del(parent);
}

module_init(kobject_test_init); 
module_exit(kobject_test_exit);

//测试后 在/pa_obj/pb_obj/路径下会有一个 child_attr
那么怎么对 child_attr文件的操作 ?
app: open("/pa_obj/pb_obj/child_attr",O_RDONLY)
        sys_open
            ...
                sysfs_open_file(struct inode *inode, struct file *file) // fs/sysfs/file.c
                struct sysfs_buffer *buffer;
                const struct sysfs_ops *ops;
                ops = kobj->ktype->sysfs_ops;   // 获取到驱动中的sysfs_ops
                buffer->needs_read_fill = 1;
                buffer->ops = ops;
                file->private_data = buffer; //放进私有数据
      对属性文件的读:
      ssize_t read(int fd, void *buf, size_t count);  
        sys_read
            .....
            static ssize_t sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
                struct sysfs_buffer * buffer = file->private_data;  
                    fill_read_buffer(file->f_path.dentry,buffer);
                        const struct sysfs_ops * ops = buffer->ops;
                        count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page); //调用ktyte中注册的show函数
      对属性文件的写操作
      ssize_t write(int fd, void *buf, size_t count); 
        sys_write
            ......
                sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
                struct sysfs_buffer * buffer = file->private_data;
                len = fill_write_buffer(buffer, buf, count);
                    buffer->page = (char *)get_zeroed_page(GFP_KERNEL);
                    error = copy_from_user(buffer->page,buf,count);
                en = flush_write_buffer(file->f_path.dentry, buffer, len);
                    const struct sysfs_ops * ops = buffer->ops;
                    rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count); //调用ktype中注册的store函数

例子:

//对内核对象的属性操作 
int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,struct kobject *parent, const char *fmt, ...)

//例子

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/slab.h>

static struct kobject * parent = NULL;
static struct kobject * child = NULL;

static struct attribute child_attr = {
    .name = "child_attr",
    .mode = S_IRUSR|S_IWUSR,
};

static ssize_t  attr_show(struct kobject *kobj, struct attribute *attr,char *buf)
{
    printk(KERN_INFO "%s\n",__FUNCTION__);
    return 0;
}

//为什么 一直 store 需要返回count 
static ssize_t attr_store (struct kobject *kobj,struct attribute *attr,const char *buf, size_t count)
{
    printk(KERN_INFO "%s\n",__FUNCTION__);

    printk(KERN_INFO"buf[0] = 0x%x",*buf);
    printk(KERN_INFO"buf[1] = 0x%x",*buf);
    //return count
    return  count;
}

static struct sysfs_ops attr_ops ={
    .show = attr_show,
    .store = attr_store,
};

static struct kobj_type attr_ktype={
    .sysfs_ops = &attr_ops,
};

static int __init kobject_test_init(void)
{
     printk(KERN_INFO "%s\n",__FUNCTION__);

     parent = kobject_create_and_add("pa_obj",NULL);

     //child = kobject_create();
     child = kzalloc(sizeof(*child), GFP_KERNEL);
     if (!child)
        return NULL;

     kobject_init_and_add(child ,&attr_ktype, parent, "pb_obj");

     sysfs_create_file(child, &child_attr);

     return 0;
}

static void __exit kobject_test_exit(void)
{
         printk(KERN_INFO "%s\n",__FUNCTION__);

     sysfs_remove_file(child, &child_attr);

     kobject_del(child);
     kobject_del(parent);
}

module_init(kobject_test_init); 
module_exit(kobject_test_exit);

MODULE_AUTHOR("derrick email: kjfure@163.com");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Kobject test Module");
MODULE_ALIAS("Kobject test Module");

//测试 
写 : echo '1' > /sys/pa_obj/pa_obj/child_attr
读 :  cat /sys/pa_obj/pa_obj/child_attr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值