发信人: 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]
|
|