当前位置: 首页 > 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;是一种在分布式系统中用于进程间…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...