我的内核模块的读取功能如下。它只是从内核缓冲区中读取一个字符并将其复制到用户缓冲区中。 一旦我到达内核缓冲区的末尾,我返回0.这非常有效。
static ssize_t debugfs_read(struct file *f, char __user *buf,
size_t length, loff_t *offset)
{
ssize_t rc = 0;
pr_info("%s.\n", "In read");
rc = copy_to_user(buf, &kbuffer[*offset], 1);
if (rc < 0)
return -EFAULT;
if (kbuffer[*offset] == '\0')
return 0;
*offset = *offset + 1;
return 1;
}
现在如果我尝试将整个内核缓冲区一次性复制到用户缓冲区中, 模块不会打印任何内容。
为什么?这种情况下的代码:
static ssize_t debugfs_read(struct file *f, char __user *buf,
size_t length, loff_t *offset)
{
ssize_t rc = 0;
pr_info("%s.\n", "In read");
rc = copy_to_user(buf, &kbuffer, BUFF_LEN);
if (rc != 0)
return -EFAULT;
return 0;
}
编辑:
在使用已接受答案的解决方案时,我意识到内核会调用read
两次。这是strace
:
read(3, "s03324135655\0", 65536) = 13
write(1, "s03324135655\0", 13) = 13
read(3, "", 65536) = 0
为什么?是因为我们必须从模块完成reading
后返回0?第二个系统调用有一个空字符串,基本上规定没有东西要读,我们应该返回零。
答案 0 :(得分:2)
1
,但是在成功的情况下,复制整个缓冲区的代码总是返回0
,这告诉调用者您向缓冲区写了0
个字节。 所以,不要自己实现所有这些逻辑,只需使用simple_read_from_buffer
,这会为你做到这一点:
static ssize_t debugfs_read(struct file *f, char __user *buf,
size_t length, loff_t *offset)
{
return simple_read_from_buffer(buf, length, offset, &kbuffer, BUFF_LEN);
}