Chinaunix首页 | 论坛 | 博客
  • 博客访问: 401826
  • 博文数量: 48
  • 博客积分: 764
  • 博客等级: 上士
  • 技术积分: 1133
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-17 13:29
文章分类

全部博文(48)

文章存档

2014年(5)

2013年(34)

2012年(9)

分类: LINUX

2013-07-29 01:51:38

== Structure ==
块设备的驱动包括几部分,如下:
0 首先,内核要支持,块子系统。
genhd_device_init()

1 想想设备,你最先可能想到什么呢?没错,设备号!
major_names管理整个系统的块设备号和设备名字的单一关系,除了名字之外找不到和实际设备的任何关系,固步自封的感觉。
register_blkdev()用来向major_names一个设备号,反之unregister_blkdev。

2 说到内核,结构设计堪称一绝,怎么个绝法?结构乃内核之根本。
我们知道unix,秉持着一切皆文件的思想,所以块设备的结构涉及到fs 和 硬件抽象两方面。
涉及到块设备结构,主要三个。
gendisk对一个硬件设备只有一个,由我们编写驱动时创建,被blk_register_region() hash在bdev_map。
block_device: 由内核创建,对应整个硬盘和分区,数量为分区数+1.
hdstruct:由内核创建,词汇对应分区具体数据和block_deviceblock一样。

3 bdev_map
在blk_register_region()中hash了所有的gendisk

4 devtmpfs 这个文件系统是完成/dev下面设备的节点的创建。

5 bdev pseudo filesytem 配合inode hashtable 找到 block_device。
在设备刚注册时和打开一个新分区时用到。目的是建立/dev下inode 和block_device的联系。

== Understand ==
内核加载驱动驱动时,驱动的执行过程
===================
0 首先,申请设备号
1 关闭或者启用request queue。
关闭request queue:blk_queue_make_request传进去一个自己写的不用处理queue的函数,就是终极函数了。
如果还想使用queue,blk_alloc_queue,自己申请一个。
开启request queue: 这个用blk_init_queue 传进去一个request_fn就好了,这个也是终极函数。
2 alloc_disk创建gendisk
3 add_disk 向系统添加gendisk。这个过程最复杂包括:
3.1 hash gendisk 到bdev_map
3.2 register_disk:
前半部分加到kernel moudle model, device_add,创建一个req结构,会被devtempfsd动态处理掉,在/dev下创建一个entry的inode。
此处,对比下char设备,可以用device_create()和mknod shell 命令两种方式。
device_create 也是通过device_add 到devtmpfsd创建/dev节点的indoe。
mknod这个shell命令和devtmpfsd 是两回事,mknode的切入路径是sys_mknod.不过最终都调用vfs_mknod.
udev知识在节点上做些装饰,真的设备节点还是由mknod和devtmpfsd创建的,以前一直混着。
块设备的节点,我们无法自己手动创建,而字符的可以。
 中部分:bdget_disk() 在bdev psueudo 创建bdev_inode
register_disk产生了两个inode,第一个在文件系统/dev下面的。
创建第一个inode后,init_special_inode 就会被调用,赋值def_blk_fops给inode的i_fop见ext3_read_inode
负责fs相关的内容。
另一个inode是bdev pseudo filesystem里面的,这个是为了快速找到block_device,这个inode通常秘不示人,不必关心。
负责和blk设备抽象的内容。这个inode是在后面blkdev_open->bd_acquire用到。
具体的用法是,bd_acquire->bdget->iget5_locked,更具体:
find_inode 将用设备号和blockdev_superblock的hash值在inode_hashtable中找到对应sb 和devt的inode。
有了这个inode就找到了block_device.
bd_acquire的最重要works是建立devtmpfs的inode->i_bdev和block_device的联系。
后半部分是blkdev_get,建立block_device gendisk hdstruct三者联系。
3.4blk_register_queue()
名不见经传。

阅读(1884) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~