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

Linux下的Debugfs

debugfs


1. 简介

类似sysfs、procfsdebugfs 也是一种内存文件系统。不过不同于sysfs一个kobject对应一个文件,procfs和进程相关的特性,debugfs的灵活度很大,可以根据需求对指定的变量进行导出并提供读写接口。debugfs又是一个Linux中 everything is a file 哲学的体现,通过VFS实现了对驱动的控制。可以通过以下命令,来挂载debugfs到指定目录。
Debugfs其存在的主要意义是为了内核开发者向用户空间传递更多有用的信息,与proc不同,proc只提供进程相关的信息;同时也与sysfs不同,sysfs对每个文件都要求一定的规则,而Debugfs没有任何的规则。
简而言之,Debugfs是一种用于内核调试的虚拟文件系统。
用途:将内核程序中的变量以文件的形式直观的展现出来,并可以直接通过文件操作来读取或修改内核变量的值,便于开发调试

2. 食用方式

1. 内核使能Debudfs

menuconfig中使能DEBUG_FS = y

在这里插入图片描述

2.挂载命令

mount -t debugfs none /sys/kernel/debug

3.内核接口

1. API接口

  • 想要使用Debugfs功能,首先要做的就是要包含 <linux/debugfs.h>头文件
  • 使用debugfs_create_dir接口,创建一个文件夹,用于保存debugfs所操作的文件
  • 使用debugfs_create_file接口,创建多个文件进行操作

2. API介绍

1. debugfs_create_dir

struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
参数作用备注
name文件夹名称
parent父目录如果为NULL,则在/sys/kernel/debug目录下
dentry返回值表示创建的 debugfs 文件(或目录)的 dentry 节点。如果文件创建成功,它返回一个有效的 dentry 指针;如果创建失败,则返回 NULL。

2. debugfs_create_file

struct dentry *debugfs_create_file(const char *name, umode_t mode,struct dentry *parent, void *data,const struct file_operations *fops);
参数作用备注
name文件名称
mode文件访问权限可以是整型(比如0644)也可以使用内核的宏
parent父目录,用于保存该文件如果为空则该文件的父目录为根目录
data文件操作的私有数据inode的i_private字段指向这个结构
fops文件的自定义操作可以自定义所有操作接口,也可以使用宏DEFINE_SIMPLE_ATTRIBUTE指定读写操作即可

DEFINE_SIMPLE_ATTRIBUTE宏

// 
// __get: 读操作 int (*get)(void *data, u64 *value),👇
//bash下cat file ,回显内容便是内核层传给应用层的*value的值
// __set: 写操作 int (*set)(void *data, u64 value),👇
//bahs下echo 1 > file , value的值便是应用层传入内核层的数据1
// __fmt: 用于指定 get 和 set 函数的输入输出格式。 const char *fmt👇
//例如,它可以定义一个整数、浮点数或字符串的格式,以便在 sysfs 读写操作接口中正确显示或解析值。
#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)		\
static int __fops ## _open(struct inode *inode, struct file *file)	\
{									\__simple_attr_check_format(__fmt, 0ull);			\return simple_attr_open(inode, file, __get, __set, __fmt);	\
}									\

3. debugfs_create_u8

void debugfs_create_u8(const char *name, umode_t mode,struct dentry *parent, u8 *value);
参数作用备注
name文件名一般以变量名来命名,方便调试
mode文件权限
parent父目录
value变量变量的值会被存在文件内

其他变量类型的接口:👇

//创建十进制的无符号文件
void debugfs_create_u8(const char *name, umode_t mode,struct dentry *parent, u8 *value);
void debugfs_create_u16(const char *name, umode_t mode,struct dentry *parent, u16 *value);
void debugfs_create_u32(const char *name, umode_t mode,struct dentry *parent, u32 *value);
void debugfs_create_u64(const char *name, umode_t mode,struct dentry *parent, u64 *value);
//创建十六进制的无符号文件
void debugfs_create_x8(const char *name, umode_t mode,struct dentry *parent, u8 *value);
void debugfs_create_x16(const char *name, umode_t mode,struct dentry *parent, u16 *value);
void debugfs_create_x32(const char *name, umode_t mode,struct dentry *parent, u32 *value);
void debugfs_create_x64(const char *name, umode_t mode,struct dentry *parent, u64 *value);//创建一个size_t类型的文件
void debugfs_create_size_t(const char *name, umode_t mode,struct dentry *parent, size_t *value);
//创建一个unsigned long类型的文件
struct dentry *debugfs_create_ulong(const char *name, umode_t mode,struct dentry *parent,unsigned long *value);
//创建一个十六进制的unsigned long类型的文件
void debugfs_create_xul(const char *name, umode_t mode,struct dentry *parent, unsigned long *value);
// 布尔型
void debugfs_create_bool(const char *name, umode_t mode,struct dentry *parent, bool *value);

Deme one

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>static struct dentry *dir = NULL;static unsigned int debugfs_hello;static u32 sum = 0;static int add_write(void *data, u64 value)
{sum += value;return 0;
}
// 文件操作变量名,get读操作,set写操作,将读写操作的返回值以字符串格式化的形式读出或写入文件内部
DEFINE_SIMPLE_ATTRIBUTE(add_ops, NULL, add_write, "%llu\n");static __init int hello_init(void)
{struct dentry *tmp_dir = NULL;/* create /sys/kernel/debug/debugfs_hello/ directory */dir = debugfs_create_dir("debugfs_hello", NULL);if (!dir) {printk(KERN_ALERT "debugfs_create_dir failed\n");return -1;}/* create /sys/kernel/debug/debugfs_hello/hello value, mode: rw*/tmp_dir = debugfs_create_u32("hello", 00666, dir, &debugfs_hello);if (!tmp_dir) {printk(KERN_ALERT "debugfs_create_u32 failed\n");return -1;}/* create /sys/kernel/debug/debugfs_hello/add value, mode: w*/tmp_dir = debugfs_create_file("add", 0222, dir, NULL, &add_ops);if (!tmp_dir) {printk(KERN_ALERT "debugfs_create_file failed\n");return -1;}/* create /sys/kernel/debug/debugfs_hello/sum value, mode: r*/tmp_dir = debugfs_create_u32("sum", 0444, dir, &sum);if (!tmp_dir) {printk(KERN_ALERT "debugfs_create_u32 failed\n");return -1;}return 0;
}static void __exit hello_exit(void)
{printk(KERN_INFO "Exit debugfs_hello module\n");debugfs_remove_recursive(dir);dir = NULL;
}module_init(hello_init);
module_exit(hello_exit);MODULE_LICENSE("GPL");

Demo TWO

#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/errno.h>
#include <linux/dcache.h>
#include <linux/types.h>static char zen_buf[512] = "hello\n";
static struct dentry *zen_dir;static int zen_open(struct inode *inode, struct file *filp)
{printk("zen open\n");filp->private_data = inode->i_private;return 0;
}ssize_t zen_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
{int retval = 0;if ((*offp + count) > 512)count = 512 - *offp;printk("read request: count:%u, offset:%u\n", count, *offp);if (copy_to_user(buf, zen_buf+*offp, count)) {printk("copy to user failed, count:%ld\n", count);retval = -EFAULT;goto out;}*offp += count;retval = count;
out:return retval;
}ssize_t zen_write(struct file *filp, const char __user *buff, size_t count, loff_t *offp)
{int retval;printk("write request: count:%u, offset:%u\n", count, *offp);if (*offp > 512)return 0;if (*offp + count > 512)count = 512 - *offp;if (copy_from_user(zen_buf+*offp, buff, count)) {printk("copy from user failed, count:%ld\n", count);retval = -EFAULT;goto out;}*offp += count;retval = count;
out:return retval;
}struct file_operations my_fops = {.owner = THIS_MODULE,.read = zen_read,.write = zen_write,.open = zen_open,
};static int __init debugfs_init(void)
{printk("INIT MODULE\n");zen_dir = debugfs_create_dir("zen_dir4", NULL);if (!zen_dir) {printk("zen_dir4 is null\n");goto fail;}static struct dentry *sub_zen_dir;sub_zen_dir = debugfs_create_dir("sub_zen", zen_dir);if (!sub_zen_dir) {printk("sub zen dir is null\n");goto fail;}struct dentry *filent = debugfs_create_file("zen", 0644, sub_zen_dir, NULL, &my_fops);if (!filent) {printk("zen file is null\n");goto fail;}printk("INIT SUCCESS\n");return 0;
fail:
//return -ENOENT;return -1;
}static void __exit debugfs_exit(void)
{printk("exit module\n");debugfs_remove_recursive(zen_dir);printk("exit success\n");
}module_init(debugfs_init);
module_exit(debugfs_exit);
MODULE_LICENSE("GPL");

4. 加载模块

编译完后生成的.ko文件,使用insmod加载进内核,即可在/sys/kernel/debug下看到生成目录及文件

相关文章:

Linux下的Debugfs

debugfs 1. 简介 类似sysfs、procfs&#xff0c;debugfs 也是一种内存文件系统。不过不同于sysfs一个kobject对应一个文件&#xff0c;procfs和进程相关的特性&#xff0c;debugfs的灵活度很大&#xff0c;可以根据需求对指定的变量进行导出并提供读写接口。debugfs又是一个Li…...

【FFmpeg】调整音频文件的音量

1、调整音量的命令 1)音量调整为当前音量的十倍 ffmpeg -i inputfile -vol 1000 outputfile 2)音量调整为当前音量的一半 ffmpeg -i input.wav -filter:a "volume=0.5" output.wav3)静音 ffmpeg -i input.wav -filter:a "volume=0" output.wav4)…...

mac 打开访达快捷键

一、使用快捷键组合 1. Command N 在当前桌面或应用程序窗口中&#xff0c;按下“Command N”组合键可以快速打开一个新的访达窗口。这就像在 Windows 系统中通过“Ctrl N”打开新的资源管理器窗口一样。 2. Command Tab 切换 如果访达已经打开&#xff0c;只是被其他应…...

Ubuntu学习笔记 - Day2

文章目录 学习目标&#xff1a;学习内容&#xff1a;学习笔记&#xff1a;Linux系统启动过程内核引导运行init运行级别系统初始化建立终端用户登录系统 Ubuntu关机关机流程相关命令 Linux系统目录结构查看目录目录结构 文件基本属性读写权限命令 下载文件的方法安装wget工具下载…...

c++基础12比较/逻辑运算符

比较/逻辑运算符 布尔比较运算符逻辑运算符位运算符&#xff08;也用于逻辑运算&#xff09;1<a<10怎么表达T140399判断是否为两位数代码 布尔 在C中&#xff0c;布尔类型是一种基本数据类型&#xff0c;用于表示逻辑值&#xff0c;即真&#xff08;true&#xff09;或假…...

mac-ubuntu虚拟机(扩容-共享-vmtools)

一、磁盘扩容 使用GParted工具对Linux磁盘空间进行扩展 https://blog.csdn.net/Time_Waxk/article/details/105675468 经过上面的方式后还不够&#xff0c;需要再进行下面的操作 lvextend 用于扩展逻辑卷的大小&#xff0c;-l 选项允许指定大小。resize2fs 用于调整文件系统的…...

数学建模学习(135):使用Python基于WSM、WPM、WASPAS的多准则决策分析

1. 算法介绍 多标准决策分析(Multi-Criteria Decision Analysis, MCDA)是帮助决策者在复杂环境下做出合理选择的重要工具。WSM(加权和法)、WPM(加权乘积法)、WASPAS(加权和乘积评估法)是 MCDA 中的三种常用算法。它们广泛应用于工程、经济、供应链管理等多个领域,用于…...

VScode的C/C++点击转到定义,不是跳转定义而是跳转声明怎么办?(内附详细做法)

以最简单的以原子的跑马灯为例&#xff1a; 1、点击CtrlShiftP&#xff0c;输入setting&#xff0c;然后回车 2、输入Browse 3、点击下面C_Cpp > Default > Browse:Path里面添加你的工程路径 然后就可以愉快地跳转定义啦~ 希望对你有帮助&#xff0c;如果还不可以的话&a…...

设备管理网关(golang版本)

硬件设备&#xff1a;移远EC200A-CN LTE Cat 4 无线通信模块 操作系统&#xff1a;openwrt 技术选型&#xff1a;layui golang sqlite websocket 工程结构 界面展示 区域管理 设备管理 运行监控 系统参数 资源文件 版本信息...

Armv8的安全启动

目录 1. Trust Firmware 2. TF-A启动流程 3. TF-M启动流程 3.1 BL1 3.2 BL2 4.小结 在之前汽车信息安全 -- 再谈车规MCU的安全启动文章里&#xff0c;我们详细描述了TC3xx 、RH850、NXPS32K3的安全启动流程&#xff0c;而在车控类ECU中&#xff0c;我们也基本按照这个流程…...

冒泡排序、选择排序、计数排序、插入排序、快速排序、堆排序、归并排序JAVA实现

常见排序算法实现 冒泡排序、选择排序、计数排序、插入排序、快速排序、堆排序、归并排序JAVA实现 文章目录 常见排序算法实现冒泡排序选择排序计数排序插入排序快速排序堆排序归并排序 冒泡排序 冒泡排序算法&#xff0c;对给定的整数数组进行升序排序。冒泡排序是一种简单…...

SQL CASE表达式与窗口函数

CASE 表达式是一种通用的条件表达式&#xff0c;类似于其他编程语言中的if/else语句。 窗口函数类似于group by&#xff0c;但是不会改变记录行数&#xff0c;能扫描所有行&#xff0c;能对每一行执行聚合计算或其他复杂计算&#xff0c;并把结果填到每一行中。 1 CASE 表达式…...

基于SpringBoot的植物园管理小程序【附源码】

基于SpringBoot的植物园管理小程序 效果如下&#xff1a; 系统登录页面 管理员主页面 商品订单管理页面 植物园信息管理页面 小程序主页面 小程序登录页面 植物信息查询推荐页面 研究背景 随着互联网技术的快速发展和移动设备的普及&#xff0c;线上管理已经成为各行各业提高…...

asp.net网站项目如何设置定时器,定时获取数据

在 Global.asax.cs 文件中编写代码来初始化和启动定时器。Global.asax.cs 文件定义了应用程序全局事件&#xff0c;比如应用程序的启动和结束。在这里&#xff0c;我们将在应用程序启动时初始化和启动定时器。 using System; using System.Timers;public class Global : Syste…...

单元/集成测试解决方案

在项目开发的前期针对软件单元/模块功能开展单元/集成测试&#xff0c;可以尽早地发现软件Bug&#xff0c;避免将Bug带入系统测试阶段&#xff0c;有效地降低HIL测试的测试周期&#xff0c;也能有效降低开发成本。单元/集成测试旨在证明被测软件实现其单元/架构设计规范、证明被…...

高效作业跟踪:SpringBoot作业管理系统

1 绪论 1.1 研究背景 现在大家正处于互联网加的时代&#xff0c;这个时代它就是一个信息内容无比丰富&#xff0c;信息处理与管理变得越加高效的网络化的时代&#xff0c;这个时代让大家的生活不仅变得更加地便利化&#xff0c;也让时间变得更加地宝贵化&#xff0c;因为每天的…...

keepalived + nginx 实现网站高可用性(HA)

keepalive 一、keepalive简介二、实现步骤1. 环境准备2. 安装 Keepalived3. 配置 Keepalived 双机主备集群架构4. 配置 Nginx5. 启动Keepalived6. 测试高可用性7. 配置keepalived 双主热备集群架构 三、虚拟ip 一、keepalive简介 目前互联网主流的实现WEB网站及数据库服务高可用…...

有哪些编辑器,怎样选择编辑器

1. Visual Studio Code (VSCode) 特点&#xff1a; 轻量级且强大&#xff1a;启动速度快&#xff0c;占用资源少&#xff0c;但功能强大。跨平台&#xff1a;支持 Windows、macOS 和 Linux。丰富的扩展生态&#xff1a;拥有庞大的扩展市场&#xff0c;可以安装各种插件来扩展功…...

软件系统开发

目录 软件开发方法 软件开发生命周期 软件开发模型 敏捷方法 敏捷型方法两个特点 敏捷方法的核心思想三点 4个核心价值观 主要敏捷方法 RUP RUP的核心特点&#xff1a; RUP软件开发生命周期 9个核心工作流 RUP裁剪 软件系统工具 软件开发工具 需求分析工具 设计…...

浅谈RPC的实现原理与RPC实战

浅谈RPC的实现原理与RPC实战 什么是RPC?RPC框架基本原理gRPC框架介绍Http/2ProtoBuf gRPC实战一、创建项目二、导入依赖三、编写proto文件编写服务端编写客户端 什么是RPC? RPC(Remote Procedore Call)&#xff0c;及远程过程调用&#xff0c;是一种在分布式系统中用于进程间…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中&#xff0c;如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议&#xff08;2PC&#xff09;通过准备阶段与提交阶段的协调机制&#xff0c;以同步决策模式确保事务原子性。其改进版本三阶段提交协议&#xff08;3PC&#xf…...

基于 HTTP 的单向流式通信协议SSE详解

SSE&#xff08;Server-Sent Events&#xff09;详解 &#x1f9e0; 什么是 SSE&#xff1f; SSE&#xff08;Server-Sent Events&#xff09; 是 HTML5 标准中定义的一种通信机制&#xff0c;它允许服务器主动将事件推送给客户端&#xff08;浏览器&#xff09;。与传统的 H…...

理想汽车5月交付40856辆,同比增长16.7%

6月1日&#xff0c;理想汽车官方宣布&#xff0c;5月交付新车40856辆&#xff0c;同比增长16.7%。截至2025年5月31日&#xff0c;理想汽车历史累计交付量为1301531辆。 官方表示&#xff0c;理想L系列智能焕新版在5月正式发布&#xff0c;全系产品力有显著的提升&#xff0c;每…...