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

JJJ:linux sysfs相关

文章目录

    • 1.sysfs(属性)文件的创建、读、写
      • 1.1 创建流程
      • 1.2 open流程
      • 1.3 read流程
    • 2.补充
      • 2.1 sysfs下常见目录介绍
      • 2.2 属性相关
        • 2.2.1 简介
        • 2.2.2 attribute文件的创建
      • 2.3 sysfs目录如何创建的

1.sysfs(属性)文件的创建、读、写

1.1 创建流程

device_add -》 error = device_create_file(dev, &dev_attr_dev);

先来看看 dev_attr_dev 的定义
static DEVICE_ATTR_RO(dev);

 637 #define DEVICE_ATTR_RO(_name) \638     struct device_attribute dev_attr_##_name = __ATTR_RO(_name)

定义了一个 device_attribute 实例,变量名为 dev_attr_dev

__ATTR_RO 定义为:

 624 ./include/linux/sysfs.h625 #define __ATTR_RO(_name) {                      \626     .attr   = { .name = __stringify(_name), .mode = 0444 },     \627     .show   = _name##_show,                     \628 }

上面的 .attr 是 struct attribute 类型

继续看 device_create_file(dev, &dev_attr_dev);

device_create_file -> sysfs_create_file(&dev->kobj, &attr->attr);
参数1是kobject实例,参数2是device_attribute下面的attribute实例

526 // sysfs中创建文件接口:在kobj对应的目录下创建属性文件
527 static inline int __must_check sysfs_create_file(struct kobject *kobj,
528                          const struct attribute *attr)
529 {
530     return sysfs_create_file_ns(kobj, attr, NULL);
531 }

sysfs_create_file_ns -> sysfs_add_file_mode_ns (主体函数)

在 sysfs_add_file_mode_ns 函数中:
假设获取到的 sysfs_ops 为 dev_sysfs_ops
那么,struct kernfs_ops ops 为 sysfs_file_kfops_rw
以这个ops 作为参数调用 : __kernfs_create_file

__kernfs_create_file 创建一个新的 kernfs_node 实例 kn,其 parent 为 device.kobj.sd
并设置 kn->attr.ops = ops; 就是 sysfs_file_kfops_rw,如此在sysfs创立属性对应的文件

(bus_create_file和device_create_file类似)

1.2 open流程

kernfs_file_fops 这个 file_operation 实例是在哪里赋值的:

kernfs_iop_lookup (kernfs_dir_iops.lookup)
kernfs_get_inode
kernfs_init_inode

先看open:
SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
do_sys_open(dfd, filename, flags, mode);
do_filp_open
path_openat
do_last

do_last 函数中有两个关键调用:lookup_open、vfs_open

先看 lookup_open:
调用:dir_inode->i_op->lookup 对于kernfs,dir_inode->i_op 为 kernfs_dir_iops(目录ops),其 lookup hook 为:kernfs_iop_lookup。kernfs_iop_lookup -》 kernfs_get_inode -》 kernfs_init_inode,在 kernfs_init_inode 中:inode->i_fop = &kernfs_file_fops;,得到文件操作集。

继续看vfs_open:
vfs_open -》 do_dentry_open
do_dentry_open函数中,会执行:f->f_op = fops_get(inode->i_fop); 将上面inode的fops赋值给file,就是 kernfs_file_fops

do_dentry_open 下面会执行:

 806     if (!open) // open 作为入参是NULL807         open = f->f_op->open;808     if (open) {809         error = open(inode, f);810         if (error)811             goto cleanup_all;812     }

会执行到底层 open hook,即 kernfs_file_fops的open hook,kernfs_fop_open

接下来看 kernfs_fop_open:
首先从(当前操作文件对应的kernfs_node 实例)获取(kernfs_ops实例)ops = kernfs_ops(kn); 就是:kn->attr.ops。
在上面创建属性文件的流程中:__kernfs_create_file 函数会设置这个ops,为 sysfs_file_kfops_rw
回到 kernfs_fop_open,会执行如下代码段:

703     if (ops->seq_show)
704         error = seq_open(file, &kernfs_seq_ops); // 设置seq_file的ops

在seq_open函数中:会从slab缓存控制器里面分配一个 seq_file实例,并设置其ops为kernfs_seq_ops,并将这个seq_file作为其所属file实例的私有数据 private_data成员。

打开流程就大概分析上面这些,主要是为了搞明白file的操作集是怎么来的,接下来read和write会调用到什么底层hook

1.3 read流程

接下来看看读流程,是怎么调用到最底层的show hook的:
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
ksys_read(fd, buf, count);
vfs_read
__vfs_read
file->f_op->read:由上面的open流程可知,f_op为 kernfs_file_fops,read hook 为 kernfs_fop_read
kernfs_fop_read
seq_read:主要是调用 m->op->show,在上面的open流程中,m->op为kernfs_seq_ops,show hook为 kernfs_seq_show
kernfs_seq_show
of->kn->attr.ops->seq_show:在创建流程中,可知为of->kn->attr.ops 为 sysfs_file_kfops_rw,seq_show hook为 sysfs_kf_seq_show
sysfs_kf_seq_show:先获取当前kernfs_node对应的kobj,获取kobj->ktype->sysfs_ops,在创建流程中可知为 dev_sysfs_ops,再调用其 show hook,为 dev_attr_show
dev_attr_show:由 attribute实例 找到 device_attribute 实例,再调用其show hook
dev_attr->show

上面 dev_attr->show 这个hook,可以通过 DEVICE_ATTR_RO 来定义,通过 device_create_file 来注册(具体看创建流程)

2.补充

2.1 sysfs下常见目录介绍

sysfs是一个基于内存的虚拟的文件系统

目录简介
/sys/block存放块设备,提供一设备名(如sda)到/sys/devices的符号链接;
/sys/bus按总线类型分类,在某个总线目录之下可以找到链接该总线的设备的符号链接,指向/sys/devices. 某个总线目录之下的drivers目录包含了该总线所需的所有驱动的符号链接。对应kernel中的struct bus_type;
/sys/calss按设备功能分类,如输入设备在/sys/class/input之下,图形设备在/sys/class/graphics之下,是指向/sys/devices的符号链接。 对应kernel中的struct class
/sys/dev按设备驱动程序分层(字符设备 块设备),提供以major:minor为名到/sys/devices的符号链接。 对应Kernel中的struct device_driver;
/sys/devices包含所有被发现的注册在各种总线上的各种物理设备。 所有物理设备都按其在总线上的拓扑结构来显示,除了platform devices和system devices。 platform devices 一般是挂载在芯片内部高速或者低速总线上的各种控制器和外设,能被CPU直接寻址。 system devices不是外设,而是芯片内部的核心结构,比如CPU,timer等。对应kernel中的strcut device;
/sys/firmware提供对固件的查询和操作接口(关于固件有专用于固件加载的一套api);
/sys/fs描述当前加载的文件系统,提供文件系统和文件系统已挂载的设备信息;
/sys/kernel提供kernel所有可调整参数,但大多数可调整参数依然存放在sysctl(/proc/sys/kernel);
/sys/module所有加载模块(包括内联、编译进kernel、外部的模块)信息,按模块类型分类;
/sys/power电源选项,可用于控制整个机器的电源状态,如写入控制命令进行关机、重启等;

2.2 属性相关

2.2.1 简介

所谓的attibute,就是内核空间和用户空间进行信息交互的一种方法。例如某个driver定义了一个变量,却希望用户空间程序可以修改该变量,以控制driver的运行行为,那么就可以将该变量以attribute的形式开放出来。

attribute分为普通的attribute和二进制attribute,如下:

 30 struct attribute {31     const char      *name;32     umode_t         mode;33 #ifdef CONFIG_DEBUG_LOCK_ALLOC34     bool            ignore_lockdep:1;35     struct lock_class_key   *key;36     struct lock_class_key   skey;37 #endif38 };161 struct bin_attribute {
162     struct attribute    attr;
163     size_t          size;
164     void            *private;
165     ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *,
166             char *, loff_t, size_t);
167     ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
168              char *, loff_t, size_t);
169     int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,
170             struct vm_area_struct *vma);
171 };

struct attribute为普通的attribute,使用该attribute生成的sysfs文件,只能用字符串的形式读写。而struct bin_attribute在struct attribute的基础上,增加了read、write等函数,因此它所生成的sysfs文件可以用任何方式读写。

2.2.2 attribute文件的创建

dev_attr_dev属性文件的创建详见 1

bus_register -> bus_create_file 也是类似的流程

2.3 sysfs目录如何创建的

设备注册:device_add -》 kobject_add -》 kobject_add_varg -》 kobject_add_internal
总线注册:bus_register -》 kset_register -》 kobject_add_internal

kobject_add_internal
create_dir:调用sysfs_create_dir_ns在sysfs中创建目录,并把kobject所属ktype指示的默认属性都填充到当前kobj所指示的目录下

相关文章:

JJJ:linux sysfs相关

文章目录 1.sysfs(属性)文件的创建、读、写1.1 创建流程1.2 open流程1.3 read流程 2.补充2.1 sysfs下常见目录介绍2.2 属性相关2.2.1 简介2.2.2 attribute文件的创建 2.3 sysfs目录如何创建的 1.sysfs(属性)文件的创建、读、写 1…...

Leetcode 刷题记录 06 —— 矩阵

本系列为笔者的 Leetcode 刷题记录,顺序为 Hot 100 题官方顺序,根据标签命名,记录笔者总结的做题思路,附部分代码解释和疑问解答。 目录 01 矩阵置零 方法一:标记数组 方法二:两个标记变量 02 螺旋矩阵…...

什么样的物联网框架适合开展共享自助KTV唱歌项目?

现在物联网的广泛应用,也让更多用户们看到了它的实力,也使得共享经济遍地开花。其中共享自助唱歌设备也备受欢迎,那么适合开展共享自助KTV唱歌项目的物联网框架都应具备哪些特点呢? 智能化与自动化管理 物联网技术在共享KTV中的应…...

【Academy】HTTP Host 标头攻击 ------ HTTP Host header attacks

HTTP Host 标头攻击 ------ HTTP Host header attacks 1. 什么是 HTTP Host 标头?2. 什么是 HTTP Host 标头攻击?3. HTTP Host 标头漏洞是如何产生的?4. 如何测试 HTTP Host 标头漏洞4.1 提供任意 Host 标头4.2 检查有缺陷的验证4.3 发送不明…...

Web基础:HTML快速入门

HTML基础语法 HTML(超文本标记语言) 是用于创建网页内容的 标记语言,通过定义页面的 结构和内容 来告诉浏览器如何呈现网页。 超文本(Hypertext) 是一种通过 链接(Hyperlinks) 将不同文本、图像…...

技术领域,有许多优秀的博客和网站

在技术领域,有许多优秀的博客和网站为开发者、工程师和技术爱好者提供了丰富的学习资源和行业动态。以下是一些常用的技术博客和网站,涵盖了编程、软件开发、数据科学、人工智能、网络安全等多个领域: 1. 综合技术博客 1.1 Medium 网址: ht…...

k8s概念及k8s集群部署(Centos7)

Centos7部署k8s集群 部署之前,先简单说下k8s是个啥: 一、k8s简介: k8s,全称:kubernetes,它可以看作是一个分布式系统支撑平台。k8s的作用: 1、故障自愈: k8s这个玩意可以监控容器…...

《DeepSeek-V3:动态温度调节算法,开启推理新境界!》

在人工智能领域不断探索的征程中,DeepSeek-V3以其卓越的创新技术,尤其是动态温度调节算法,成为了备受瞩目的焦点。这项算法犹如一把神奇的钥匙,巧妙地开启了推理速度与精度动态平衡的大门,为大语言模型的发展开辟了新的…...

Python从入门到精通1:FastAPI

引言 在现代 Web 开发中,API 是前后端分离架构的核心。FastAPI 凭借其高性能、简洁的语法和自动文档生成功能,成为 Python 开发者的首选框架。本文将从零开始,详细讲解 FastAPI 的核心概念、安装配置、路由设计、请求处理以及实际应用案例&a…...

fastapi+angular停车管理系统可跨域

说明: 我计划用fastapiangular做一款停车管理系统,支持跨域 1.设计mysql数据库表, 2.建表,添加测试数据,多表查询, 3.在fastapi写接口查询数据, 4.用postman测试, 5.在angular前端展…...

前端题目类型

HTMLCSS常见面试题 HTML标签有哪些行内元素 img、picture、span、input、textarea、select、label 说说你对元素语义化的理解 元素语义化就是用正确的元素做正确的事情。虽然理论上所有html元素都可通过css样式实现相同效果,但这样会使事情复杂化,所以需…...

openwrt路由系统------lua、uci的关系

1. Luci 的核心组成 (1) Lua 简介:Luci 的界面和逻辑几乎完全使用 Lua 脚本语言编写。Lua 是一种轻量级、高效的嵌入式脚本语言,适合在资源受限的路由器环境中运行。作用: 生成动态 Web 页面(与后端交互渲染 HTML)。处理用户提交的表单数据(如修改 Wi-Fi 密码)。调用系…...

Elastic:AI 会开始取代网络安全工作吗?

作者:来自 Elastic Joe DeFever 不会,但它正在从根本上改变这些工作。 生成式 AI (GenAI) 正迅速成为日常安全工作流程中的一个重要组成部分。那么,它是合作伙伴还是竞争对手? GenAI 技术在安全堆栈几乎每个方面的广泛应用&#…...

Linux安装升级docker

Linux 安装升级docker Linux 安装升级docker背景升级停止docker服务备份原docker数据目录移除旧版本docker安装docker ce恢复数据目录启动docker参考 安装找到docker官网找到docker文档删除旧版本docker配置docker yum源参考官网继续安装docker设置开机自启配置加速测试 Linux …...

【经验分享】Ubuntu20.04编译RK3568 AI模型报错问题(已解决)

【经验分享】Ubuntu20.04编译RK3568 AI模型报错问题(已解决) 前言问题现象问题分析解决方案总结 前言 这里使用的是Rockchip提供的rknn_model_zoo,https://github.com/airockchip/rknn_model_zoo/tree/main 此解决方案适用于Rockchip芯片在U…...

国产算力助力工业智能新范式

随着人工智能、智能制造以及边缘计算等技术趋势的发展,算力设备正逐渐从中心云向边缘机房乃至边缘现场下沉。在此背景下,以工控机为例的部署于各类边缘现场的算力设备市场,也正面临着新的变革。 根据IDC 2024研究报告显示:在能源制…...

学习笔记:利用OpenAI实现阅卷智能体

https://zhuanlan.zhihu.com/p/18047953492 ### 学习笔记:利用OpenAI实现阅卷智能体 #### 一、背景与需求 在各类考试中,选择题、判断题、填空题的阅卷相对简单,只需对比答案与作答是否一致。然而,简答题的阅卷较为复杂&#xff…...

第6届传智杯复赛第一场

A小红劈字符串 题目链接 题目链接:A-小红劈字符串(B组)_第6届传智杯复赛第一场(补题) (nowcoder.com) 题目描述 小红拿到了一个仅由小写字母组成的字符串,她希望将其分割成两个非空子串,使得第…...

CSDN博客:Markdown编辑语法教程总结教程(中)

❤个人主页:折枝寄北的博客 Markdown编辑语法教程总结 前言1. 列表1.1 无序列表1.2 有序列表1.3 待办事项列表1.4 自定义列表 2. 图片2.1 直接插入图片2.2 插入带尺寸的图片2.3 插入宽度确定,高度等比例的图片2.4 插入高度确定宽度等比例的图片2.5 插入居…...

Codeforces Round 258 (Div. 2) E. Devu and Flowers 生成函数

题目链接 题目大意 有 n n n ( 1 ≤ n ≤ 20 ) (1\leq n \leq 20) (1≤n≤20) 个花瓶,第 i i i 个花瓶里有 f i f_i fi​ ( 1 ≤ f i ≤ 1 0 12 ) (1\leq f_i \leq 10^{12}) (1≤fi​≤1012) 朵花。现在要选择 s s s ( 1 ≤ s ≤ 1 0 14 ) (1\leq s \leq 1…...

【高并发内存池】释放内存 + 申请和释放总结

高并发内存池 1. 释放内存1.1 thread cache1.2 central cache1.3 page cache 2. 申请和释放剩余补充 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励,我们一起努力吧!😃&#x…...

AutoGen学习笔记系列(九)Advanced - Selector Group Chat

这篇文章瞄的是AutoGen官方教学文档 Advanced 章节中的 Selector Group Chat 篇章,介绍了SelectorGroupChat对象如何从一个Team中选择其中一个Agent与LLM进行对话,并且在得到结果后进行二次规划,同时你也可以自定义选择函数。本质上还是对Tea…...

Stream特性(踩坑):惰性执行、不修改原始数据源

在日常开发中,Stream API 提供了一种高效且易于使用的工具集来处理集合数据。 本文主要讲解 Stream 的两个特性:惰性执行,不修改原始数据源。 为什么说这两个、而不讲下其他的特性呢?主要是因为在开发中如果忽略这两个特性的话&…...

springcloud sentinel教程

‌QPS(Queries Per Second)即每秒查询率 TPS,每秒处理的事务数目 PV(page view)即页面浏览量 UV 访问数(Unique Visitor)指独立访客访问数 一、初识Sentinel 什么是雪崩问题? 微服务之间相…...

像素的一生 Life of a Pixel - Steve Kobes 2020版

像素的一生 Life of a Pixel - Steve Kobes 2020版 《Life of a Pixel》 作者是Google大佬 Steve Kobes 2020年 介绍Chromium内核完整渲染流程的视频,介绍的非常好,想要学习了解chromium内核渲染必看! 油管视频地址为:https://w…...

系统部署【信创名录】及其查询地址

一、信创类型 (一)服务器: 1.华为云 2.腾讯云 3.阿里云 (二)中央处理器(CPU): 1.海思,鲲鹏920服务器 (三)中间件 1.人大金仓 &#xff0…...

VSCode 配置优化指南:打造高效的 uni-app、Vue2/3、JS/TS 开发环境

VSCode 配置优化指南,适用于 uni-app、Vue2、Vue3、JavaScript、TypeScript 开发,包括插件推荐、设置优化、代码片段、调试配置等,确保你的开发体验更加流畅高效。 1. 安装 VSCode 如果你还未安装 VSCode,可前往 VSCode 官网 下载最新版并安装。 2. 安装推荐插件 (1) Vue…...

C++中的析构函数

目录 一、什么是析构函数: 二、析构函数的特性: 一、什么是析构函数: C中的析构函数非常简单,它的功能无非是帮助我们自动归还堆区的空间给操作系统。当我们使用内存开辟函数(如malloc()、realloc())等&a…...

同步,异步,并发,并行

同步: 任务按顺序执行,必须等待前一个任务完成后才能开始下一个任务。 任务之间是强依赖的,通过直接调用或阻塞等待实现。 示例:读取文件时,代码会阻塞直到文件读取完成。 异步: 任务无需等待前一个任务完成即可启…...

种子填充(Floodfill、泛滥填充、洪水填充) 算法c++模板

种子填充(Floodfill) 算法: 从任意 W 开始,不停地把邻接的 W 用 . 代替。1 次 DFS 后与初始 W 连接的所有 W 都被替换成 . 了。 因此,直到图中不存在 W 为止,总共进行 DFS 的次数就是答案了。 问题: 有一个大小为 N x M 的园子,雨后积水。 8 连通的积水被认为是连接在…...