从我收集到的,这是我从我的设备写和阅读我是创建一个代表我的设备的结构,我称之为my_char_struct,如下所示.
struct my_char_structure{ struct cdev my_cdev; struct semaphore sem; char *data; ssize_t data_size; unsigned int access_key; unsigned long size; };
这是一个静态结构,当我的驱动程序是insmod时,它被初始化并指向.
static dev_t dev_num; static struct my_char_structure Dev; int start_mod(void){ //Because we are dealing with a fictitIoUs device,I want //the driver to create my two devices with arbitrarily //assigned major numbers. struct my_char_structure *my_dev = &Dev; int err; alloc_chrdev_region(&dev_num,FIRST_MINOR,COUNT,DEVICE_NAME); sema_init(&(my_dev->sem),1); cdev_init(&(my_dev->my_cdev),&fops); my_dev->my_cdev.owner = THIS_MODULE; my_dev->my_cdev.ops = &fops;// fops is my file operations struct err = cdev_add(&my_dev->my_cdev,dev_num,COUNT); if(err<0) printk(KERN_ALERT "There was an error %d.",err); printk(KERN_ALERT " insmod to major number %d",MAJOR(dev_num)); return 0; } module_init(start_mod);
当我的设备打开时,我只是打开一个指针,指向我在module_init(start_mod)中设置的静态结构,因此…
int dev_open(struct inode *in_node,struct file *filp){ static struct my_char_structure *my_dev; my_dev = container_of(in_node->i_cdev,struct my_char_structure,my_cdev); printk(KERN_ALERT "The device number is %d",iminor(in_node)); if(!my_dev) printk(KERN_ALERT "something didn't work. my_dev not initialized."); filp->private_data = my_dev; return 0; }
我的读取和写入方法做的是修改初始结构Dev,我已经指向我的打开的文件.无论我的结构中的copy_to_user是用户认为是写入设备的,以及用户认为他们正在撰写的copy_from_user.但是,除了改变我的初始结构Dev,文件位置或偏移的想法没有意义,除非它指向内核中缓冲内存的指针,用于某些任意结构或类型.这是我对文件偏移的唯一解释…这是正确的吗?这是指loff_t * offp在哪里?
write(struct file *filp,const char __user *buff,size_t count,loff_t *offp) read(struct file *filp,char __user *buff,loff_t *offp)
(给定我的理解是正确的)当一些file_operation如读/写被调用并且我没有设置* offp个人时,loff_t * offp最初设置为?
如果在最后一个file_operation offp = some_arbitrary_address(因为我这么说),那么当再次调用这个操作时,这个offp会被设置为什么?
如果我有其他的file_opens操作运行,会怎么做,它将设置为最后一个file_operation留下它,或者它会保留一个选项卡,其中使用file_open操作,并将* offp替换为file_open的内容?
一个char设备的概念对我而言太抽象了,因为它似乎设备本身甚至不能像文件一样存储信息,而是其保存信息的驱动程序.我希望我解释了我的雾气,我会清除任何我看起来模糊的东西.
感谢任何帮助:)
解决方法
当您进入驱动程序时,指针本身指向用户提供的偏移量(假设用户代码执行驱动程序访问 – 从技术上讲,内核可以提供自己的权限,但用户案例是要考虑的)通过lseek或llseek或lseek64等,然后通过普通的读写操作.考虑常规磁盘文件的情况:当您首次打开文件时,您(作为用户)获取内核以提供跟踪当前文件位置的数据结构,以便在读取或写入时一些字节,下一个读取或写入从你离开的地方拾起.
此外,如果您歪斜文件描述符,或者通过(例如)fork和exec等效于运行一系列命令,则该查找位置由所有继承的进程共享.因此,在shell提示符下,命令:
(prog1; prog2; prog3) > outputfile
创建一个输出文件,然后将描述符复制到三个程序,以便prog2写入的输出在prog1输出后立即进入该文件,并且prog3的输出跟随其他两个,因为所有三个独立进程共享相同的底层内核数据结构与内部loff_t相同.
这同样适用于设备驱动程序文件.当您的读写功能被调用时,您将收到用户提供的“当前偏移量”,并且可以(并且应该)根据需要进行更新…假设有任何需要(例如,您想要向用户提供常规文件的外观,包括在读取和写入时寻求偏移移动的事实).如果设备有一些逻辑应用的seek偏移量,那么可以在这里使用.
当然,还有更多的设备驱动程序,这就是为什么有这些东西(q.v.)的整个书籍章节.