Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Linux设备驱动程序:将字符串从内核复制到用户空间_C_Linux_Linux Kernel_Linux Device Driver - Fatal编程技术网

C Linux设备驱动程序:将字符串从内核复制到用户空间

C Linux设备驱动程序:将字符串从内核复制到用户空间,c,linux,linux-kernel,linux-device-driver,C,Linux,Linux Kernel,Linux Device Driver,我有一个这样的结构: typedef struct { char* BUFFER; int Size; }DataTransfer; DataTransfer dataTransfer; if(ioctl(fd, CHAR_DRIVER_IOCQREAD, &dataTransfer) < 0) { perror("ERROR in ioctl CHAR_DRIVER_IOCQREAD"); } else { printf("Kernel retu

我有一个这样的结构:

typedef struct
{
    char* BUFFER;
    int Size;
}DataTransfer;
DataTransfer dataTransfer;
if(ioctl(fd, CHAR_DRIVER_IOCQREAD, &dataTransfer) < 0)
{
    perror("ERROR in ioctl CHAR_DRIVER_IOCQREAD");
}
else
{
    printf("Kernel returned size %d \n", dataTransfer.Size);
    printf("Kernel returned string %s \n", dataTransfer.BUFFER);
}
在IOCTL函数中,我尝试填充结构并传递给用户空间:

case CHAR_DRIVER_IOCQREAD:
    printk(KERN_INFO "In CHAR_DRIVER_IOCQREAD");
    dataTransfer.BUFFER = kmalloc(strlen_user("Hello") +1, GFP_KERNEL);
    dataTransfer.Size = strlen_user("Hello") +1;
    error_count = copy_to_user((DataTransfer*) arg, &dataTransfer, sizeof(dataTransfer) );
在用户空间中,我尝试按如下方式接收结构:

typedef struct
{
    char* BUFFER;
    int Size;
}DataTransfer;
DataTransfer dataTransfer;
if(ioctl(fd, CHAR_DRIVER_IOCQREAD, &dataTransfer) < 0)
{
    perror("ERROR in ioctl CHAR_DRIVER_IOCQREAD");
}
else
{
    printf("Kernel returned size %d \n", dataTransfer.Size);
    printf("Kernel returned string %s \n", dataTransfer.BUFFER);
}
DataTransfer数据传输;
if(ioctl(fd、字符、驱动程序和数据传输)<0)
{
perror(“ioctl字符驱动程序IOCQREAD中的错误”);
}
其他的
{
printf(“内核返回大小%d\n”,dataTransfer.size);
printf(“内核返回字符串%s\n”,dataTransfer.BUFFER);
}

正确的方法是什么?

这里有几个问题。首先,您要将结构复制到用户空间,而不是它所指向的字符串。该结构将指向您分配的用户空间无法访问的内核内存。第二,您正在分配内核内存,但实际上没有将任何东西放在那里

这样做的一种方法是,用户空间为IOCtl分配内存,以便将字符串写入其中,然后向IOCtl传递一个类似DataTransfer的结构,该结构描述了它分配的内存。内核将使用copy_from_user从用户内存中读取结构,然后,如果分配的缓冲区足够大,可以容纳字符串,则使用copy_to_user将其写入结构中传递给它的地址

例如(内核侧,仅草图):

case CHAR\u DRIVER\u IOCQREAD:
数据传输;
if(从用户复制用户(&dataTransfer,arg,sizeof(dataTransfer)))
返回-默认值;
if(dataTransfer.Size
zOMG的可能复制品,这种款式是从哪里来的@“安德烈,我不明白你的意思?”罗本·福特·范·男孩回答得好!我不确定在
数据传输时返回的最合适的错误代码是什么。Size
太小,无法容纳字符串,但可能是
-EOVERFLOW