精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>电脑技术>>● FreeBSD>>FreeBSD 核心探讨 (cool!)>>FreeBSD核心探讨.8.驱动程序篇

主题:FreeBSD核心探讨.8.驱动程序篇
发信人: 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]

[关闭][返回]