发信人: liangvy() 
整理人: hahalee(1999-04-26 17:23:26), 站内信件
 | 
 
 
[版权所有,不得书面出版]
  Lenn<[email protected]>
  2。3Device Driver 进程的io要求到这里说的差不多了。上面也解说了对于文字型,块型的驱动程序接口,就 是dev_spec_vnodeop_opv_desc里定义的子函数那些。参考设备驱动程序,在sys/conf.h 里定义的结构体。block型是         struct bdevsw{                 d_open_t        *d_open;                 d_close_t       *d_close;                 d_strategy_t    *d_strategy;                 d_ioctl_t       *d_ioctl;                 d_dump_t        *d_dump;                 d_psize_t       *d_psize;       /*得到容量*/                 int             *d_flags;                        char            *d_name;        /*device 名*/                 struct cdesw    *d_cdev;        /*对应的文字型*/                 int             d_maj;          /*major号*/         }         文字型的则是         struct cdevsw{                 d_open_t        *d_open;                 d_close_t       *d_close;                 d_read_t        *d_read;        /* rawread() */                 d_write_t       *d_write;       /* rawwrite()*/                 d_ioctl_t       *d_ioctl;                 d_stop_t        *d_stop;        /* nostop()*/                 d_reset_t       *d_reset;       /* nullreset()*/                 d_devtotty_t    *d_devtotty;    /* nodevtotty*/                 d_select_t      *d_select;      /* deltrue*/                 d_mmap_t        *d_mmap;        /* nommap*/                 d_strategy_t    *d_strategy                 char            *d_name;        /*device名*/                 struct bdevsw   *d_bdev;        /*对应block型*/                 int             d_may;          /*major号*/         }
 
  两方面共同的部分有         xx_open(dev_t dev,int oflags,int devtype,struct proc *p)         xx_close(dev_t dev,int fflag,int devtype,struct proc *p)         xx_ioctl(dev_t dev,int cmd,caddr_t data,int fflag,struct proc *p) xx_open()用于打开device号的设备。xx_close()则用于关闭它。xx_ioctl()则对设备的 动作状态,机能的取得,设置等进行控制,它通过int cmd命令和参数caddr_t data对之 进行处理。xx_open()的oflags则是系统调用open()里指定的标志。xx_close()和 xx_ioctl()的fflag是每个文件描述符设定的标志。int devtype用来区别设备类型是文 字型的还是块型的。struct proc *p是本次要求的进程号。
          在文字型的操作里,有这三个函数         xx_read(dev_t dev,struct uio *uio,int ioflag)         xx_write(dev_t dev,struct uio *uio,int ioflag)         xx_select(dev_t dev,int which, struct proc *p) xx_read()/xx_write()是对device号的io,struct uio *uio 是io的buffer,int ioflag 标志io动作的option。例如,输入data没准备好的场合不用进入等待状态也可以。 xx_select()检查是否可以进行io要求。         在块设备的操作中,有一个函数         xx_strategy(struct buf *bp) 它处理io要求。struct buf *bp里面包含着device号,输入还是输出,io的buffer等。
          device号中的major号,对文字型的struct cdevsw *cdevsw[],对块型的struct  bdevsw *bdevsw[],作为配列的添加字使用。向这些配列登记,就可以调出device driver 的登记routine。         对cdevsw[]登记的过程在kern/kern_conf.c,它使用         int cdevsw_add(                 dev_t *descrip,         /*收集device号的变量的指针*/                 struct cdevsw *newentry,/*设置struct cdevsw的指针*/                 struct cdevsw **oldentry,/*旧的设定内容的返回领域*/         )         另一方面,对bdevsw[]的登记过程则使用         int bdevsw_add_generic(                 int bdev,               /*block型的major号*/                 int cdev,               /*文字型的major浩*/                 struct bdevsw *bdevsw,  /*设定struct bdevsw的指针,对应d_cdev*/         )         block型的device和char型的device有着一定的对应关系。这些结构体相互参考。 bdevsw_add_generic()从block的结构体开始,对作为char型的device的结构体进行初始化。 还有,network interface的devive driver,并没有向cdevsw[]和bdevsw[]登记。而且也没有 device号。网络间的package流,和进程间与网络间的package流也没有特别指明。         调用登记routine的时候,可以把文件系统的modules作为特殊设备文件参考。登记 routine在什么地方都可以调用。         。main()(@kern/init_mail.c)的初始化过程中登记的routine调用的时候,各个           device driver的modules里由宏SYSINIT()准备进行。         。确认device driver里的io设备的存在的时候,调用登记routine。         当调用登记程序段的时候,如果major号和/dev/MAKEDEV的major号有冲突的时候, 就调用全部无关性device file的处理routine,也可能没有预期的的灾难事情。还有别的 以外事情,就是当/dev里没有对应的特殊设备文件的时候,也就不能从进程进行参考。
  --
  Lenn  Tel:    0755-3913403(H) E-mail: [email protected] Oicq: Lenn 28663
  ※ 来源:.网易 BBS bbs.netease.com.[FROM: www2.dt.sanyo.co.jp]
  | 
 
 
 |