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
。