6

我正在尝试使用以下函数将值从用户空间复制到内核空间:

static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t  *off) 
{

    unsigned long copy=0;
    int desp=0; 

    copy = copy_from_user(&desp, &len, 4);  

    printk(KERN_ALERT "copy: %lx\n", copy);      
    printk(KERN_ALERT "desp: %d\n", desp);
}

其中“len”是用户空间中存在的变量,我想将它复制到内核空间中的“desp”

我从用户空间进行的函数调用是(根据 file_operations 结构写入的是 device_write):

 write (fd,buffer,8, &off);

当我打印应该存储在“desp”中的值总是0(应该是8)。我的代码有什么问题?我已经看到了几个例子,我实现了许多变体,但没有一个有效。

4

2 回答 2

7

手册中的write函数原型为:

ssize_t write(int fd, const void *buf, size_t count);

因此,您只需将 3 个值传递给write,即:文件描述符fdbuffer数据所在的位置以及count要写入的字节数。

这关于用户空间。现在让我们转到内核空间写入函数,即您的device_write.

该函数的参数buf是包含要从用户空间写入的数据的参数,count是内核发送的要写入的数据的长度。所以你应该从buf指针而不是复制数据len

所以,正确的方法是:

char *desp;  //allocate memory for this in kernel using malloc
copy_from_user (desp, buff, len);

这应该做。

于 2013-07-06T09:07:43.863 回答
4

len存在于用户空间。它是按值传递的,因此len可以作为内核空间中的普通变量访问。 desp = (int)len是你所需要的全部。但是请注意,size_t 与 int 不同,在 64 位平台上 size_t 是 8 个字节。

copy_from_user()用于您尝试写入的缓冲区(buffer在您的用户空间代码和buff内核空间参数列表中调用)。传递的是指向仅存在于用户空间中的内存地址的指针,因此copy_from_user()将该缓冲区复制到内核空间缓冲区。

于 2013-07-05T14:08:49.353 回答