c-copy_to_user()保持无限打印消息



我正在学习"Linux设备驱动程序">。我创建了一个名为char_device的字符设备。当我从设备中读取数据时,它不断地将消息打印到终端,无限地使机器崩溃。

驱动程序中读取操作的源代码:

static ssize_t my_read(struct file *my_file, char __user *buf, size_t len, loff_t *off) {
uint8_t *message = "Hello from the kernel world!n";
size_t datalen = strlen(message);

if(len > datalen) {
len = datalen;
}
printk(KERN_INFO "Char driver: Read");
if(copy_to_user(buf, message, len)) {
return -EFAULT;
}
return len;
}

用于读取设备的用户空间命令:

cat /dev/char_device

驱动程序不断打印";你好,来自内核世界"消息发送到终端。

cat等程序将读取当前输入文件,直到遇到文件结束条件或读取错误。按照惯例,read()返回值0表示请求非零数据量时的文件结束条件。-1的返回值指示具有errno变量中的错误号的读取错误。

在内核级别,read文件操作处理程序应返回0以指示文件结束条件(但当请求量为0时也可以这样做(,并且应返回否定的errno值以指示读取错误。

OP当前的read文件操作处理程序my_read将字符串文字"Hello from the kernel world!n"的内容复制到用户内存缓冲区,限制为请求的读取量或字符串长度,以最小者为准。它从不返回文件结尾条件。它唯一返回0的时间是请求的金额为0,但这不是有效的文件结尾条件。

my_read可以做的一件事是使用传入的文件位置信息来确定从哪里开始读取,并限制要复制的数量。它应该相应地更新位置。然后,当没有更多数据要复制时,它可以在何时返回0以指示文件结束。这里有一个可能的实现:

static ssize_t my_read(struct file *my_file, char __user *buf, size_t len, loff_t *off) {
char *message = "Hello from the kernel world!n";
size_t datalen = strlen(message);

if (*off >= datalen) {
return 0; /* end of file */
} 
if(len > datalen - *off) {
len = datalen - *off;
}
printk(KERN_INFO "Char driver: Readn");
if(copy_to_user(buf, message, len)) {
return -EFAULT;
}
*off += len;
return len;
}

行为的一个变化是,长度为10的连续读取量(例如(将从上一个read停止的位置开始,例如:

  • 读取10,返回10('H''e''l''l''o'' ''f''r''o''m'(
  • 读取10,返回10(' ''t''h''e'' ''k''e''r''n''e'(
  • 读取10,返回9('l'' ''w''o''r''l''d''!''n'(
  • 读取10,返回0(文件结尾(

相关内容

  • 没有找到相关文章

最新更新