linux 内核结构基础

embedded/2025/2/13 7:30:48/

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/embedded/161816.html

相关文章

【DeepSeek】DeepSeek的横向扩展使用② | 制作PPT

本文的主要内容是使用DeepSeek KIMI 制作PPT,效率飞起。 目录 如何使用DeepSeek制作PPT? ①利用 DeepSeek 生成 PPT 内容。 ②使用 Kimi 转换生成 PPT DeepSeek官网:DeepSeek 点击“开始对话”,进入交互页面。 Chat&#x…

Kafka的消费消息是如何传递的?

大家好,我是锋哥。今天分享关于【Kafka的消费消息是如何传递的?】面试题。希望对大家有帮助; Kafka的消费消息是如何传递的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Kafka 的消息传递机制是基于 发布-订阅 模型…

5、大模型的记忆与缓存

文章目录 本节内容介绍记忆Mem0使用 mem0 实现长期记忆 缓存LangChain 中的缓存语义缓存 本节内容介绍 本节主要介绍大模型的缓存思路,通过使用常见的缓存技术,降低大模型的回复速度,下面介绍的是使用redis和mem0,当然redis的语义…

机器学习(李宏毅)——BERT

一、前言 本文章作为学习2023年《李宏毅机器学习课程》的笔记,感谢台湾大学李宏毅教授的课程,respect!!! 读这篇文章必须先了解self-attention、Transformer,可参阅我其他文章。 二、大纲 BERT简介self-…

MRC最大比合并

1️⃣ 分集和复用技术介绍 多天线技术大致可以分为两类:分集技术和空间复用技术。 分集技术利用多天线接收同一个信号,从而提高传输的可靠性。分集技术的基本思想是将瑞利衰落无线信道转换成更加稳定的信道,像 AWGN 一样没有灾难性的信号衰…

Kafka的ISR是什么,HW是什么,怎么保证可靠性,Kafka怎么实现顺序消息?为什么Kafka的broker上的topic越多,效率越慢?

目录 1. Kafka 的 ISR 是什么 2. Kafka 的 HW 是什么 3. Kafka 如何保证可靠性 4. Kafka 怎么实现顺序消息 5. 为什么 Kafka 的 broker 上的 topic 越多,效率越慢 1. Kafka 的 ISR 是什么 ISR 即 In-Sync Replicas(同步副本集),是 Kafka 中一个重要的概念,用于保障消…

音视频协议

1. 多媒体信息 1.1 多媒体信息的两个主要特点: 信息量很大 标准语音:64Kbits(8KHz采样,8位编码)高质量音频:3Mbps(100KHz采样,12位编码) 在传输多媒体数据时,对时延和时延抖动均有较高要求 1.2 处理时延…

Python3创建虚拟环境

个人博客地址:Python3创建虚拟环境 | 一张假钞的真实世界 Python虚拟环境主要是为了解决Python多版本及模块间版本兼容的问题。创建虚拟环境的方法很简单,使用下面的命令即可: python3 -m venv PySparkEnv PySparkEnv即虚拟环境的主目录。…