【发布时间】:2022-10-19 05:35:13
【问题描述】:
我正在尝试创建一个简单的字符设备 LKM,但我已经被困了好几天,试图让我的读写正常工作。目前当我做类似的事情时:
echo hi > /dev/simple_character_device
我能够看到我正在写入正确数量的字节。
但是当我试图找出该设备的内容时,它会不断循环 hi 直到到达一个错误的地址。目前我正在尝试跟踪我在全局计数器中写入了多少字节。但这似乎不对。任何有关实现读写的帮助将不胜感激。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/string.h>
MODULE_LICENSE("GPL");
#define BUFFER 1024
char * buffer_data;
// Count open and closed
size_t current_count;
int my_open(struct inode *, struct file *);
int my_release(struct inode *, struct file *);
ssize_t my_read(struct file *, char __user *, size_t count, loff_t *);
ssize_t my_write(struct file *, const char __user *, size_t count, loff_t *offp);
static struct file_operations fops = {
.owner = THIS_MODULE,
.open = my_open,
.release = my_release,
.read = my_read,
.write = my_write
};
int reg_init(void)
{
// Allocate memory to store information
buffer_data = kmalloc(BUFFER, GFP_KERNEL); // Use Kernel Flag
register_chrdev(240, "simple_character_device", &fops);
printk(KERN_ALERT "Init Allocating Memory");
return 0;
}
void reg_exit(void)
{
// Free and unregister device and data
kfree(buffer_data);
unregister_chrdev(240, "simple_character_device");
printk(KERN_ALERT "Deregister Simple Character Device");
}
int my_open(struct inode *inode, struct file *file){
printk(KERN_ALERT "Open File Device.\n");
return 0;
}
int my_release(struct inode *inode, struct file *file){
printk(KERN_ALERT "Close File Device.\n");
return 0;
}
ssize_t my_read(struct file *filp, char __user *buff, size_t count, loff_t *offp){
// Check if we are reading within the Buffer Size
if(BUFFER - *offp < 0){
printk(KERN_ALERT "Out of buffer range.\n");
return -EFAULT;
}
// Check if we fail to copy to user
if (copy_to_user(buff, buffer_data, current_count) != 0){
printk(KERN_ALERT "Failed to send character to user\n");
return -EFAULT;
}
(*offp) += current_count;
printk(KERN_ALERT "Read %zu bytes.\n", current_count);
return current_count;
}
ssize_t my_write(struct file *filp, const char __user *buff, size_t count, loff_t *offp){
// We need to get data FROM the user space
// Make sure we are reading within the buffer
if (*offp >= BUFFER || BUFFER - count < *offp){
printk(KERN_ALERT "ATTEMPTING TO WRITE TO OUSIDE OF BUFFER!\n");
return EFAULT;
}
// Get the amount of bytes from the user
copy_from_user(buffer_data + *offp, buff, count);
*offp += count;
printk(KERN_ALERT "Wrote %zu to the device.\n", count);
current_count = count;
return current_count;
}
module_init(reg_init);
module_exit(reg_exit);
【问题讨论】:
-
在
my_read()中,您不需要像在my_write()中那样将*offp添加到buffer_data吗? -
我不完全确定你想用
current_count做什么,但my_read()返回那个值。当count不为零时,文件结束条件由返回值 0 指示。cat将继续读取文件,直到文件结束或出现错误。此外,my_read()在每次调用中不得将超过count字节复制到buff(即它不应访问buff[count]及以上)。 -
我试过修改 my_read 但仍然没有运气。它现在停止循环,但不显示输出并且计数非常大。
copy_to_user(buff, buffer_data + *offp, count);my_write 肯定也有问题:copy_from_user(buffer_data + *offp, buff, count); -
驱动程序打算建模什么样的数据结构?像随机访问数据块这样的东西,就像管道一样?
-
更像是一个可以写入和读取的简单文件。例如,我们的测试用例脚本会向设备写入“hello”。然后从设备中读取并期望返回与您刚刚写入的字节数相同的字节数