memdisk驱动与块设备驱动框架


memdisk指的是以memory为基础,实现一个模拟的block device,这样在内存中虚拟出一块“磁盘”,用来在系统运行期间临时保存一些经常被访问到的文件。它产生的最初原因是因为在我们的SOC虚拟验证平台Zebu/Haps等上面并没有Nand/eMMC这类存储,没有分区去保存system.img/userdata.img/cache.img等来供Android系统启动。

本文以memdisk为例子简单记录block device驱动框架、实现,以及block device与platform device关系。


块设备驱动框架

块设备是I/O设备中的一类,当我们的应用层对该设备读写时,是按扇区大小来读写数据的,若读写的数据小于扇区的大小,就会需要缓存区,可以随机读写设备的任意位置处的数据。

对于Linux块设备而言,只能以“块”为单位进行访问的设备,即一次性写入或者读出一个块整体,块是Linux定制的数据处理基本单位,大小通常由一个或者多个扇区组成,一般是512个字节的整数倍。

常见的块设备有Nand/eMMC存储、SD卡、光盘等.

从文件系统到磁盘

在Linux操作系统中,从用户态到磁盘的访问流程大致如下面框图所示:

各层API接口

分层 API Description Notes
Libc 没有访问权限 任何访问将产生域错误 lalala
Syscall 没有访问权限 任何访问将产生域错误 lalala
VFS 没有访问权限 任何访问将产生域错误 lalala
FS 没有访问权限 任何访问将产生域错误 lalala
Generic Block Layer void end_request(struct request *req, int uptodate) 结束获取申请 当uptodate==0表示使用该申请读写扇区失败,uptodate==1表示成功
IO Scheduler struct request *elv_next_request(request_queue_t *q) 通过电梯算法获取申请队列中未完成的申请 获取成功返回一个request结构体,不成功返回NULL
Block Driver int register_blkdev(unsigned int major, const char *name) 创建一个块设备 当major==0时表示动态创建,创建成功会返回一个主设备号
同上 unregister_blkdev(unsigned int major, const char *name) 卸载一个块设备 在出口函数中使用,major:主设备号,name:名称
同上 struct gendisk *alloc_disk(int minors) 分配一个gendisk结构 minors为分区数,填1表示不分区
同上 void del_gendisk(struct gendisk *disk) 释放gendisk结构 在出口函数中使用,也就是不需要这个磁盘了
同上 request_queue *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock) 分配一个request_queue请求队列 分配成功返回一个request_queue结构体
同上 void blk_cleanup_queue(request_queue_t * q) 清除内核中的request_queue请求队列 在出口函数中使用
同上 static inline void set_capacity(struct gendisk *disk, sector_t size) 设置gendisk结构体的扇区数(成员copacity) size等于扇区数
同上 void add_disk(struct gendisk *gd) 向内核中注册gendisk结构体 -
同上 void put_disk(struct gendisk *disk) 注销内核中的gendisk结构体 在出口函数中使用
Hardware 没有访问权限 任何访问将产生域错误 lalala

Android中磁盘mount过程

TODO...

uevent机制

见文章Linux设备驱动模型与uevent机制


memdisk的块设备驱动实现


memdisk的platform设备驱动实现


platform设备与块/字符设备

块/字符设备:根据访问设备的实际操作方式而言;
Platform设备:根据所在的总线类型而言,挂接在Linux虚拟的Platform总线上;


参考文档

Linux设备驱动详解
Linux块设备驱动之框架详细分析(详解)
Linux块设备驱动详解
块设备驱动架构分析
Linux DirectIO机制分析
Linux内核写文件流程
Linux 通用块层之DeadLine IO调度器
文件读写(BIO)波澜壮阔的一生
块层介绍 第一篇: bio层
块层介绍 第二篇: request层

Comments
Write a Comment