linux 内核结构基础

devtools/2025/2/13 14:56:14/

linux 内核对象基础

    • 1.linux 的 kobj(struct kobject) 类
    • 2.linux 中的 kset
    • 3. linux 下的 ktype (kobj_type 类)
    • 4. kobj 的使用理解

linux__kobjstruct_kobject__2">1.linux 的 kobj(struct kobject) 类

kobjlinux 下的高级抽象类定义,用于派生所有其余的类定义,比如设备类定义struct device.

struct kobject 定义在 include/linux/kobject.h 文件中:

struct kobject {const char		*name;struct list_head	entry;struct kobject		*parent;struct kset		*kset;struct kobj_type	*ktype;struct kernfs_node	*sd; /* sysfs directory entry */struct kref		kref;
#ifdef CONFIG_DEBUG_KOBJECT_RELEASEstruct delayed_work	release;
#endifunsigned int state_initialized:1;unsigned int state_in_sysfs:1;unsigned int state_add_uevent_sent:1;unsigned int state_remove_uevent_sent:1;unsigned int uevent_suppress:1;
};

kobj 成员说明:

成员描述
namekobj 名字,会显示在 /sys/ 目录下
entry双向链接节点,用于被链入所属的 kset
parent指向 parent kobj, 在 /sys/ 中会以目录的形式呈现
kset当前 kobj 所属的 kset,kset 是一个特殊的 kobj, 用来集合相似的 kobj,表示父目录
ktype每一个 kobj 都必须有一个 ktype,用于访问该内核文件特有的属性,用于生成目录下的文件,以及实现文件读写驱动
sd当前 kobj 在 sysfs 中的目录入口,用于表示文件对象节点对象,kernfs_node 结构体中的 priv 成员会设置为 kobject 对象。
krefkobj 引用计数
state_initialized初始化状态
state_in_sysfs当前 kobj 是否已在 /sys/ 中呈现
state_add_uevent_sent记录是否已经向用户空间发送 uevent
state_remove_uevent_sent记录移除节点时,是否向用户空间发送 remove uevent
uevent_suppress是否忽略所有的用户空间事件上报,即事件通知

linux__kset_46">2.linux 中的 kset

kset 用于集合一系列相似的 kobj(类比某根目录?), 原型如下:

struct kset {struct list_head list;spinlock_t list_lock;struct kobject kobj;const struct kset_uevent_ops *uevent_ops;
} __randomize_layout;

kset 是一个特殊的 kobj,成员说明如下:

成员描述
list双向链表头,用于链接管理 kobj
list_lock自旋锁,防止接口竞争
kobjkset 是一个特殊的 kobj, kset 也会在 ‘/sys/’ 目录下出现
uevent_ops事件操作?

比如 /sys/bus/ 存在多个总线,bus 就属于一个 kset?

比如 /sys/class/ 存在多个 class,class 也属于一个 kset?

(似乎是的)

那么猜测: kset 用于表示 /sys/ 目录下的一级目录。

linux__ktype_kobj_type__76">3. linux 下的 ktype (kobj_type 类)

ktype 用于实现 kobj 的一些特殊操作,比如释放 kobj 空间。

原型如下:

struct kobj_type {void (*release)(struct kobject *kobj);const struct sysfs_ops *sysfs_ops;struct attribute **default_attrs;	/* use default_groups instead */const struct attribute_group **default_groups;const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);const void *(*namespace)(struct kobject *kobj);void (*get_ownership)(struct kobject *kobj, kuid_t *uid, kgid_t *gid);
};

最重要的 release 函数指针,用于释放 kobj空间。

sysfs_ops 用于访问当前 kobj 的属性文件。

/*** 作为 kobj_type 的成员,用于访问该内核对象下的属性文件的通用读写操作,而实际的属性读写函数,由驱动实现。* 一般用于内核层,比如内核总线、class 的属性访问方法,会调用实际总线、class 实现的属性访问方法*/
struct sysfs_ops {ssize_t	(*show)(struct kobject *, struct attribute *, char *);ssize_t	(*store)(struct kobject *, struct attribute *, const char *, size_t);
};

struct attribute **default_attrs 为属性指针数组,该数组保存一系列的属性指针。

/* 内核文件的属性,一个属性对应一个文件 */
/*** 这是通用的属性对象,使用时会对该对象进行封装,比如总线属性,设备属性,一般会根据实际情况封装属性文件的读写方法。 */
struct attribute {const char		*name;umode_t			mode;
#ifdef CONFIG_DEBUG_LOCK_ALLOCbool			ignore_lockdep:1;struct lock_class_key	*key;struct lock_class_key	skey;
#endif
};

还存在一个 struct attribute_group 类,用于存储一组属性,但用法没有研究透。

struct attribute_group {const char		*name;umode_t			(*is_visible)(struct kobject *,struct attribute *, int);umode_t			(*is_bin_visible)(struct kobject *,struct bin_attribute *, int);struct attribute	**attrs;struct bin_attribute	**bin_attrs;
};

代码分析:根据 sysfs_create_groups() 函数实现,如果 struct attribute_group name 成员实现,那么会在指定的 kobj 对象下另建一个 group 目录,并在 group 目录下创建所有的可见属性文件。

4. kobj 的使用理解

kobj 大多时候是嵌入到高级数据结构中,比如设备定义 struct device 中。

这些高级数据结构一般是动态分配的,当内嵌的 kobj 的引用计数 kref 减为 0 时,需要释放高级数据结构所占内存,以及对应的 kobj 内存。

此时,需要使用 kobj 中 ktype 定义的 release 函数指针。

所以,每一个包含 kobj 的高级数据结构,都必须实现所属的 ktype。

基于面向对象编程的思想,系统用户看到的只有 kobj,而不会看到驱动相关的数据结构。

以访问 /sys/ 下的文件举例, 基于一切皆文件的思想,linux 用户向/sys访问 kobj 的流程如下:

应用层linux应用层 open\read\write\close 访问文件
VFS/kernfslinux VFS 文件系统根据文件所属的实际文件系统,调用 sysfs 文件系统的 open\read\write\close
sysfssysfs 文件系统的实际驱动根据获取 kobj 对象,并调用 kobj 提供的属性(文件)访问接口
kobjkobj 调用驱动层提供的属性访问接口。
驱动驱动对私有属性的实现。

以访问字符设备 /dev/tty0举例, 基于一切皆文件的思想,linux 用户向/dev/tty0访问 kobj 的流程如下:

应用层linux应用层 open\read\write\close 访问文件
VFS/kernfslinux VFS 文件系统根据文件所属的实际文件系统,获取 knode, 并调用设备文件系统的 open\read\write\close
设备文件系统?设备文件系统根据 knode 结构获取 kobj 结构,并转换为 cdev 结构,然后直接调用驱动注册的 open/read/write/close
驱动驱动对open\read\write\close的实现。

kobj 是系统内核能访问的最底层数据结构,其余结构都是对 kobj 的再封装。

Linux应用层访问驱动自定义class属性流程如下:
在这里插入图片描述

应用层到系统内核层:

  1. 应用层使用 open/read/write/close 访问某一文件系统的文件, 系统调用;

  2. Kernfs 层根据文件系统类型调用文件系统的驱动,并获取当前文件的 knode 结构,文件的 knode 结构是对 kobj 的再封装(knode 对象与 kobj 对象相互引用);

  3. Sysfs 层会通过 knode 结构获取 kobj 结构,并调用文件(属性)的读/写;

  4. Kobj 层会调用属性访问驱动将对应属性传递到 class 层;

驱动层:

驱动层会自定义 class 属性,并定义属性访问函数;实现驱动变量的控制

  1. Class 层接收内核层对某一属性的读写访问,实现由应用层来控制驱动变量的值,控制驱动行为。

  2. 驱动根据属性变量值,做出不同的行为。

注意:

  1. 每一个驱动自定义 class 属性都会生成一个文件,通过调用 class_create_file()。
  2. class 层是对 kobj 的封装层,源码比较容易理解.

http://www.ppmy.cn/devtools/158508.html

相关文章

川翔云电脑是什么?租电脑?

在数字化时代,川翔云电脑借助云计算技术,把用户终端和云端虚拟电脑连接,打破本地硬件的局限,让大家随时随地工作、娱乐。 川翔云电脑的优势 强大硬件配置 川翔云电脑硬件配置处于行业前列,显卡尤为突出。它配备性能…

Kafka 读写示例

一、概述 Kafka 是一款流行的分布式消息队列系统,具有高吞吐量、可扩展性和持久性等优点。本文将介绍如何使用 Kafka 进行消息的生产和消费。 二、Kafka 生产者 1. 生产者配置 以下是一些常用的 Kafka 生产者配置参数: 参数描述bootstrap.serversKafka 集群的地址,用于生…

第二章:13.1 机器学习的迭代发展

目录 机器学习模型开发流程 构建电子邮件垃圾邮件分类器示例 总结 垃圾邮件分类示例 构建垃圾邮件分类器 机器学习模型开发流程 确定系统架构: 首先,需要决定机器学习系统的总体架构,这包括选择合适的模型、确定使用的数据集、可能还包括…

工具-screen-管理终端会话(服务器长时间运行任务)

screen 是一个用于管理多个终端会话的实用工具,常用于在单个终端窗口中运行多个虚拟终端。它允许用户在一个终端窗口中分离和重新连接会话,非常适合在远程服务器上工作或长时间运行任务时使用。 主要功能 1.会话管理: 可以创建多个虚拟终端…

蓝桥杯算法日记|贪心、双指针

3412 545 2928 2128 贪心学习总结: 1、一般经常用到sort(a,an);【a[n]】排序,可以给整数排,也可以给字符串按照字典序排序 2、每次选最优 双指针 有序数组、字符串、二分查找、数字之和、反转字…

996引擎-问题处理:三职业改单职业

996引擎-问题处理:三职业改单职业 问题解决方案顺便补充点单性别设置补充:可视化配置表参考资料问题 目前的版本: 引擎版本号:2024.8.7.0 三端配套客户端:3.40.9 传统PC客户端:23.12.07 配套数据库:64_24.8.7.0此版本需要通过可视化配置表

网络安全 | SNI介绍及F5中的配置应用

关注:CodingTechWork SNI介绍 SNI(Server Name Indication)是 TLS/SSL 协议中的一个重要扩展,旨在解决同一 IP 地址上托管多个网站时,如何选择正确的 SSL/TLS 证书进行加密通信的问题。SNI 通过在 TLS 握手初期传递客…

协议-LVDS

是什么? LVDS 全称为 Low-Voltage Differential Signaling,低电压差分信号 低功耗、低误码率、低串扰和低辐射的差分信号,采用-350mV~350mV极底的电压摆幅高速差动传输数据,实现点对点或一点对多点的连接 由于电压幅度低&#xf…