我的驱动程序必须从用户缓冲区写入名为msg的char数组,该数组在全局范围内
//global scope
...
#define SIZE 64;
char msg[SIZE];
...
所以这是写函数。
static ssize_t Dev_Write(struct file *flip, const char __user *buffer, size_t length, loff_t *offset)
{
copy_from_user(msg + *offset, buffer, length); //I hope *offset = 0 at the first call
printk(KERN_INFO "message from UserSpace is: %s \n", msg);
*offset += length;
return length;
}
当我按顺序调用此函数两次时,它会覆盖msg中的第一个数据。我希望它只是从最后一个位置继续。 我想我必须用 * offset
做点什么这是用户程序:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <iostream>
using namespace std;
#define BUFFER_SIZE 64
int main (int argc, char ** argv)
{
int fd;
ssize_t read_bytes;
ssize_t written_bytes;
char buffer[BUFFER_SIZE] = "aaaaaa";
char buffer1[BUFFER_SIZE] = "bbbbbb";
char buffer2[BUFFER_SIZE];
fd = open ("/dev/2", O_RDWR);
if (fd < 0)
{
fprintf (stderr, "Cannot open file\n");
exit (1);
}
written_bytes = write (fd, buffer, BUFFER_SIZE);
write (fd, buffer1, BUFFER_SIZE);
read_bytes = read (fd, buffer2, BUFFER_SIZE);
cout<<buffer<<endl;
if(written_bytes < 0)
{
fprintf (stderr, "myread: Cannot write to file\n");
exit (1);
}
if (read_bytes < 0)
{
fprintf (stderr, "myread: Cannot read from file\n");
exit (1);
}
close (fd);
exit (0);
}
谢谢。
答案 0 :(得分:2)
虽然根本问题并不完全清楚,但你确实有一个错误,它将你推入未定义的行为。您的用户空间程序每次写入64个字节(BUFFER_SIZE
),但您的内核缓冲区只有64个字节长。第二次写入会导致溢出。
要调试问题,请执行以下步骤。在写入函数的入口处调试消息的长度和偏移量:
printk(KERN_INFO "Size from userspace is: %d offset %d\n", length, *offset);
另外,请缩小您的副本大小,以免覆盖缓冲区:
if (*offset > SIZE)
return -ENOSPC;
if (*offset + length > SIZE)
length = SIZE - *offset;
完成这些测试后,您可以执行copy_from_user
。测试是必要的,但我不确定它们是否足够。调试行可能会发现其他东西混淆了这种情况。
答案 1 :(得分:1)
我想我必须用* offset
做点什么
是的,你确实应该这样做。也就是说,如果驱动程序没有文件位置的概念(如管道或套接字),则可以忽略设置文件位置。并且为了能够设置此文件位置,offset
是一个指针,因此您可以修改该值以使其在外部可见。 (您还需要在代码中进行更多安全检查,以确保不要写入缓冲区的末尾。)*offset += whatever
是正确的。请注意,文件偏移量不需要以字节为单位进行测量,您也可以计入“记录”或其他任何浮动您的船只。
答案 2 :(得分:0)
我解决了我的问题。
我必须添加*偏移缓冲区中实际的数据长度。
copy_from_user(msg + *offset, buffer, length);
printk(KERN_INFO "message from UserSpace is: %s \n", msg);
*offset += strlen(buffer);
提前谢谢你。