别紧张,RK磁盘是一种非常简单设备——这一点从其代码量中也可以看出。
首先,它由一个控制器外加 1~8个devices组成,这8个devices编号为0~7,缓
冲头的b_dev的minor号记录的就是该device编号,为简单起见,我们不考虑多
于8个device的情况——对RK磁盘来说,b_dev的minor部分就是0~7,而major部分为0。
RK驱动器在core空间上有6个控制寄存器,其起始地址为“ RKADDR”
5363: #define RKADDR 0177400
通过下列struct可访问到这6个寄存器,莱昂对这几个寄存器有详细的介绍,再次不再赘述。
5376: struct {
5377: int rkds;
5378: int rker;
5379: int rkcs;
5380: int rkwc;
5381: int rkba;
5382: int rkda;
5383: };
要启动磁盘驱动,需要首先设置rkda、rkba、rkwc三个寄存器,然后,设置rkwc
——这就直接启动了磁盘设备。而磁盘操作结束后,会通过矢量地址220产生中断
——处理函数是“rkintr”。
首先看一下“rkaddr(bp)”,它会根据输入缓存头内的物理块号,来返回满足rkda寄
存器格式的值。这个函数容易让人困惑的地方是其对b_dev的处理——记住,我们的
模型里最多只有8个device,故“5430: if(m <= 0)”的结果一定为真。
函数devstart(bp, devloc, devblk, hbcom)用来启动磁盘驱动器,它有4个参数:
(1) bp: 缓存头,存放此次启动的各种配置信息;
(2) devloc:指向rkda寄存器,见上面所示struct;
(3) devblk:按rkda格式设置的Block信息,即rkaddr的返回值;
(4) hbcom:在我们的模型里,都为0。可忽略此项。
devstart的操作其实很简单,即按照我们前面所述配置各个寄存器(要理解这一点,
请仔细观察上面列出的struct,看看各个寄存器的位置关系),最后设置rkcs启动操作。
如下所示,rkstart是更高层一些的函数,它检查rktab的任务队列,如果还有任务
就调用devstart启动RK设备。
5440: rkstart()
5441: {
5442: register struct buf *bp;
5443:
5444: if ((bp = rktab.d_actf) == 0)
5445: return;
5446: rktab.d_active++;
5447: devstart(bp, &RKADDR->rkda, rkaddr(bp), 0);
5448: }
RK设备启动后,就自行进行工作,工作完成后通过220中断进入中断处理函数rkintr。
5451: rkintr()
5452: {
5453: register struct buf *bp;
5454:
5455: if (rktab.d_active == 0)
5456: return;
5457: bp = rktab.d_actf;
5458: rktab.d_active = 0;
5459: if (RKADDR->rkcs < 0) { /* error bit */
……
5468: }
5469: rktab.d_errcnt = 0;
5470: rktab.d_actf = bp->av_forw;
5471: iodone(bp);
5472: rkstart();
5473: }
简单起见,我们不讨论设备出错的情况,即5429行的判断一直为假。这样的话,整个
程序就很简单了:
(1) 首先,在进入rkintr时,设备的“忙”标记应该是置位的,否则,就是一个
“假中断”,直接退出即可;
(2) 清除“忙”标志,调用iodone()——它主要有两个功能:
i. 设置Done标记
p_flag =| B_DONE
ii. 通知等待的进程;
【注】:对iodone的描述偏简单了,因为对异步io来讲,情况更复杂些。
(3) 取下一个任务,启动之;
最后,介绍最后一个RK驱动程序——rkstrategy函数。事实上,前面介绍的内容多数
是RK驱动程序的内部函数,而rkstrategy才是驱动提供给OS的接口函数。正如莱昂所
说,该函数的开头几行似乎走了弯路,事实上对我们的模型而言,第5397~5401行可
忽略不看。剩下的内容就很清晰了:
(1) 参数abp指向一个缓存头,该结构内记录了要进行的操作信息;
(2) 检查要操作的磁盘块号,如果已经超出RK磁盘的最大块号则报错;
(3) 将abp指向的缓存头结构插入到rktab的任务队列中;
(4) 如果此时设备空闲,则调用rkstart启动磁盘操作。
博客地址:http://blog.csdn.net/cszhao1980
博客专栏地址:http://blog.csdn.net/column/details/lions-unix.html