我正在尝试编写一个简单的内核模块(char设备),它充当内存,确切地说是LIFO(堆栈)。目前的代码是这样的:
#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函数的内容后,我的印象是我可以循环它们并处理文件指针,以便更改设备的写入顺序。我将write函数更改为:
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;
}
基本上,我试图从用户逐个字符地复制,从后到前,希望当我读取消息时,它将被反转(你知道LIFO如何读取从最后一个条目到第一个条目) 。
然而,当我尝试使用它时,设备会变得疯狂:即使我写了“hola”,dmesg日志显示为50“写入设备”消息,当我尝试从中读取所有内容时是 。 任何人都可以指出我在俯瞰什么?我的尝试太天真了吗?
答案 0 :(得分:0)
因为你一直返回0(假设copy_from_user没有失败)。所以VFS认为你的司机没有接受(写)任何东西。 VFS将继续尝试写.... 这就是为什么你不断获得&#34;写入设备&#34;消息。
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;
}