gpt4 book ai didi

linux - copy_to_user 在内核模块中不工作

转载 作者:太空狗 更新时间:2023-10-29 12:19:26 25 4
gpt4 key购买 nike

我试图在内核模块读取函数中使用 copy_to_user,但无法将数据从内核复制到用户缓冲区。如果我做错了什么,谁能告诉我。我的内核版本是 2.6.35。我给出了内核模块的一部分以及用于测试它的应用程序。现在我的重点是为什么这个 copy_to_user 不起作用。任何帮助都会很棒。

///////////////////////////////////kernel module//////////////////////////////////////

#define BUF_LEN 80

static char msg[BUF_LEN];
static char *msg_Ptr;

static int device_open(struct inode *inode, struct file *file)
{
static int counter = 0;

if (Device_Open)
return -EBUSY;

Device_Open++;
printk(KERN_ALERT "In open device call\n");

sprintf(msg, "I already told you %d times Hello world!\n", counter++);
msg_Ptr = msg;
try_module_get(THIS_MODULE);

return SUCCESS;
}


static ssize_t device_read(struct file *filp,
char __user *buffer,
size_t length,
loff_t * offset)
{
/*
* Number of bytes actually written to the buffer
*/
int bytes_read = 0;

/*
* If we are at the end of the message,
* return 0 signifying end of file
*/
if (*msg_Ptr == 0)
return 0;

/*
* Actually put the data into the buffer
*/


else {
bytes_read=copy_to_user(buffer, msg, length);
if (bytes_read==-1);
{
printk(KERN_INFO "Error in else while copying the data \n");
}

}

return bytes_read;
}






////////////////////////////////////////application////////////////////////
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

#define BUF_SIZE 40

int main()
{
ssize_t num_bytes;
int fd, n=0;
char buf[BUF_SIZE];

fd=open("/dev/chardev", O_RDWR);
if(fd== -1){perror("Error while opening device");exit(1);}

printf("fd=%d\n",fd);
num_bytes=read(fd, buf, BUF_SIZE);
if(num_bytes==-1){perror("Error while reading"); exit(2);}

printf("The value fetched is %lu bytes\n", num_bytes);

while(n<=num_bytes)
{
printf("%c",buf[n]);
n++;
}

close(fd);
return 0;

}

最佳答案

您编写的代码片段中存在一些问题。首先,调用 try_module_get(THIS_MODULE);
并不是一件好事该语句试图增加模块的引用计数......在模块本身!相反,您应该在 init 方法中将 file_ops 结构的 owner 字段设置为 THIS_MODULE。这样,引用处理将发生在模块代码之外,在 VFS 层中。你可以看看 Linux Kernel Modules: When to use try_module_get / module_put .
然后,正如 Vineet 所说,您应该从 file_ops private_data 字段中检索指针。

最后但并非最不重要的是,这就是为什么似乎发生了错误而……实际上……却没有发生的原因:如果 copy_to_user 调用已成功将所有需要的字节复制到目标内存区域,则调用返回 0,如果出现错误。也就是说,当你运行时:

/* Kernel part */
bytes_read=copy_to_user(buffer, msg, length);
/*
* Wrong error checking :
* In the below statement, "-1" is viewed as an unsigned long.
* With a simple equality test, this will not bother you
* But this is dangerous with other comparisons like "<" or ">"
* (unsigned long)(-1) is at least 2^32 - 1 so ...
*/
if (-1 == bytes_read) {
/* etc. */
}
return bytes_read;

/* App part */
num_bytes=read(fd, buf, BUF_SIZE);
/* etc.. */
while(n<=num_bytes) {
printf("%c",buf[n]);
n++;
}

成功复制后你应该只得到一个字符,在你的情况下只有一个“I”。此外,您使用 msg_Ptr 指针作为保护措施,但您从不更新它。这可能会导致错误调用 copy_to_user
copy_to_user 通过调用 access_ok 检查用户空间指针,但如果内核空间指针和给定的长度不正确,这可能会以内核 Oops/ panic 。

关于linux - copy_to_user 在内核模块中不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14496146/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com