Linux 内核模块,创建后进先出设备

标签 linux linux-kernel linux-device-driver

我正在尝试编写一个简单的内核模块(字符设备)作为内存,确切地说是一个后进先出(堆栈)。当前的代码是这样的:

#include <linux/module.h> 
//and the rest of the includes and defines go here

struct virtual_device{ char data[STACK_SIZE];
}stack;// my stack data is stored in this structure

int device_open(struct inode *inode, struct file *filp){return 0;}

int device_release(struct inode *inode, struct file *filp){return 0;}

ssize_t device_write(struct file *filp, const char *buf, size_t count, loff_t *offset){
  ret = copy_from_user(stack.data,buf,count);
  return ret;
}

ssize_t device_read(struct file *filp, char* buf, size_t count, loff_t *offset){
  ret = copy_to_user(buf, stack.data,count);
  return ret; 
}

struct file_operations fops = {
  .open = device_open,
  .write = device_write,
  .read = device_read,
  .release = device_release
};

static int driver_entry( void ){
  //this part of the code is pretty standard, 
  //module initialization , major number generation and so on
}

static void driver_exit( void ){
  //char device deletion, unregister...
}

module_init(driver_entry);
module_exit(driver_exit);

在阅读了一些关于 copy_to_user 和 copy_from_user 函数之后,我的印象是我可以循环它们并处理文件指针,从而改变写入设备的顺序。我将写入函数更改为:

ssize_t device_write(struct file *filp, const char *buf, size_t count,loff_t *offset){
  char *temp;
  int i=1;

  while(i<= count){
    temp = buf + count - i;
    ret = copy_from_user(stack.data,temp,1);
    printk(KERN_INFO "Writing to device");      
    i +=1;
  } 
return ret; 
}

基本上,我正在尝试从后到前逐个字符地从用户复制,希望当我阅读消息时,它会倒转(你知道后进先出法是如何从最后一个条目读取到第一个条目的) .

但是,当我尝试使用它时,设备会变得疯狂:即使我向它写了“hola”,dmesg 日志显示了 50 条“正在写入设备”消息,当我尝试从中读取所有信息时,我得到了是�。 谁能指出我忽略了什么?我的尝试是不是太天真了?

最佳答案

因为你一直返回 0(假设 copy_from_user 没有失败)。所以 VFS 认为你的司机没有接受(写)任何东西。 VFS 将继续尝试写入.... 这就是为什么您不断收到“正在写入设备”消息的原因。

while(i<= count){

    temp = buf + count - i;

    ret = copy_from_user(stack.data,temp,1); // ==> U keep writing data to same position -> stack.data[0]

    printk(KERN_INFO "Writing to device");      
    i +=1;
} 


ssize_t device_read(struct file *filp, char* buf, size_t count, loff_t *offset){
  ret = copy_to_user(buf, stack.data,count);//==> U should return whatever u have in "data" instead of use "count" which might be pretty big.
  return ret; 
}

关于Linux 内核模块,创建后进先出设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39594596/

相关文章:

c++ - 如何从用户区的分段内存创建映射?

linux-device-driver - 环回网络内核模块不工作

c - "get_user_pages"是如何工作的(对于 linux 驱动程序)

C 套接字 : Redirecting buffer to another file

c++ - 底层段寄存器的线程本地实际使用

linux - 遍历结构页面

linux-kernel - Linux设备驱动程序,该程序在哪里启动?

linux - 自主脚本

linux - 如何在不丢失原始目的地的情况下将 TCP 包重定向到代理?

linux-kernel - 在 ARM 中禁用内存页的写保护