Coding: 小写一个debugfs
扫描二维码随身看资讯
使用手机 二维码应用 扫描右侧二维码,您可以
1. 在手机上细细品读~
2. 分享给您的微信好友或朋友圈~
上一个月我写了一个简单的module,熟悉了module的挂载、查看和卸载。这一次我们将使用linux的debugfs API编写一个调试文件系统。
底层的API已经全部编写好了,我们只需要简单地调用API即可完成。
事先检查
首先检查当前的内核是否支持debugfs调试:
zcat /proc/config.gz | grep DEBUG_FS
# CONFIG_XEN_DEBUG_FS is not set
CONFIG_BLK_DEBUG_FS=y
CONFIG_BLK_DEBUG_FS_ZONED=y
# CONFIG_SCSI_SNIC_DEBUG_FS is not set
# CONFIG_SCSI_LPFC_DEBUG_FS is not set
# CONFIG_USB_GADGET_DEBUG_FS is not set
# CONFIG_OCFS2_DEBUG_FS is not set
CONFIG_DEBUG_FS=y
CONFIG_DEBUG_FS_ALLOW_ALL=y
# CONFIG_DEBUG_FS_DISalloW_MOUNT is not set
# CONFIG_DEBUG_FS_ALLOW_NONE is not set
在这里,我们需要查看的是:
CONFIG_DEBUG_FS=y
, 如果是n,说明当前内核不支持调试文件系统,需要自定义内核。如果需要帮助,可以阅读之前我写的博客,在Arch Linux上编写自定义内核模块。
开始
文件系统有自己一套fops。与我们对文件系统的理解一样,文件系统提供了对设备的一套抽象访问读写等操作的句柄。因此,我们需要实现这些基本操作,如打开文件、读文件和写文件。
文件系统将以模块的方式动态加载到内核中。所以我们需要首先学习如何编写模块,并掌握相关知识。如果您之前不熟悉这方面的知识,可以阅读我之前的博客,先掌握这些内容,然后进行实践。
现在,让我们继续编写模块的Makefile:
obj-m:= charlie.o
pwd:= $(shell pwd)
ker-ver:= $(shell uname -r)
KDIR:= /lib/modules/$(ker-ver)/build
all:
make -C $(KDIR) M=$(pwd) modules
clean:
rm -rf *.o .* .cmd *.ko *.mod.c .tmp_versions *.order *.symvers *.mod写代码!
撸代码
我们首先需要引入写模块和调试文件系统的基本头文件。
#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/errno.h>
#include <linux/types.h>
然后完成读写操作和打开文件的基本操作。
static int charlie_fs_open(struct inode* inode, struct file* pfile)
{
printk("Charlie_filesystem_open\n");
pfile->private_data = inode->i_private;
return 0;
}
static sSize_t charlie_fs_read(struct file* pFile, char __user *buf, size_t cnt, loff_t* offp)
{
int retval = 0;
if((*offp + cnt) > 512)
cnt = 512 - *offp;
printk("Received read request! count:%ld, offset:%lld\n", cnt, *offp);
if(copy_to_user(buf, charlie_buf + *offp, cnt)){
pr_warn("Oh no, failed to copy to user! count is %ld\n", cnt);
retval = -EFAULT;
goto out;
}
*offp += cnt;
retval = cnt;
out:
return retval;
}
static ssize_t charlie_fs_write(struct file* pFile, const char __user *buf, size_t cnt, loff_t* offp)
{
int retval;
pr_info("Write request is here: count: %ld, offset:%lld\n", cnt, *offp);
if(*offp > 512)
return 0;
if((*offp + cnt) > 512)
cnt = 512 - *offp;
if(copy_from_user(charlie_buf + *offp, (const void*)buf, cnt)){
pr_warn("Oh no, failed to copy from user! count is %ld\n", cnt);
retval = -EFAULT;
goto out;
}
*offp += cnt;
retval = cnt;
out:
return retval;
}
关于这里使用的函数的详细说明,可以自行查找更多信息。
文件系统是通过模块进行载入和卸载的,这意味着我们需要编写初始化函数和析构函数。我们需要在初始化时完成文件系统处理函数的注册,并在卸载文件系统时移除在初始化时注册的相关函数。
struct file_operations charlie_fs_fops = {
.owner = THIS_MODULE,
.read = charlie_fs_read,
.write = charlie_fs_write,
.open = charlie_fs_open
};
static int __init charlie_debug_fs_init(void)
{
pr_info("The module is initing...");
charlie_dir = debugfs_create_dir("Charliedir", NULL);
if(!charlie_dir){
pr_crit("Failing shit! can not create any dir at all!");
goto failed;
}
static struct dentry* sub_charlie_dir;
sub_charlie_dir = debugfs_create_dir("CharlieSubDir", charlie_dir);
if(!sub_charlie_dir){
pr_crit("Failing shit! can not create any sub dir at all!");
goto failed;
}
struct dentry* filent = debugfs_create_file("Charlie", 0644, sub_charlie_dir, NULL, &charlie_fs_fops);
if(!filent){
pr_err("Can not create file!");
goto failed;
}
pr_info("Init finish!");
return 0;
failed:
return -ENOENT;
}
static void __exit charlie_debug_fs_exit(void)
{
pr_info("Safe quit! begin");
debugfs_remove_recursive(charlie_dir);
pr_info("Safe quit! end");
}
module_init(charlie_debug_fs_init);
module_exit(charlie_debug_fs_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Charliechen");
保存并进行编译命令:
make -C /lib/modules/6.9.7-arch1-1/build M=/home/Charliechen/Works/opearte_system/module/test2 modules
sudo insmod charlie.ko && lsmod | grep charlie
模块正确挂载后,下一步是测试我们编写的功能。
sudo ls /sys/kernel/debug/ | grep Charliedir
sudo ls /sys/kernel/debug/Charliedir
sudo ls /sys/kernel/debug/Charliedir/CharlieSubDir
sudo echo 114514 > /sys/kernel/debug/Charliedir/CharlieSubDir/Charlie
测试过程已经完成。
- 欢喜大冒险物语 最新版
- 三角洲行动 下载入口
- Rotaeno旋转音律官方版下载 v2.0.1 安卓版
- zoom会议
- 驯龙物语GM版下载 v24.0 安卓版
- 萌翻天消消乐官方正版下载 v4.3.63 安卓版
- 剑侠传奇免内购版下载 v2.6 安卓版
- 正统三国充值返利VIP版下载 v1.12.30 安卓版
- 异世界三国志
- 传奇塔防中文内购破解下载 v3.2.10 安卓版
- 黎歌传奇3D
- 健身俱乐部大亨无限金币版下载 v1.6.9 安卓版
- 末日血战内购破解版有所有英雄无限钻石免费 v1.11.101 安卓版
- 怒焰三国杀小七版下载 v3.7.2 安卓版
- 图解CPU的实模式与保护模式
- DVT:华为提出动态级联Vision Transformer,性能杠杠的 | NeurIPS 2021
- 比特币交易流程详解
- PaddleNLP UIE -- 药品说明书信息抽取(名称、规格、用法、用量)
- 我对《RAG/大模型/非结构化数据知识库类产品》技术架构的思考、杂谈
- Python中引用不确定的函数详解及示例
- 深度解读昇腾CANN多流并行技术,提高硬件资源利用率
- 微信号id名字大全
- 如何找到自己感兴趣的开源项目
- C#/.NET/.NET Core优秀项目和框架2024年6月简报
- 如何在本地测试中进行虚假权限验证
- [python] Python日志记录库loguru使用指北
- 1
加查之花 正版
- 2
爪女孩 最新版
- 3
捕鱼大世界 无限金币版
- 4
企鹅岛 官方正版中文版
- 5
内蒙打大a真人版
- 6
烦人的村民 手机版
- 7
跳跃之王手游
- 8
球球英雄 手游
- 9
情商天花板 2024最新版
- 10
旅行串串 免费下载