《块设备驱动开发教学课件电子教案.pptx》由会员分享,可在线阅读,更多相关《块设备驱动开发教学课件电子教案.pptx(24页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、5.4 块设备驱动开发Internet+Education Solutions第5章 Linux驱动开发技术5.4 块设备驱动开发EducationSolutions目录ContentsInternet+Linux块设备Linux块设备驱动架构RamDisk块设备驱动开发开发实践8:57 / 4Linux磁盘设备块设备也就是存储以“块”为单位数据的设备,如磁盘或光盘。Linux操作系统的磁盘设备并不直观,在LInux系统中“一切皆文件”的理念下,磁盘设备其实也是一个文件,只不过是一个比较特殊的文件。Linux块设备8:57 / 5Linux系统中磁盘的本质对于Linux操作系统而言,磁盘为一个
2、文件。其中,在Linux操作系统,磁盘设备是基于bdev的伪文件系统来管理的,bdev文件系统是一个在内存中的伪文件系统,位置与Ext4等文件系统相同。8:57 / 6块设备可以随机访问,块设备的访问位置能够在介质的不同区间前后移动。块设备结构由以下几部分构成:Linux块设备基本构成页段块扇区扇区块扇区扇区块扇区扇区块扇区扇区8:57 / 7块设备总体结构:Linux块设备驱动8:57 / 8字符设备与块设备区别这两种类型的设备的根本区别在于它们是否可以被随机访问换句话说就是,能否在访问设备时随意地从一个位置跳转到另一个位置。字符设备仅仅需要控制一个位置当前位置而块设备访问的位置必须能够在介
3、质的不同区间前后移动。块设备可以随机存取,而字符设备不能随机存取。块设备通过系统缓存进行读取,不是直接和物理磁盘读取。字符设备可以直接物理磁盘读取,不经过系统缓存。8:57 / 9Linux块设备驱动框架linux i2c驱动架构:虚拟文件系统(VFS)磁盘缓存(Caches)磁盘文件系统 (Disk FS)块设备文件系统 (Block FS)映射层(Mapping Layer)通用块层(Generic Block Layer)I/0调度层(I/0 Scheduler Layer)bio结构体request queue块设备驱动(Block Device Driver)块设备驱动(Block
4、Device Driver)I/0请求( request结构体)硬件(Hard Disk)硬件(Hard Disk)file operationgendisk结构体硬件文件系统硬件系统8:57 / 10块设备的驱动开发过程相对固定,流程步骤如下:结构体与接口函数分配gendisk: alloc_disk分配/设置队列: request_queue,提供读写能力设置gendisk其他信息,提供容量等属性实现blk_init_queue注册add_disk8:57 / 11常用结构体结构体与接口函数结构体说明block_device描述一个分区或整个磁盘对内核的一个块设备实例gendisk描述一个
5、通用硬盘(generic hard disk)对象bio描述块数据传送时怎样完成填充或读取块给driverrequest描述向内核请求一个列表准备做队列处理request_queue描述内核申请request资源建立请求链表并填写BIO形成队列8:57 / 12Linux块设备驱动框架块设备驱动开发常用函数:int register_blkdev(unsigned int major, const char *name);int unregister_blkdev(unsigned int major, const char *name);struct gendisk *alloc_disk(
6、int minors);void del_gendisk(struct gendisk *disk);request_queue *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock);void blk_cleanup_queue(request_queue_t * q);static DEFINE_SPINLOCK(spinlock_t lock);static inline void set_capacity(struct gendisk *disk, sector_t size);8:57 / 13常用函数APILinux块设备驱动
7、框架void add_disk(struct gendisk *gd);void put_disk(struct gendisk *disk);struct request *elv_next_request(request_queue_t *q);void end_request(struct request *req, int uptodate);static inline void *kzalloc(size_t size, gfp_t flags);void kfree(const void *block);rq_data_dir(rq);8:57 / 14I/O调度程序通过两种方法来
8、减少磁盘的寻址时间:块设备I/O请求处理 合并指将两个或多个请求结合成一个新请求。合并 排序指整个队列请求将按照扇区增长的方向有序排列,不仅是为了缩短单独一次的请求寻址时间,更重要通过优化,保持磁头以直线方向移动,缩短所有请求的磁盘寻址时间。排序8:57 / 15块设备驱动的I/O请求处理有两种方式:使用请求队列和不使用请求队列。请求队列的处理流程如下:块设备I/O请求处理通知请求完成判断这一条请求的方向,向设备写还是读,然后将数据装入缓冲区从请求队列中拿出一条请求8:57 / 16块设备驱动的I/O请求处理使用请求队列:处理流程static int _int ramdisk_init(voi
9、d) /*块设备驱动注册*/ register_blkdev(RAMDISK_MAJOR, RAMDISK_NAME); /*使用请求队列的方式*/ ramdisk_queue = blk_init_queue(ramdisk_do_request, NULL); /*分配gendisk*/. /*初始化gendisk*/. /*添加gendisk到系统中*/.首先:从请求队列中拿出一条请求其次:判断这一条请求的方向,是向设备写还是读,然后将数据装入缓冲区最后:通知请求完成8:57 / 17块设备驱动的I/O请求处理不使用请求队列:static int _int ramdisk_init(vo
10、id) /*块设备驱动注册*/ ramdisk_major = register_blkdev(RAMDISK_MAJOR, RAMDISK_NAME); /*使用制造请求的方式,先分配ramdisk_queue*/ ramdisk_queue = blk_alloc_queue(GFP_KERNEL); /*再绑定请求制造函数*/ blk_queue_make_request(ramdisk_queue, &ramdisk_make_request); /*分配gendisk*/ . /*初始化gendisk*/ . /*添加gendisk到系统中*/ .8:57 / 18对于ramdisk
11、 这种完全随机访问的非机械设备,并不需要进行复杂的I/O 调度。所以,可以绕开I/O调度层。RamDisk块设备驱动分析虚拟文件系统(VFS)磁盘文件系统磁盘文件系统原始块设备块I/O调度层块设备驱动块设备驱动块设备驱动绕过I/O调度层8:57 / 19RamDisk块设备驱动开发块设备满足文件系统的读写操作的请求处理函数流程。使用blk_fetch_request循环地从请求队列中提取一个个请求并处理。使用_rq_for_each_bio循环地从请求中提取一个个bio并处理。使用bio_for_each_segment循环地从bio中提取一个个segment(扇区)并处理一个请求完成文件系统
12、报_blk_end_request_all(req, 0)8:57 / 20RamDisk块设备驱动分析l块设备操作详细流程。在入口函数中:使用add_disk()注册gendisk结构体使用kzalloc()来获取缓存地址,用做扇区设置gendisk结构体的成员使用alloc_disk()分配一个gendisk结构体blk_init_queue()使用分配一个申请队列,并赋申请队列处理函数使用register_blkdev()创建一个块设备8:57 / 21RamDisk块设备驱动分析l块设备操作详细流程。处理函数simp_blkdev_do_request(struct request_q
13、ueue *q): elv_next_request()申请队列中每个未处理的申请rq_data_dir()获取每个申请的读写命令标志 end_request()结束获取的每个申请8:57 / 22RamDisk块设备驱动分析l块设备操作详细流程。在出口函数中:使用put_disk()和del_gendisk()来注销,释放gendisk结构体blk_cleanup_queue()用于清除内存中的申请队列8:57 / 23开发实践RamDisk驱动程序开发将ramdisk驱动源码文件夹拷贝到共享文件夹内使用root权限将实验源码拷贝到虚拟机/home目录下面对Makefile编译将生产的.ko文件拷贝到共享文件夹把simp_blkdev.ko文件拷贝到开发板使用超级用户,进行加载在ramdisk上面创建文件系统进行挂载在当前目录创建一个文件夹,并拷贝到/mnt/tmp1目录行读操作验证,往文件里面写入数据456使用cat进行查看,终端打印出456说明读写成功进行卸载8:57 / 24项目思考Linux块设备的特性,与字符设备比较有哪些区别?绘制Linux块设备驱动架构图?块设备驱动是以何种方式对块设备进行访问?块设备驱动的I/O请求处理的两种方式有什么区别?
限制150内