gpt4 book ai didi

从内核模块写入和读取设备文件的代码?

转载 作者:太空狗 更新时间:2023-10-29 11:34:03 26 4
gpt4 key购买 nike

下面的代码我已经试过很多次了。

#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<asm/uaccess.h>
#include<linux/semaphore.h>

MODULE_LICENSE("DUAL BSD/GPL");
static int dev_open(struct inode *,struct file *);
static int dev_release(struct inode *,struct file *);
ssize_t dev_read(struct file *,char *, size_t ,loff_t *);
ssize_t dev_write(struct file *,const char *,size_t ,loff_t *);

static int major;
int dev_major = 0;
int dev_minor = 0;
struct cdev *cdev;

struct device {
char array[100];
struct semaphore sem;
}chr_arr;

struct file_operations dev_ops = {
.owner = THIS_MODULE,
.read = dev_read,
.write = dev_write,
.open = dev_open,
.release = dev_release
};

ssize_t dev_read(struct file *filp,char *buf,size_t count,loff_t *offset)
{
int i;
i=copy_to_user(buf,chr_arr.array,count);
printk(KERN_ALERT"buff:%s",buf);
return i;
}

ssize_t dev_write(struct file *filp,const char *buf,size_t count,loff_t *offset)
{
//printk(KERN_ALERT"\nsorry,byebye");
int j;
//msg_ptr = kmalloc(count,GFP_KERNEL);
//for(j=0;j<count;j++)
if(count>100)
return -1;
j = copy_from_user(chr_arr.array,buf,count);
//printk(KERN_ALERT"msg_ptr:%s",msg_ptr);
return j;
}

static int dev_open(struct inode *inode,struct file *filp)
{
filp->private_data = inode->i_cdev;
if(down_interruptible(&chr_arr.sem))
{
printk(KERN_INFO " could not hold semaphore");
return -1;
}
//printk(KERN_ALERT"ah ha the device is open !now we can go further");
return 0;
}

static int dev_release(struct inode *inode,struct file *filp)
{
up(&chr_arr.sem);
//module_put(THIS_MODULE);
return 0;
}

static int init_device(void)
{
int result;
dev_t dev_no,dev;
result = alloc_chrdev_region(&dev_no,0,1,"chr_dev");
if(result < 0)
{
printk("sorry no major number left");
return result;
}
major = MAJOR(dev_no);
dev = MKDEV(major,0);
cdev = cdev_alloc();
cdev->ops = &dev_ops;
sema_init(&chr_arr.sem,1);
printk("the major number allocated is %d\n",major);
result = cdev_add(cdev,dev,1);
if(result < 0 )
{
printk(KERN_INFO "Unable to allocate cdev");
return result;
}
return 0;
}

static void clean_device(void)
{
cdev_del(cdev);
unregister_chrdev_region(major,1);
}

module_init(init_device);
module_exit(clean_device);

但它给了我以下警告。

CC [M]  /home/karan/practice/scrw/scrw1.o
In file included from /usr/src/linux-2.6.34.10-0.6/arch/x86/include/asm/uaccess.h:571:0,
from /home/karan/practice/scrw/scrw1.c:4:
In function ‘copy_from_user’,inlined from ‘write’ at /home/karan/practice/scrw/scrw1.c:43:6:
/usr/src/linux-2.6.34.10-0.6/arch/x86/include/asm/uaccess_32.h:212:26: warning: call to ‘copy_from_user_overflow’ declared with attribute warning: copy_from_user() buffer size is not provably correct
Building modules, stage 2.
MODPOST 1 modules
CC /home/karan/practice/scrw/scrw1.mod.o
LD [M] /home/karan/practice/scrw/scrw1.ko

然后当我尝试写入 echo hi >/dev/my_dev 时,屏幕会在 30 秒左右后卡住。

最佳答案

问题是你应该在读/写方法中返回读/写的字节数,如果一切顺利,copy_{from,to}_user() 的返回值为 0。返回例如如果复制成功,请计入您的写入方法:

unsigned long ret;
printk(KERN_INFO "Inside write \n");
if (count > sizeof(char_arr.array) - 1)
return -EINVAL;
ret = copy_from_user(char_arr.array, buff, count);
if (ret)
return -EFAULT;
char_arr.array[count] = '\0';
return count;

您还应该确保在复制到缓冲区时附加终止符 '\0'(如果您只想处理字符串)。如果它是您处理的二进制数据,也将其长度存储在您的结构中。

示例读取方法:

ssize_t dev_read(struct file *filp,char *buf,size_t count,loff_t *offset)
{
int len = count >= strlen(chr_arr.array) ? strlen(chr_arr.array) : count;

if (*offset >= strlen(chr_arr.array))
return 0;

if (copy_to_user(buf,chr_arr.array,len))
return -EFAULT;

return len;
}

编辑:弄乱了示例代码,修复它。

Edit2:示例读取方法。

关于从内核模块写入和读取设备文件的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9047950/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com