JJJ:linux sysfs相关

Linux Swap 子系统:架构、内存管理与虚拟化 Swap Linux Swap机制通过将不活跃内存页移至磁盘或压缩内存,扩展系统有效内存容量,缓解内存压力。传统架构中,逻辑Swap槽与物理存储绑定,导致资源浪费,尤其在使用Zswap等压缩技术时。为此,Vswap与Xswap提出虚拟化方案:前者以XArray实现灵活映射,支持多后端迁移;后者采用稀疏映射,简化管理但容量固定。二者在架构设计、资源记账与动态扩展上各有权衡,反映了内核开发中对性能、可维护性与灵活性的深层考量。 阅读详情

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.h
 625 #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 作为入参是NULL
 807         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_ALLOC
 34     bool            ignore_lockdep:1;
 35     struct lock_class_key   *key;
 36     struct lock_class_key   skey;
 37 #endif
 38 };
 
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 也是类似的流程


bus_type实例的const struct attribute_group **dev_groups;成员也会定义一个属性组,该bus下的kobj在注册到sysfs时,默认会创建这些属性对应的属性文件
device_add -》 bus_add_device -》 device_add_groups -》 sysfs_create_groups -》sysfs_create_group

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所指示的目录下

IntelliJ IDEA 2025.1 + Gradle 镜像配置避坑指南:解决依赖下载慢的终极方案 本文针对IntelliJ IDEA 2025.1开发环境中Gradle依赖下载缓慢的问题,提供了详细的镜像配置避坑指南。通过解析Gradle依赖解析机制,重点指导如何正确配置阿里云等国内镜像仓库,并分享验证配置生效、排查常见错误及高级优化技巧,旨在彻底解决依赖下载难题,提升开发效率。 阅读详情

相关推荐

openEuler 欧拉 安装Oracle19c数据库RPM包安装

欧拉系统安装部署oracle 19c rpm方式

陈苏漾的IT生涯 6890

JJJ:linux内核传参、解析流程

文章目录1 module_param_cb1.1 待解析内容:1.2 涉及到的相关定义:1.3 涉及到的通用定义1.4 基于1.1的展开流程2 module_param3、推荐(详细的参数解析流程) 1 module_param_cb 1.1 待解析内容: // block/genhd.c module_param_cb(events_dfl_poll_msecs, &disk_events_dfl_poll_msecs_param_ops, &disk_events_d

engineer0的博客 779

从零开始:手把手教你设计DP接口电路(含原理图实战)

本文是一份详尽的DisplayPort接口电路设计实战指南。文章从DP接口的核心架构与HDMI的差异讲起,手把手解析了高速差分对、AUX辅助通道、热插拔检测等关键模块的原理图设计要点,并提供了一个完整的DP Source端原理图实例,最后总结了PCB布局与信号完整性的核心考量,旨在帮助硬件工程师高效、稳定地完成DP接口电路设计。

transformer2023的博客 730

理解 Linux 动态库加载:LD_LIBRARY_PATH

flyfish

二分掌柜的 318

RPA实战:手把手教你打造抖音自动养号机器人(含避坑指南)

本文详细介绍了如何利用RPA技术从零构建一个智能化的抖音自动养号机器人。内容涵盖环境准备、核心工具选型、拟人化行为流程设计、代码实现模块拆解,并提供了关键的避坑指南与风控对抗策略,帮助开发者高效、稳定地实现账号自动化运营。

orange的博客 556

桁架 拓扑优化 matlab程序_拓扑优化在结构轻量化及板壳加筋肋最优布置的应用...

1 拓扑优化简介材料的有效利用一直都是人类追求的目标,也是许多研究领域不变的话题,并伴随着结构优化理论和方法的产生而发展。结构优化设计通常分为三个层次:(1)拓扑优化:在一个确定的连续区域内寻求结构内部非实体区域位置和数量的最佳配置,寻求结构中的构件布局及节点联结方式最优化,使结构能在满足应力、位移等约束条件下,将外载荷传递到结构支撑位置,同时使结构的某种性态指标达到最优;(2)形状优化:指在保持...

weixin_39525355的博客 1876

Linux 磁盘满了怎么排查?df / du / find 三步定位大文件

Linux 磁盘满排查三步法:df -h 定位分区、du 逐层下钻、find 按大小和时间抓大文件,附 inode 耗尽、文件已删未释放、du 与 df 不一致等经典坑的解决方案。

weixin_38291577的博客 213

基于STM32F4XX 、HAL库的SHT40-CD1B-R3温湿度传感器驱动应用C语言程序设计

define SHT40_ADDR_READ 0x8B // CD1B 读地址 ((0x45 << 1) + 1)#define SHT40_ADDR_WRITE 0x8A // CD1B 写地址 (0x45 << 1)// 初始化 I2C1 (根据 CubeMX 生成的函数)// 湿度: -6%RH + 125%RH * (raw / 2^16)// 温度: -45°C + 175°C * (raw / 2^16)// 返回值: 0=成功, 1=失败(CRC错误或I2C通信错误)

PP_Cottage的博客 234

Linux-iostat命令详解

Linux命令学习记录

m0xin的博客 81

[Dify] -进阶13- 使用“知识库 + 工作流”打造智能推荐系统

本文介绍了在Dify平台上构建智能推荐系统的方法,重点阐述了知识库与工作流技术的结合应用。通过知识库管理RAG流程,实现文档上传、向量嵌入和检索优化;利用工作流设计节点化推荐逻辑,支持并行处理与条件分支。以电话销售话术推荐为例,展示了从数据收集到实时生成的完整流程。该方法具有准确性高、扩展性强、维护简便等优势,可广泛应用于各类推荐场景,实现从数据存储到智能推荐的闭环解决方案。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 1065

DiffusionDriveV2 (1) : 端到端自动驾驶中受强化学习约束的截断扩散建模

DiffusionDriveV2:强化学习约束的截断扩散模型在端到端自动驾驶中的应用 本文针对端到端自动驾驶中扩散模型面临的模式崩溃问题,提出DiffusionDriveV2框架。该方法通过引入强化学习约束,解决了DiffusionDrive依赖模仿学习导致的多样性与持续高质量之间的困境。主要创新包括: 采用尺度自适应乘法噪声促进广泛探索 提出锚点内GRPO管理单个锚点样本间的优势估计 设计锚点间截断GRPO整合全局视角,避免不同驾驶意图间的不当比较 实验表明,该方法在NAVSIM基准测试中达到最先进水平(

@bangbang的博客 380

【Linux】APT 本地 deb 安装与 `-f` 参数总结笔记

apt install ./xx.deb 可自动解析并安装依赖,无需 -f;-f 仅用于修复已损坏的依赖状态,非首次安装时必需。apt install -f 可单独运行,修复 broken dependencies。两者职责不同:前者是安装与依赖解决,后者是故障修复。完全离线时需提前准备依赖包或本地源。

hknaruto的专栏 205

硬核实战!Python爬虫从0到1完整版:爬取知乎热榜+回答内容(数据去重+Excel一键导出+避坑指南,零基础友好)

✔️ 适用人群:Python爬虫零基础、想练手实战爬虫、需要爬取知乎内容做数据分析、办公/学习素材整理的同学爬取知乎热榜全量数据(排名+标题+热榜链接+热度值) →自动跟进爬取每个热榜问题的回答内容(回答者昵称+赞同数+评论数+回答正文+发布时间) →数据清洗+智能去重→一键导出格式化Excel文件,所有功能一站式完成入门级难度,无复杂反爬破解、无分布式/代理池,纯requests请求+静态解析,新手能看懂、能运行、能修改;爬取速度快,热榜+回答全程仅需几十秒。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1459

Linux 服务器性能排查手册(2026):CPU、内存、磁盘IO、网络四大瓶颈定位

iptables 四表五链模型、firewalld zone 信任级别、云安全组与主机防火墙的关系与优先级,避坑改了防火墙把自己挡在服务器外面的翻车事故。

2502_91473995的博客 281

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Linux rm 误删文件恢复实操教程

Linux使用rm删除文件时,并不会直接抹除磁盘上的数据,只是移除文件索引,让系统不再识别这块空间。只要没有写入新数据,原有扇区内容就会保留。新文件写入才有可能覆盖这些区域,一旦覆盖就很难找回。恢复的本质就是扫描磁盘,找到这些还存在、但索引丢失的数据条目,再把它们导出保存到其他分区。越早停止写入,恢复成功的概率越高。

海天数据恢复-winhex数据恢复教程 199

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Linux sudo

如果输出 → 无 sudo 权限 如果输出 → 拥有全部 sudo 权限 辅助验证命令 ⚠️ 注意:在 wheel 组 ≠ 一定能 sudo,必须 开启 Ubuntu/Debian: ✅ 重要:修改组之后,用户要重新登录才生效! 或者执行 临时生效 看到这行(没有 #注释)才生效: 方式 2:visudo 直接单独给用户授权(精细化权限) 找到 ,下面添加一行: 自带语法校验,写错会告警,不要直接 vim 改 ,写错直接 sudo 炸掉! 想免密 su

fengliyang_的博客 176

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Windows/Linux下强实时运动控制内核(二):基于Qt的Delta机械手的开发应用

强实时运动控制内核MotionRT750下Qt开发Delta机械手的完整开发流程。

weixin_57350300的博客 238

Linux 磁盘 100% 但 du 查不出东西,五种情况逐个排

监控告警说根分区 100%,登录上去 du -sh /* 加起来只有 12GB,df 显示 40GB 已用。差了快 30GB,du 找不到任何东西。这种情况基本都是"文件被删了但进程还开着",但也可能是别的原因。这篇按可能性排一下顺序。

2408_89646393的博客 160

【Linux 网络编程】DNS 与 ICMP:从域名解析到 ping、traceroute,把“网络通不通”问清楚

DNS 让名字与网络资源建立联系,ICMP 让部分网络状态有机会被看见。真正排查问题时,我们需要的不是一条万能命令,而是把每次观测放回它对应的层次。看到一个 DNS 结果,先问“谁回答的、什么类型、缓存多久”;看到一次 ping 回复,先问“哪个地址、哪个方向、证明了哪一次往返”;看到一份 traceroute,先问“用了什么探测、哪些节点回应、星号还有哪些解释”。当这些问题能被分别回答,“网络通不通”就不再是一个模糊判断,而会变成一条可以逐步验证的分析路径。

星光编译者的技术博客,专注 C/C++、Linux、数据结构与算法。 490

Linux、Shell、MySQL 测试卷逐题细讲(下篇:MySQL)

本文为Linux、Shell、MySQL测试卷下半段MySQL部分逐题讲解,包含填空、选择与SQL分析三类题型。填空题覆盖COUNT、HAVING、DISTINCT、事务、约束、索引等核心语法;选择题辨析存储过程、索引类型、ACID、存储引擎、用户管理等考点。SQL大题围绕员工、部门、职位、地点四张关联表,考察多表连接、分组聚合、自连接、相关子查询、NULL处理等高频写法,标注LEFT JOIN统计计数、NULL判断、子查询别名等易错坑点,同时梳理试卷OCR识别带来的干扰问题,重点提示SQL实操中的常见失误

dongziwen1的博客 179

Linux 网络基础详解:IP、子网、路由与 ip、ss 命令实战

建库建表、增删改查、连接查询(内连左连右连)、聚合函数、权限控制 GRANT/REVOKE,每条命令配可运行示例,零基础也能跟着敲会 SQL 基础。

2502_91473995的博客 606

Linux 下 OpenCode 接入自定义大模型 API 教程:以 DeepSeek-V4.1-Flash-1017 为例

本文介绍在Linux下通过Python脚本配置OpenCode接入自定义大模型API(以DeepSeek-V4.1-Flash-1017为例),实现永久化、非侵入式配置。通过修改~/.config/opencode/opencode.json文件,添加OpenAI兼容服务商BLSC,注册模型并设置APIKey。支持命令行测试、默认模型设定及安全权限控制,操作简单且不影响原有配置。适用于各类支持OpenAI接口的自定义模型服务,提升开发灵活性与安全性。

qq_15060477的博客 117

【Linux 命令实战(02):文件与目录操作,掌握 pwd、ls、cd 三个核心命令】

命令作用cd /进入根目录cd ~进入当前用户家目录cd返回当前用户家目录cd …返回上一级目录cd …/…返回上两级目录cd -返回上一次所在目录进入指定目录命令核心用途常用参数pwd查看当前目录-L、-Pls查看文件和目录cd切换目录…、~、-Linux 文件系统的基本结构。绝对路径与相对路径的区别。Tab 自动补全。Shell 通配符。使用&&组合命令。这篇文章主要解决的是如何在 Linux 文件系统中快速定位目录。

一些微不足道的见解、希望能帮助各位 184

Linux Day29——HTTP与网络排障

*实测**:`traceroute -n -m 8 8.8.8.8` 的输出:第 1 跳 `172.17.144.1`(本机网关)、第 2 跳 `10.32.0.1`、第 3 跳 `10.50.255.253`、第 4 跳 `* * *`、第 5 跳 `221.226.71.193`、第 6 跳 `* * *`、第 7、8 跳有地址但夹着星号。`ping` 和 `traceroute` 都靠它。**实测**:`ss -lta` 看到三行 `domain`,加 `-n` 后变成 `53`。

2503_94114317的博客 147

【Linux指南】进程通信系列(七):System V 信号量 —— 同步互斥的内核原语

System V 三兄弟的压轴成员 —— 信号量(Semaphore) —— 是最特别的一位:它根本不传数据。消息队列传消息、共享内存传字节,信号量只干一件事:当保镖。

倔强的石头的博客 4245

Linux-IPC进程间通信

进程间通信(IPC)因进程空间独立但需数据共享而必要。主要方式包括:管道(无名/有名,基于队列)、信号(异步通知)、消息队列、共享内存(高效读写,需配合信号量同步)及Socket(网络通信)。无名管道用于亲缘进程,有名管道支持任意单机进程;共享内存提供高速共享,但需同步机制避免冲突。各类IPC各有特性,适用于不同场景。

2401_86256335的博客 159
上一篇: JJJ:fread返回值分析
下一篇: JJJ:amixer指令简介
你板子冒烟了
博客等级 码龄8年 1278粉丝 582原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值