(莱昂氏unix源代码分析导读-30) device

                    

                                                                 By cszhao1980

我们现在必须放下身段看一看低层的IO操作了,复杂繁琐的外设。

 

PDP-11/40拥有两种外设:

(1)         Block device

(2)         Character device

 

简单说来,Block deviceblock来单位操作数据,而character device则以character为单位

操作数据。我们本章只讨论block device

 

struct bdevswblock device的“操控开关”,通过这个结构可以对此设置执行各种操作,

它由4个指针组成:

4617: struct bdevsw {

4618:     int (*d_open)();      /指向该设备的open函数

4619:     int (*d_close)();      /指向该设备的close函数

4620:     int (*d_strategy)();    /指向该设备的strategy函数(what’s this?)

4621:     int *d_tab;           /指向该设备的struct devtab

4622: } bdevsw[ ];

 

bdevsw [ ]数组则是unixblock device配置表:

4656: int (*bdevsw[])()

4657: {

4658:     &nulldev,    &nulldev,    &rkstrategy,    &rktab,     /* rk */

4659:     &nodev,     &nodev,     &nodev,        0,         /* rp */

…….

4667: };

 

对任何block device的操作都通过bdevsw [ ]数组进行——这样做的好处是高层函数可以

以相同的方法处理任何一种block device,即通过为block device配置各自的操作函数,就

屏蔽掉了低层的细节。

 

在我们讨论的模型中,仅有一种block device,即RK磁盘,而相应的bdevsw [ ]数组仅配置了

一种block设备。其他设备的操作函数为nodev,它将返回一个错误:

6566: nodev()

6567: {

6569:     u.u_error = ENODEV;

6570: }

 

【注】nulldev不同,它是个空操作(refer to 6577行)。

 

swapdev 是系统定义的用于swap的设备,它的高8bit称为major device number,将作为该设备

bdevsw数组内的index,如下所示,本模型中定义的swap设备为RK磁盘:

      4696:  int swapdev {(0<<8)|0

 

而低8bitminor设备号,与具体设备密切相关,在讲解RK磁盘时我们会讲到。

 

 系统也定义了majorminor,如下所示:

                 4604: struct {

4605:     char d_minor;

4606:     char d_major;

4607: };

 

还有个结构与device有关:

4551: struct devtab

4552: {

4553:     char d_active; /* busy flag */

4554:     char d_errcnt; /* error count (for recovery) */

4555:     struct buf *b_forw; /* first buffer for this dev */

4556:     struct buf *b_back; /* last buffer for this dev */

4557:     struct buf *d_actf; /* head of I/O queue */

4558:     struct buf *d_actl; /* tail of I/O queue */

4559: };

bdevsw结构中的d_tab指针实际上就指向该结构的变量。它记录的其实是设备的“状态”信

息——每个device在系统中都有一个对应的devtab结构,比如RK磁盘驱动器的为“rktab”:

5386: struct devtab rktab;

 

我们来看一下devtab的各项:

1 d_active:“忙”标记。一般说来,在启动device操作时,应该置1,当操作结束后,置0

2 d_errcnt;  error count (for recovery)

3.剩下的是4个指向struct buf的指针,可分为两对儿:

    1 d_actfd_actl

          构成了device的任务队列,其中,d_actf指向“对”头;d_actl指向“对”尾。

os要启动外设操作时,就在队列里添加一项,而外设操作结束后,会删除一项。

 

    2 b_forwb_back

          缓存区的头和尾。

 

 

博客地址:http://blog.csdn.net/cszhao1980

博客专栏地址:http://blog.csdn.net/column/details/lions-unix.html

你可能感兴趣的:((莱昂氏unix源代码分析导读-30) device)