C和内核编程新手-所以想知道你是否可以建议我需要改变什么才能得到正确的输出。
我有一个内核模块,它将创建/proc/test_file
当我在/proc/test_file上使用cat命令时-我希望它返回存储在变量“my_number”中的整数值。但是现在它返回的是asynchronous字符 ( 的asynchronous decimal是42),而不是我存储在“my_number”中的整数。我假设我错误地调用了函数,或者错误地传递了变量。我真的还没有得到C。
// 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;
}
预期输出:chris@dev:~$cat /proc/test_file
42
实际输出:chris@dev:~$cat /proc/test_file
*
我猜问题出在这里,我告诉它“42”是一个char,它正在转换它或其他东西:
静态ssize_t read_proc(结构文件 * 文件,*char __user * 缓冲区 *,size_t计数,loff_t *pos)
编辑:
只是回来并根据下面@Tsyvarev的答案添加工作代码。其中一个好处是,它绕过了通过proc_ops进行file_operations的需要,因此它现在可以在旧的内核版本上工作(如果你需要的话)。
// 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;
}
1条答案
按热度按时间lf5gs5x21#
seq_file
提供了一种方便的机制,可以轻松地创建一个文件,将一些信息表示为字符串。对于procfs,此机制可用,例如:通过proc_create_single
函数:使用这种方法,您只需提供
show
函数(在上面的示例中,它被命名为my_show
),每当读取文件时都会调用该函数。该函数的目的是生成内容,然后返回给用户。在这样的函数中有几个生成内容的助手,
seq_printf
就是其中之一。从它的名字可以猜到,这个帮助器非常类似于printf
函数,但是使用seq_file操作。然后,
show
函数作为参数传递给proc_create_single
。seq_file
机制描述如下:在kernel documentation中。该文档仅描述了该机制对“标准”文件的应用,即file_operations
。该机制对procfs文件的适应由include/linux/proc_fs.h头文件中的几个函数表示。