如何在内核模块中实现不同/proc入口读取返回不同自定义内容
解决方案
核心实现逻辑是通过proc文件创建接口的私有数据参数传递不同的输出内容标识,在read回调中读取标识区分输出,以下是修正后的完整实现:
关键修改点
- 修正内核API调用错误,当前标准proc创建/删除接口为
proc_create()/remove_proc_entry() - 使用
proc_create()的最后一个参数传递不同的输出字符串作为私有数据 - 在read回调中通过
PDE_DATA()宏获取对应proc入口的私有数据,输出对应内容 - 修复原有代码的语法、变量名拼写错误,去掉存在并发风险的静态
done变量,改用偏移量判断读取状态
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/proc_fs.h> #include <linux/uaccess.h> #define PROC_NAME1 "entry1" #define PROC_NAME2 "entry2" #define BUFFER_SIZE 1024 static const char *entry1_msg = "Hello World\n"; static const char *entry2_msg = "Goodbye World\n"; static ssize_t proc_read(struct file *, char __user *, size_t, loff_t *); static const struct file_operations fops = { .read = proc_read, .owner = THIS_MODULE, }; static int __init proc_init(void) { // 创建两个proc入口,分别传递对应的输出字符串作为私有数据 proc_create(PROC_NAME1, 0, NULL, &fops, (void *)entry1_msg); proc_create(PROC_NAME2, 0, NULL, &fops, (void *)entry2_msg); return 0; } static void __exit proc_exit(void) { remove_proc_entry(PROC_NAME1, NULL); remove_proc_entry(PROC_NAME2, NULL); } static ssize_t proc_read(struct file *file, char __user *usr_buf, size_t count, loff_t *pos) { // 获取当前proc入口对应的私有数据(就是创建时传入的字符串) const char *msg = PDE_DATA(file_inode(file)); int len = strlen(msg); // 如果偏移量已经超过字符串长度,说明读取完成,返回0结束读取 if (*pos >= len) return 0; // 拷贝字符串到用户空间 if (copy_to_user(usr_buf, msg, len)) return -EFAULT; // 更新偏移量,返回读取的字节数 *pos += len; return len; } module_init(proc_init); module_exit(proc_exit); MODULE_LICENSE("GPL");
测试效果
加载模块后执行对应命令即可得到预期输出:
cat /proc/entry1 # 输出:Hello World cat /proc/entry2 # 输出:Goodbye World
内容的提问来源于stack exchange,提问作者Amin
相关产品推荐
相关产品推荐

