C 如何正确使用“从用户复制”的方法?

C 如何正确使用“从用户复制”的方法?,c,linux-kernel,kernel,C,Linux Kernel,Kernel,我试图使用以下函数将值从用户空间复制到内核空间: 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

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

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”

我从用户空间进行的函数调用是(write是device\u write,根据file\u operations struct):

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

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


copy\u from\u user()
用于您试图写入的缓冲区(在用户空间代码中称为
buffer
,在内核空间参数列表中称为
buff
)。传递的是指向仅存在于用户空间中的内存地址的指针,因此
copy\u from\u user()
将该缓冲区复制到内核空间缓冲区。

手册中的
write
函数原型是:

ssize\u t write(int fd,const void*buf,size\u t count)

因此,只需将3个值传递给
写入
,即:文件描述符
fd
数据所在的缓冲区
,以及要写入的字节数

这与用户空间有关。现在让我们转到内核空间写入函数,即您的
设备\u write

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

因此,正确的方法是:

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

这应该可以。

当然可以,但我的想法是传递第四个参数offset(loff_t*),当我从用户空间调用时,它不会到达内核空间。所以我把这些变量看作是用户空间。另一方面,如果我可以直接从内核空间访问“buff”…你怎么能从用户空间调用它呢
write()
是一个定义的系统调用接口,它接受3个参数。C库和内核VFS层最终将调用转换为
device\u write()
处理程序。您不能只添加第四个参数,编译器也不会允许您这样做。您是在找
pwrite
吗?不管怎样,这和我回答的你的问题有什么关系?如果您想问一些不同的问题,请修复您的问题。我们将阅读关于pwrite/read的文章,尝试实现该系统调用,非常感谢!Peter,在结构文件操作中没有实现pread/pwrite,在我的内核3.6(arm)中,我必须使用ioctl…您仍然对内核空间文件操作处理程序和用户空间系统调用之间的区别感到困惑。当用户想要写入文件时,他调用函数write(或pwrite,或writev或pwritev)。从那里,C库将该函数调用转换为系统调用。从这里开始,您就进入了内核空间。然后,在调用最终到达文件操作处理程序之前,内核经历了几个转换步骤。相信我!试试看!从用户空间调用pwrite,并观察调用在write()处理程序中显示。问题是系统调用只有3个参数,我想使用文件操作结构(device_read/write)方法中的4个参数。因此,当放入内核空间时,编译器不会给出任何关于有方法的参数数量的警告(这是不同的),我尝试过做一个系统llamdas 5参数!编译和执行没有任何问题的警告。。。谢谢你的回答!!!
char *desp;  //allocate memory for this in kernel using malloc
copy_from_user (desp, buff, len);