You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在内核模块中实现不同/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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 07:12:05