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

Linux内核模块:如何让/proc文件返回整数而非ASCII字符

关于/proc模块返回ASCII字符而非数字的问题分析与解决

我是C语言与内核编程新手,编写了一个创建/proc/test_file的Linux内核模块。执行cat /proc/test_file时,期望返回变量my_number的整数值42,但实际返回ASCII字符*(十进制ASCII值为42)。以下是初始代码和修改后的可行代码,分析问题原因及修正方法如下:

问题原因分析

  • 直接拷贝二进制数据的错误:初始代码中通过copy_to_user直接将int类型变量my_number的二进制内存内容拷贝到用户空间。my_number=42作为32位int存储的二进制值是0x0000002A,用户空间的cat工具会把这段数据当作ASCII字符流解析,取低字节的0x2A对应ASCII字符*,因此输出不符合预期。
  • 缺少格式化转换步骤:/proc文件的核心是向用户空间返回可读的文本内容,而初始代码没有将整数42转换为字符串"42",直接传递了二进制数值,导致解析错误。

修正方法说明

  • 采用seq_file接口处理文本输出:内核提供的seq_file机制专门简化/proc文件的文本生成,seq_printf函数可以安全地将整数格式化为字符串,自动处理内存管理和数据拷贝,避免手动操作的失误。
  • 使用简化的proc创建接口:用proc_create_single替代proc_create,该接口针对只读的简单/proc文件做了封装,只需要实现一个负责格式化输出的回调函数,无需手动处理文件读写的偏移量、字节计数等细节,降低出错概率。

初始代码

// Includes
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>

// License
MODULE_LICENSE("GPL");

// Defines
#define TEST_FILE "test_file"

// Declarations & Variables
static int start_module(void);
static void exit_module(void);
static void create_proc_fs_file(void);
static void cleanup_proc_fs_file(void);
static struct proc_dir_entry *res;

static int my_number = 42;
static ssize_t read_proc(struct file *file, char __user *buffer, size_t count, loff_t *pos);
static struct proc_ops test_fops = {
    .proc_read = read_proc
};

// Entry and Exit
module_init(start_module);
module_exit(exit_module);

// Code
static int start_module(void)
{
    pr_info("\n\nSTARTING PROC ENTRY CREATION\n\n");
    create_proc_fs_file();
    return 0;
}

static void exit_module(void)
{
    cleanup_proc_fs_file();
    pr_info("\n\nExiting Module. Bye Bye!\n\n");
}

static void create_proc_fs_file(void)
{   
    // Create /proc/test_file
    res = proc_create(TEST_FILE, 0666, NULL, &test_fops);
    if(!res){
        pr_err("\nFailed to create /proc/test_file\n\n");
    }else{
        pr_info("\nSuccessfully create /proc/test_file\n\n");
    }

}

static void cleanup_proc_fs_file(void)
{   
    pr_info("\nRemoving /proc/test_file subtree....\n\n");
    remove_proc_subtree(TEST_FILE, NULL);
}

static ssize_t read_proc(struct file *file, char __user *buffer, size_t count, loff_t *pos) 
{   
    size_t len = sizeof(my_number);
    pr_info("\nproc file read....\n\n");
    if (*pos >= len) {
        return 0;  // End of file
    }

    if (count > len - *pos) {
        count = len - *pos;
    }
    if(copy_to_user(buffer, &my_number + *pos, count)){
        return -EFAULT;
    }
    *pos += count;
    return count;
}

可行代码

// Includes
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>

// License
MODULE_LICENSE("GPL");

// Defines
#define TEST_FILE "test_file"

// Declarations & Variables
static int start_module(void);
static void exit_module(void);
static void create_proc_fs_file(void);
static void cleanup_proc_fs_file(void);
static struct proc_dir_entry *res;

static int my_number = 42;
static int print_out(struct seq_file *m, void *v);

// Entry and Exit
module_init(start_module);
module_exit(exit_module);

// Code
static int start_module(void)
{
    pr_info("\n\nSTARTING PROC ENTRY CREATION\n\n");
    create_proc_fs_file();
    return 0;
}

static void exit_module(void)
{
    cleanup_proc_fs_file();
    pr_info("\n\nExiting Module. Bye Bye!\n\n");
}

static void create_proc_fs_file(void)
{   
    // Create /proc/test_file
    res = proc_create_single(TEST_FILE, 0666, NULL, &print_out);
    if(!res){
        pr_err("\nFailed to create /proc/test_file\n\n");
    }else{
        pr_info("\nSuccessfully create /proc/test_file\n\n");
    }
}

static void cleanup_proc_fs_file(void)
{   
    pr_info("\nRemoving /proc/test_file subtree....\n\n");
    remove_proc_subtree(TEST_FILE, NULL);
}

static int print_out(struct seq_file *m, void *v) 
{   
    seq_printf(m, "Count of Packets: %d\n", my_number);
    return 0;
    
}

内容的提问来源于stack exchange,提问作者Chris S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 07:26:00