2024年最全设备驱动模型-Kobject和Kset(1),2024年最新想自学C C++的速来

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

/sys 文件系统下的目录结构

/sys 下的目录结构是经过精心设计的:在 /sys/devices 下是所有设备的真实对象,比如视频卡和以太网卡等真实的设备;在其它目录如 class, bus 等中则在分类的目录中含有大量对 devices 中真实对象引用的符号链接文件

/sys子目录所包含的内容
devices这是内核对系统中所有设备的分层次表达模型,也是 /sys 文件系统管理设备的最重要的目录结构
dev这个目录下维护一个按字符设备和块设备的主次号码(major:minor)链接到真实的设备(/sys/devices下)的符号链接文件,它是在内核 2.6.26 首次引入;
bus这是内核设备按总线类型分层放置的目录结构, devices 中的所有设备都是连接于某种总线之下,在这里的每一种具体总线之下可以找到每一个具体设备的符号链接,它也是构成 Linux 统一设备模型的一部分;
class这是按照设备功能分类的设备模型,如系统所有输入设备都会出现在 /sys/class/input 之下,而不论它们是以何种总线连接到系统。它也是构成 Linux 统一设备模型的一部分;
block这里是系统中当前所有的块设备所在,按照功能来说放置在 /sys/class 之下会更合适,但只是由于历史遗留因素而一直存在于 /sys/block, 但从 2.6.22 开始就已标记为过时,只有在打开了 CONFIG_SYSFS_DEPRECATED 配置下编译才会有这个目录的存在,并且在 2.6.26 内核中已正式移到 /sys/class/block, 旧的接口 /sys/block 为了向后兼容保留存在,但其中的内容已经变为指向它们在 /sys/devices/ 中真实设备的符号链接文件;
firmware这里是系统加载固件机制的对用户空间的接口,关于固件有专用于固件加载的一套API
fs这里按照设计是用于描述系统中所有文件系统,包括文件系统本身和按文件系统分类存放的已挂载点,但目前只有 fuse,gfs2 等少数文件系统支持 sysfs 接口,一些传统的虚拟文件系统(VFS)层次控制参数仍然在 sysctl (/proc/sys/fs) 接口中
kernel这里是内核所有可调整参数的位置,目前只有 uevent_helper, kexec_loaded, mm, 和新式的 slab 分配器等几项较新的设计在使用它,其它内核可调整参数仍然位于 sysctl (/proc/sys/kernel) 接口中 ;
module这里有系统中所有模块的信息,不论这些模块是以内联(inlined)方式编译到内核映像文件(vmlinuz)中还是编译为外部模块(ko文件),都可能会出现在 /sys/module 中:编译为外部模块(ko文件)在加载后会出现对应的 /sys/module//, 并且在这个目录下会出现一些属性文件和属性目录来表示此外部模块的一些信息,如版本号、加载状态、所提供的驱动程序等;
power这里是系统中电源选项,这个目录下有几个属性文件可以用于控制整个机器的电源状态,如可以向其中写入控制命令让机器关机、重启等。
/sys/slab (对应 2.6.23 内核,在 2.6.24 以后移至 /sys/kernel/slab)从2.6.23 开始可以选择 SLAB 内存分配器的实现,并且新的 SLUB(Unqueued Slab Allocator)被设置为缺省值;如果编译了此选项,在 /sys 下就会出现 /sys/slab ,里面有每一个 kmem_cache 结构体的可调整参数。对应于旧的 SLAB 内存分配器下的 /proc/slabinfo 动态调整接口,新式的 /sys/kernel/slab/ 接口中的各项信息和可调整项显得更为清晰。
二、Kobject与Kset概述

这里写图片描述

kobject

Kobject是linux设备驱动模型的基础,也是设备模型中抽象的一部分。
Kobject实现了基本的面向对象的管理机制,是构成Linux2.6设备模型的核心结构。它与sysfs文件系统紧密相连,在内核中注册的每个kobject对象对应sysfs文件系统中的一个目录

kobject是组成设备模型的基本结构,是所有用来描述设备模型的数据结构的基类,它嵌入于所有的描述设备模型的容器对象中,例如bus,devices,drivers等。这些容器通过kobject链接起来,形成一个树状结构,这个树状结构与/sys中是一一对应的。需要注意的是,并不是说每一个kobject对象都需要在sysfs中表示,但是每一个被注册到系统中的kset都会被添加到sysfs文件系统中,一个kset对象就对应一个/sys中的一个目录,kset中的每一个kobject成员,都对应sysfs中一个文件或者一个目录。

ktype

Kobj type数据结构包含三个域:

  • 一个release方法用于释放kobject占用的资源;
  • 一个sysfs文件系统缺省属性列表。
  • 一个sysfs ops指针指向sysfs操作表和; Sysfs操作表包括两个函数store()和show()。当用户态读取属性时,show()函数被调用,该函数编码指定属性值存入buffer中返回给用户态;而store()函数用于存储用户态传入的属性值。
kset

kset最重要的是建立上层(sub-system)和下层的(kobject)的关联性。kobject 也会利用它来分辨自已是属于那一個类型,然後在/sys 下建立正确的目录位置。而kset 的优先权比较高,kobject会利用自已的*kset 找到自已所属的kset,并把*ktype 指定成该kset下的ktype,除非沒有定义kset,才会用ktype來建立关系。Kobject通过kset组织成层次化的结构,kset是具有相同类型的kobject的集合,也可以说kset具有kobject所有的功能。

三、Kobject与Kset函数与实现
kobject基本操作函数
kobject\_init();
// kobject 初始化函数;

kobject\_add();
//将kobj 对象加入Linux 设备层次。挂接该kobject 对象到kset 的list 链中,
//增加父目录各级kobject 的引用计数,在其 parent 指向的目录下创建文件节点,并启动该类型内核对象的hotplug 函数

kobject\_init\_and\_add();
//kobject\_init() and kobject\_add()函数的结合,返回值与kobject\_add()相同;
//与kobject\_create\_and\_add的区别是,kobject结构体必须已经创建好,动态创建或者静态声明均可;

kobject\_del();
//从Linux 设备层次(hierarchy)中删除kobj 对象;

kobject\_create();
//动态的创建一个kobject结构体;

kobject\_create\_and\_add();
// kobject\_create\_and\_add动态创建了一个kobject结构体,将其初始化,将其加入到kobject层次中,
//并最终返回所创建的 kobject的指针,当然如果函数执行失败,则返回NULL;

kobject\_rename();
//改变一个kobject的名字;

kobject\_move();
//将一个kobject从一个层次移动到另一个层次;

kobject\_get();
//将kobj 对象的引用计数加1,同时返回该对象的指针;

kobject\_put();
//将kobj 对象的引用计数减1,如果引用计数降为0,则调用kobject\_release()释放该kobject 对象;

kobject\_get\_path();
//返回kobject的路径;

kobject\_set\_name();
//设置kobject的名字
kobject代码示例
#include <linux/module.h> // module\_init module\_exit
#include <linux/init.h> // \_\_init \_\_exit
#include <linux/device.h> 
#include <linux/kernel.h> 
#include <linux/string.h> 
#include <linux/sysfs.h> 
#include <linux/stat.h> 

//MODULE\_xxx这种宏作用是用来添加模块描述信息
MODULE_LICENSE("GPL");                // 描述模块的许可证
MODULE_AUTHOR("pp");                  // 描述模块的作者
MODULE_VERSION("0.1");                // 描述模块的版本
MODULE_DESCRIPTION("module kobject");   // 描述模块的介绍信息
MODULE_ALIAS("alias kobject");          // 描述模块的别名信息

void obj_test_release(struct kobject *kobject);
ssize_t kobj_test_show(struct kobject *kobject,struct attribute *attr,char *buf);
ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf,size_t count);


//文件:文件名+文件权限
struct attribute test_attr ={
    .name = "kobj\_config",
    .mode = S_IRWXUGO,
};
//属性(指针数组),一个指针代码一个文件,有几个代表几个文件
static struct attribute *def_attrs[]={
    &test_attr,
    NULL,
};

//读写文件时会调用show/store方法
struct sysfs_ops obj_test_sysops = 
{
    .show = kobj_test_show,
    .store = kobj_test_store,
};

//important
struct kobj_type ktype =
{
    .release = obj_test_release,
    .sysfs_ops =&obj_test_sysops,
    .default_attrs = def_attrs,
};

//release当计数为0时调用
void obj_test_release(struct kobject *kobject)
{
    printk("eric\_test: release .\n");
}

//读
ssize_t kobj_test_show(struct kobject *kobject,struct attribute *attr,char *buf)
{
    printk("have show.\n");
    printk("attrname:%s.\n",attr->name);
    sprintf(buf,"%s\n",attr->name);
    return strlen(attr->name)+2;
}
//写
ssize_t kobj_test_store(struct kobject *kobject,struct attribute *attr,const char *buf,size_t count)
{
    printk("have store\n");
    printk("write:%s\n",buf);
    return count;
}

//
struct kobject kobj;
static int  __init kobj_test_init(void)
{
    printk("kobject test init.\n");
    //初始化kobect,并将其注册到linux系统
    //ktype记录了kobject对象的属性和动作
    //NULL表示在sys根目录创建一个目录,目录名为kobject\_test
    kobject_init_and_add(&kobj,&ktype,NULL,"kobject\_test");
    return 0;
}

static void __exit  kobj_test_exit(void)
{
    printk("kobject test exit.\n");
    kobject_del(&kobj);
}

module_init(kobj_test_init);
module_exit(kobj_test_exit);


验证:
这里写图片描述


kset概述

kset是具有相同类型的kobject的集合,在sysfs体系中体现为一个目录,在内核中有一个网上有一个非常经典的图,反应出kobject和kset的关系。
这里写图片描述
kobject对应于sysfs文件系统的一个目录,该目录可以有一些设备属性相关的文件。
kset相同类型的kobject的集合,也是对应于sysfs文件系统的一个目录,其子目录,也就是kobject的目录。

struct kset {
    struct list_head list;       //连接kset中所有的kobject的链表
    spinlock_t list_lock;       //访问时候加锁
    struct kobject kobj;        //连接kobject
    const struct kset_uevent_ops *uevent_ops;//主要是热插拔事件
};

由上面的数据类型和图可以看出,kset和kobject的基本关系。
在linux系统中,当系统的环境发生变化时,如添加kset到系统,移动kobject都会从内核空间发送到用户控件,这个是热插拔事件,那么相应的处理程序会被调用,这个处理程序会调用加载驱动,创建设备节点等来响应。

struct kset_uevent_ops {
    int (* const filter)(struct kset *kset, struct kobject *kobj);
    const char *(* const name)(struct kset *kset, struct kobject *kobj);


![img](https://img-blog.csdnimg.cn/img_convert/072d3253646e221063b6aeae2f5698e1.png)
![img](https://img-blog.csdnimg.cn/img_convert/0ab16fe3c4c8b32ff6af1bc1f206831c.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

W-1715618459650)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值