资源描述:
《Linux内核实验报告实验.doc》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、Linux内核实验报告实验题目:字符设备驱动程序实验实验目的:在本实验中完成一个简单的字符驱动程序的设计;在该基础上,添加上同步机制,使用读写缓冲区,实现一种免锁算法,以此来实现类似一个管道的字符设备。硬件环境:Pentium(R)Dual-CoreCPUT4400@2.20GHz软件环境:Ubuntu12.04gccversion4.6.3(Ubuntu/Linaro4.6.3-1ubuntu5)内核版本:3.0.24实验步骤:1、代码分析内核中使用定义在中的dev_t类型变量保存设备编号,2.6
2、中dev_t在是一个32位整数,12位用来表示主设备号,20位用来表示次设备号。每种设备都对应一个唯一的设备号。2.6中可以用静态或动态方法分配设备号。例如动态分配一个字符设备的函数:intalloc_chrdev_region(dev_t*dev,//保存获取的设备号unsignedintfirstminor,//第一个次设备号,通常为0unsignedintcount,//请求的连续的次设备数char*name);//关联的设备名设备卸载时应该释放这些设备号:voidunregister_chrdev_region(dev_
3、tfirst,//要释放的设备号unsignedintcount);//数量程序中可用定义在的宏:获得主设备号:MAJOR(dev_tdev)获得次设备号:MINOR(dev_tdev)主设备号和次设备号转换为dev_t类型:MKDEV(intmajor,intminor)structscull_qset*scull_follow(structscull_dev*dev,intn):该函数遍历我们定义的链表,遍历到第n项;必要的时候,分配主动分配链表项也就是说该方法基本上一直能成功(除非内存不够)
4、量子集和量子的分配推迟到向设备文件写入时才有必要分配。实验B:读取函数,在读写指针一样时,即表明现在没有可以读取的数据,则等待到inq上;否则,根据相对位置,或是直接读到写指针的位置,或是因为回绕,先直接回到缓冲区的末尾。在读的过程中需要获得先获得设备的信号量,在读取结束后释放信号量;最终唤醒所有因为读写指针相等而阻塞在队列上的写进程。注意在此写指针会绕的时候,我们只是读取从读指针到缓冲区末尾的部分内容,在读取完成之后,我们才将读指针也绕回到环形缓冲区开始处。这样的话处理起来比较方便,不需要copy两次。staticssize_
5、tscull_p_read(structfile*filp,char__user*buf,size_tcount,loff_t*f_pos){structscull_pipe*dev=filp->private_data;if(down_interruptible(&dev->sem))return-ERESTARTSYS;while(dev->rp==dev->wp){/*nothingtoread*/up(&dev->sem);/*releasethelock*/if(filp->f_flags&O_NONBLOCK)ret
6、urn-EAGAIN;PDEBUG(""%s"reading:goingtosleep",current->comm);if(wait_event_interruptible(dev->inq,(dev->rp!=dev->wp)))return-ERESTARTSYS;/*signal:tellthefslayertohandleit*//*otherwiseloop,butfirstreacquirethelock*/if(down_interruptible(&dev->sem))return-ERESTARTSY
7、S;}/*ok,dataisthere,returnsomething*/if(dev->wp>dev->rp)count=min(count,(size_t)(dev->wp-dev->rp));else/*thewritepointerhaswrapped,returndatauptodev->end*/count=min(count,(size_t)(dev->end-dev->rp));if(copy_to_user(buf,dev->rp,count)){up(&dev->sem);return-EFAULT;}dev
8、->rp+=count;if(dev->rp==dev->end)dev->rp=dev->buffer;/*wrapped*/up(&dev->sem);/*finally,awakeanywritersandreturn*/wake_up_interrupt