当前位置: 首页 > news >正文

Linux设备模型交互机制详细分析

Linux设备模型交互机制详细分析

概述

本文档深入分析Linux设备模型中kset、kobject、device等组件的交互机制,包括初始化流程、生命周期管理、事件处理和sysfs映射等核心机制。

1. kobject生命周期管理机制

1.1 kobject初始化流程图

kobject_init
设置ktype
初始化kref=1
初始化list_head
设置状态标志
kobject_add
设置name
设置parent
加入kset链表
创建sysfs节点
发送ADD uevent

1.2 引用计数管理机制

// 引用计数操作核心代码分析
struct kobject *kobject_get(struct kobject *kobj)
{if (kobj) {if (!kref_get_unless_zero(&kobj->kref))kobj = NULL;}return kobj;
}void kobject_put(struct kobject *kobj)
{if (kobj) {kref_put(&kobj->kref, kobject_release);}
}static void kobject_release(struct kref *kref)
{struct kobject *kobj = container_of(kref, struct kobject, kref);// 调用ktype->release()if (kobj->ktype && kobj->ktype->release)kobj->ktype->release(kobj);
}

1.3 引用计数流转图

                    kobject引用计数生命周期创建时           获取引用         释放引用         销毁时kref=1    -->    kref++    -->    kref--    -->   kref=0│                │               │               │▼                ▼               ▼               ▼┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐│ CREATED │    │ ACTIVE  │    │ ACTIVE  │    │RELEASED ││         │    │         │    │         │    │         ││kobject_ │    │kobject_ │    │kobject_ │    │ktype->  ││init()   │    │get()    │    │put()    │    │release()│└─────────┘    └─────────┘    └─────────┘    └─────────┘

2. kset容器管理机制

2.1 kset操作流程

// kset核心操作代码分析
struct kset *kset_create_and_add(const char *name,const struct kset_uevent_ops *uevent_ops,struct kobject *parent_kobj)
{struct kset *kset;int error;kset = kset_create(name, uevent_ops, parent_kobj);if (!kset)return NULL;error = kset_register(kset);if (error) {kfree(kset);return NULL;}return kset;
}static void kset_release(struct kobject *kobj)
{struct kset *kset = container_of(kobj, struct kset, kobj);// 清理kset资源kfree(kset);
}

2.2 kset层次结构管理图

                    kset层次结构管理机制┌─────────────────┐│   kernel_kobj   │ (根kobject)└─────────┬───────┘│ parent▼┌─────────────────────────────────────────────────────┐│                devices_kset                         ││  ┌─────────────────────────────────────────────┐    ││  │         embedded kobject                    │    ││  │  name: "devices"                           │    ││  │  parent: &kernel_kobj                     │    ││  │  ktype: &kset_ktype                       │    ││  └─────────────────────────────────────────────┘    ││                                                     ││  ┌─────────────────────────────────────────────┐    ││  │              list                           │    ││  │   ┌──────────┐  ┌──────────┐  ┌──────────┐  │    ││  │   │device1   │  │device2   │  │device3   │  │    ││  │   │.entry    │  │.entry    │  │.entry    │  │    ││  │   │.kset ────┼──┼.kset ────┼──┼.kset ────┼──┼────┼┐│  │   └──────────┘  └──────────┘  └──────────┘  │    │││  └─────────────────────────────────────────────┘    │││                                                     │││  uevent_ops: &device_uevent_ops                     ││└─────────────────────────────────────────────────────┘││┌─────────────────────────────────────────────────────┐││             同级kset: bus_kset                      │││             同级kset: class_kset                    │││             同级kset: fs_kset                       ││└─────────────────────────────────────────────────────┘││关联 ◄──────────────────────────┘

3. device与kobject集成机制

3.1 device初始化流程

// device初始化核心代码
void device_initialize(struct device *dev)
{dev->kobj.kset = devices_kset;  // 加入devices_ksetkobject_init(&dev->kobj, &device_ktype);  // 初始化嵌入的kobjectINIT_LIST_HEAD(&dev->devres_head);device_pm_init(dev);set_dev_node(dev, -1);// ... 其他初始化
}int device_add(struct device *dev)
{// 1. 设置kobject名称if (dev->init_name) {dev_set_name(dev, "%s", dev->init_name);dev->init_name = NULL;}// 2. 设置父设备关系if (dev->parent)dev->kobj.parent = &dev->parent->kobj;// 3. 添加到kobject层次结构error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);// 4. 添加到各个子系统if (dev->bus)bus_add_device(dev);if (dev->class)device_add_class_symlinks(dev);// 5. 创建属性文件device_add_attributes(dev, dev->class);return 0;
}

3.2 device与各子系统关联图

                    device与子系统关联机制┌─────────────────────────────────────────────────────┐│                    device                           ││  ┌─────────────────────────────────────────────┐    ││  │            kobject                          │    ││  │  name: "eth0"                              │    ││  │  parent: &pci_device.kobj                  │    ││  │  kset: devices_kset                        │    ││  │  ktype: &device_ktype                      │    ││  └─────────────────────────────────────────────┘    ││                                                     ││  bus: &pci_bus_type ────────────────────────────────┼─┐│  driver: &e1000_driver ─────────────────────────────┼─┼─┐│  class: &net_class ─────────────────────────────────┼─┼─┼─┐│  parent: &pci_device ───────────────────────────────┼─┼─┼─┼─┐└─────────────────────────────────────────────────────┘ │ │ │ ││ │ │ │device_private                 │ │ │ │┌─────────────────────────────────────────────────────┐ │ │ │ ││  knode_bus    ──────────────────────────────────────┼─┘ │ │ ││  knode_driver ──────────────────────────────────────┼───┘ │ ││  knode_class  ──────────────────────────────────────┼─────┘ ││  knode_parent ──────────────────────────────────────┼───────┘│  klist_children                                     ││  device: &device                                    │└─────────────────────────────────────────────────────┘│▼┌─────────────────────────────────────────────────────┐│                pci_bus_type                         ││  ┌─────────────────────────────────────────────┐    ││  │          subsys_private                     │    ││  │   klist_devices contains device             │    ││  │   klist_drivers contains drivers            │    ││  └─────────────────────────────────────────────┘    │└─────────────────────────────────────────────────────┘│▼┌─────────────────────────────────────────────────────┐│               e1000_driver                          ││  ┌─────────────────────────────────────────────┐    ││  │          driver_private                     │    ││  │   klist_devices contains device             │    ││  └─────────────────────────────────────────────┘    │└─────────────────────────────────────────────────────┘│▼┌─────────────────────────────────────────────────────┐│                 net_class                           ││  ┌─────────────────────────────────────────────┐    ││  │          subsys_private                     │    ││  │   klist_devices contains device             │    ││  └─────────────────────────────────────────────┘    │└─────────────────────────────────────────────────────┘

4. sysfs映射机制

4.1 sysfs文件系统映射流程

// sysfs映射核心代码
int kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...)
{// 1. 设置名称和父对象kobj->parent = parent;// 2. 创建sysfs目录error = create_dir(kobj);if (error)return error;// 3. 加入kset链表kobj_kset_join(kobj);// 4. 发送uevent事件kobject_uevent(kobj, KOBJ_ADD);return 0;
}static int create_dir(struct kobject *kobj)
{const struct kobj_type *ktype = get_ktype(kobj);// 创建kernfs节点kobj->sd = kernfs_create_dir(parent_sd, kobj->name, 0755, kobj);// 创建默认属性文件if (ktype && ktype->default_groups) {error = sysfs_create_groups(kobj, ktype->default_groups);}return 0;
}

4.2 sysfs目录结构映射图

                    sysfs目录结构映射机制内核对象层次                     sysfs文件系统kernel_kobj                      /sys/│                              │▼                              ▼devices_kset ────────────────→  /sys/devices/│                              │├─device1 ───────────────→     ├─pci0000:00/│   │                          │    ││   ├─kobject.name="pci..."    │    ├─0000:00:1f.2/│   ├─attribute1               │    │    ├─vendor│   ├─attribute2               │    │    ├─device  │   └─child_device ──────────→ │    │    └─subsystem -> ../../bus/pci│                              │    │├─device2 ───────────────→     ├─platform/│                              │    │└─device3 ───────────────→     └─virtual/│bus_kset ────────────────────→  /sys/bus/│                              │├─pci_bus ──────────────→      ├─pci/│   │                          │   ├─devices/│   ├─devices_kset              │   │   ├─0000:00:1f.2 -> ../../../devices/pci0000:00/0000:00:1f.2│   └─drivers_kset              │   │   └─...│                              │   └─drivers/└─platform_bus ─────────→      │       ├─e1000/│       └─...└─platform/class_kset ──────────────────→  /sys/class/│                              │├─net_class ────────────→      ├─net/│   │                          │   ├─eth0 -> ../../devices/pci0000:00/0000:00:1f.2/net/eth0│   └─devices_kset              │   └─...│                              │└─block_class ──────────→      └─block/├─sda -> ../../devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/block/sda└─...

5. uevent事件机制

5.1 uevent事件流程

// uevent事件处理核心代码
int kobject_uevent(struct kobject *kobj, enum kobject_action action)
{return kobject_uevent_env(kobj, action, NULL);
}int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,char *envp_ext[])
{struct kobj_uevent_env *env;struct kset_uevent_ops *uevent_ops;// 1. 检查是否抑制事件if (kobj->uevent_suppress)return 0;// 2. 找到顶层ksettop_kobj = kobj;while (!top_kobj->kset && top_kobj->parent)top_kobj = top_kobj->parent;// 3. 获取uevent操作集uevent_ops = top_kobj->kset->uevent_ops;// 4. 过滤事件if (uevent_ops && uevent_ops->filter) {if (!uevent_ops->filter(kobj))return 0;}// 5. 构建环境变量env = kzalloc(sizeof(*env), GFP_KERNEL);// 添加标准环境变量add_uevent_var(env, "ACTION=%s", kobject_actions[action]);add_uevent_var(env, "DEVPATH=%s", devpath);add_uevent_var(env, "SUBSYSTEM=%s", subsystem);// 6. 调用自定义uevent处理if (uevent_ops && uevent_ops->uevent) {retval = uevent_ops->uevent(kobj, env);}// 7. 发送netlink消息到用户空间netlink_broadcast_filtered(uevent_sock, skb, ...);return 0;
}

5.2 uevent事件传播图

                    uevent事件传播机制内核空间                                用户空间┌─────────────────┐                   ┌─────────────────┐│   kobject       │                   │     udevd       ││                 │                   │                 ││ kobject_uevent()│ ──────────────────┤                 │└─────────┬───────┘                   │  netlink socket ││                           │                 │▼                           │                 │┌─────────────────┐                   │                 ││ kset_uevent_ops │                   │                 ││                 │                   │                 ││ ├─filter()      │                   │                 ││ ├─name()        │                   │                 ││ └─uevent()      │                   │                 │└─────────┬───────┘                   │                 ││                           │                 │▼                           │                 │┌─────────────────┐    netlink        │                 ││ netlink_broadcast│ ─────────────────►│                 ││                 │                   │                 ││ ACTION=add      │                   │                 ││ DEVPATH=/devices│                   │                 ││ SUBSYSTEM=net   │                   │                 ││ DEVTYPE=...     │                   │                 │└─────────────────┘                   └─────────────────┘│▼┌─────────────────┐│   用户空间处理   ││                 ││ ├─创建设备节点   ││ ├─加载模块      ││ ├─设置权限      ││ └─运行脚本      │└─────────────────┘

6. 设备驱动绑定机制

6.1 driver-device匹配流程

// 驱动设备匹配核心代码
static int device_attach(struct device *dev)
{if (dev->driver) {// 设备已有驱动device_bind_driver(dev);return 1;}// 在总线上查找匹配的驱动return bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
}static int __device_attach(struct device_driver *drv, void *data)
{struct device *dev = data;// 检查驱动是否匹配设备if (!driver_match_device(drv, dev))return 0;// 尝试绑定return driver_probe_device(drv, dev);
}static inline int driver_match_device(struct device_driver *drv,struct device *dev)
{return drv->bus->match ? drv->bus->match(dev, drv) : 1;
}

6.2 驱动设备绑定状态图

                    驱动设备绑定状态转换图设备状态        事件           驱动状态         结果┌─────────┐   device_add    ┌─────────┐     ┌─────────┐│ CREATED │ ─────────────── │AVAILABLE│ ──► │ PROBING │└─────────┘                 └─────────┘     └─────────┘│                           │               ││ driver_register            │ match()       │ probe()▼                           ▼               ▼┌─────────┐                 ┌─────────┐     ┌─────────┐│UNBOUND  │ ◄─────────────── │MATCHING │ ──► │ BOUND   │└─────────┘   probe_failed   └─────────┘     └─────────┘▲                                           ││ device_release_driver                     │ device_remove└───────────────────────────────────────────┘状态说明:CREATED: 设备已创建但未添加到系统UNBOUND: 设备在系统中但未绑定驱动AVAILABLE: 驱动可用等待设备MATCHING: 正在进行匹配过程PROBING: 正在执行probe函数BOUND: 设备和驱动成功绑定

7. 总结

Linux设备模型通过kobject、kset、device等核心组件的精妙配合,实现了:

  1. 统一的对象管理: 所有设备对象都基于kobject,提供统一的引用计数和生命周期管理
  2. 层次化的组织结构: 通过kset容器和parent指针构建清晰的设备树
  3. 透明的sysfs映射: 内核对象层次直接映射到用户空间可见的文件系统
  4. 灵活的事件通知: uevent机制实现内核到用户空间的异步事件通知
  5. 动态的驱动绑定: 支持设备和驱动的热插拔和动态匹配
http://www.dtcms.com/a/343924.html

相关文章:

  • 分段渲染加载页面
  • 第9课:本地功能集成
  • 宋红康 JVM 笔记 Day06|虚拟机栈
  • Seaborn数据可视化实战:Seaborn数据可视化基础-从内置数据集到外部数据集的应用
  • 学习游戏制作记录(合成表UI和技能树的UI)8.22
  • Python打卡Day49 CBAM注意力
  • 小迪安全v2023学习笔记(六十九讲)—— Java安全JWT攻防监控组件泄露接口
  • 北斗导航 | 基于MCMC粒子滤波的接收机自主完好性监测(RAIM)算法(附matlab代码)
  • 【C++组件】Elasticsearch 安装及使用
  • ODYSSEY:开放世界四足机器人的探索与操控,助力长范围任务
  • ref 简单讲解
  • 【前端教程】从基础到进阶:淘宝 HTML 界面“回到顶部”功能的交互升级实战
  • 刷题日记0822
  • Git 版本管理各模块知识点梳理
  • Logstash_Input插件
  • Chrome和Edge如何开启暗黑模式
  • 浏览器插件优化工具:bypass paywalls chrome
  • 【TrOCR】根据任务特性设计词表vocab.json
  • 今日科技热点 | NVIDIA AI芯片、5G加速与大数据平台演进——技术驱动未来
  • ESP32C5在espidf环境下报错5g bitmap contains only invalid channels= @xff
  • 龙虎榜——20250822
  • 线上日志排查问题
  • docker 查看容器 docker 筛选容器
  • 使用 Ragas 评估你的 Elasticsearch LLM 应用
  • 基于Python的伊人酒店管理系统 Python+Django+Vue.js
  • 基于Docker的高可用WordPress集群部署:Nginx负载均衡+Mysql主从复制+ProxySQL读写分离
  • Unreal Engine UFloatingPawnMovement
  • SpringBoot集成ELK
  • 【Dubbo】高性能的 RPC
  • 零基础从头教学Linux(Day 18)