日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

2 FreeBSD 核心( 五 )


ufs_write()則要考慮到文件大小的延伸 。




FreeBSD核心探討.8.驅(qū)動程序篇


2.3 Device Driver
進程的io要求到這里說的差不多了 。上面也解說了對于文字型,塊型的驅(qū)動程序接口,就
是dev_spec_vnodeop_opv_desc里定義的子函數(shù)那些 。參考設備驅(qū)動程序,在sys/conf.h
里定義的結(jié)構(gòu)體 。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()則用于關(guān)閉它 。xx_ioctl()則對設備的
動作狀態(tài),機能的取得,設置等進行控制,它通過int cmd命令和參數(shù)caddr_t data對之
進行處理 。xx_open()的oflags則是系統(tǒng)調(diào)用open()里指定的標志 。xx_close()和
xx_ioctl()的fflag是每個文件描述符設定的標志 。int devtype用來區(qū)別設備類型是文
字型的還是塊型的 。struct proc *p是本次要求的進程號 。

在文字型的操作里,有這三個函數(shù)
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沒準備好的場合不用進入等待狀態(tài)也可以 。
xx_select()檢查是否可以進行io要求 。
在塊設備的操作中,有一個函數(shù)
xx_strategy(struct buf *bp)
它處理io要求 。struct buf *bp里面包含著device號,輸入還是輸出,io的buffer等 。

device號中的major號,對文字型的struct cdevsw *cdevsw[],對塊型的struct
bdevsw *bdevsw[],作為配列的添加字使用 。向這些配列登記,就可以調(diào)出device driver
的登記routine 。
對cdevsw[]登記的過程在kern/kern_conf.c,它使用
int cdevsw_add(
dev_t *descrip, /*收集device號的變量的指針*/
struct cdevsw *newentry,/*設置struct cdevsw的指針*/
struct cdevsw **oldentry,/*舊的設定內(nèi)容的返回領域*/
)
另一方面,對bdevsw[]的登記過程則使用
int bdevsw_add_generic(
int bdev, /*block型的major號*/
int cdev, /*文字型的major浩*/
struct bdevsw *bdevsw, /*設定struct bdevsw的指針,對應d_cdev*/
)
block型的device和char型的device有著一定的對應關(guān)系 。這些結(jié)構(gòu)體相互參考 。
bdevsw_add_generic()從block的結(jié)構(gòu)體開始,對作為char型的device的結(jié)構(gòu)體進行初始化 。
還有,network interface的devive driver,并沒有向cdevsw[]和bdevsw[]登記 。而且也沒有
device號 。網(wǎng)絡間的package流,和進程間與網(wǎng)絡間的package流也沒有特別指明 。
調(diào)用登記routine的時候,可以把文件系統(tǒng)的modules作為特殊設備文件參考 。登記
routine在什么地方都可以調(diào)用 。
。main()(@kern/init_mail.c)的初始化過程中登記的routine調(diào)用的時候,各個
device driver的modules里由宏SYSINIT()準備進行 。
。確認device driver里的io設備的存在的時候,調(diào)用登記routine 。

推薦閱讀