精华区 [关闭][返回]

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

主题:FreeBSD核心探讨.7.驱动程序篇
发信人: liangvy()
整理人: hahalee(1999-04-26 17:24:09), 站内信件

[译者:Lenn<[email protected]>]
[版权所有,不得书面出版]

2。2。5系统调用open()的处理概要
        进程通过系统调用read()/write()进行io处理,它由文件描述符指定对哪里进
行i/o,文件描述符是0以上的整数,它在各个进程的struct proc的成员
struct filedesc *p_fd(struct filedesc(@sys/filedesc.h))保留的struct file
((@sys/file.h)进行选择添加。对struct file,它含有从文件的头的输入输出的byte
位置,输入操作,输出操作,输入输出控制,输入输出的准备状态的检查,执行close
的routine,以及描述io处理对象的信息(v-node,socket,pipe) 。系统调用open()
(@kern/vfs_syscalls.c)就是把包含路径信息的v-node找寻出来,为了对它进行io处理,
先要对struct file进行初始化,然后返回文件描述符。
        从路径名查找v-nodehe和io准备操作由vn_open()(@kern/vfs_vnops.c)承担。
vn_open()通过namei()(@kern/vfs_lookup.c)查找路径对应的v-node名,由VOP_OPEN()
调用不同的v-node定义的准备过程routine。例如,有如下的处理方法。
        。普通的file/directory
          调用ufs_open()(@ufs/ufs/ufs_vnops.c),检查open的mode
        。特殊设备文件
          调用spec_open()(@miscfs/specfs/spec_vnops.c)
          文字型        调用device driver的open routine
          快型          mount的时候出错。如果不是这样,就调用device driver的
                        open routine。

        回过头来,namei()的任务是就是,对于指定的路径名,对应于跟目录或者当
前目录的v-node作为起点,通过lookup()(@kern/vfs_lookup.c)进行v-node查找。
lookup()从路径名开始的v-node(VDIR)开始查找。找到了的v-node作为新的起点继续进行
查找下一步的要素名,然后得到目的的v-node。这个时候,根据v-node的不同,目录的检
索方法也就不同。各个要素的实际检索由VOP_LOOKUP()来做。

2。2。6系统调用read()的处理概要
        open()取得文件描述符后,对它的输入处理,有如下的流程。指定的文件描述符
的struct file内登记的处理routine有vn_read()(@kern/vfs_vnops.c),vn_write(),
vn_ioctl(),vn_select(),vn_closefile(),v_node
登记的操作routine不能分开使用。vn_*()里,只有在合适的前缀操作下,才能正确调用。
        read()首先在struct uio(@sys/uio.h)登记进程指定的buffer的位置和长度。
执行read()后,vn_read()向struct file设定登记的文件的读写位置,然后调用VOP_READ()。
根据读出来的byte数,读写位置相应增加。
        VOP_READ()的call routine则是与v-node有关,就象下图一样。

                                        vn_read()
                        文字型/块型       |
                        /------------------
                        |                 | file/directory
                  spec_read() ---------ffs_read()-------VOP_READ()
        block型         |                 |
        /---------------|char型           |
        bread()       device driver    bread()
        |                                 |
        spec_strategy() ---------------ufs_strategy() --VOP_STRATEGY()
        |                                 |                         |
        |                                 |                         |
        device driver                  spec_strategy() -------------/
                                          |
                                          |
                                       device driver


        。普通的file/directory
          调用ffs_read()(@ufs/ufs/ufs_readwrite.c)。对应指定的读写位置,计算block
          的位置,然后用bread()读出来。读出来的数据送到进程所准备的缓冲区。从bread()
          传递过来的block并不是物理block的位置,而是把file作为block列的一个理论值。
          从理论块到物理块的变换由VOP_STARATEGY()完成。也就是说,ufs_strategy()先把
          文件内位置转化为物理block位置,然后从v-node记录的i-node把表示物理设备的
          v-node 去出来,这个VOP_STRATEGY就调用spec()(@miscfs/specfs/spec_vnops.c)
          让它进行输入要求。
        。特殊设备文件
          通过调用spec_read()(@miscfs/specfs/spec_vnops.c),把它分为文字型和块型两类。
          文字型        调用device driver的输入routine
          块型          通过bread()进行输入处理

        对文件的系统调用write()的场合也是类似的处理流程(ufs_write()->bwrite()),
ufs_write()则要考虑到文件大小的延伸。

--

Lenn 

[email protected]

Oicq: Lenn 28663

※ 来源:.网易 BBS bbs.netease.com.[FROM: www2.dt.sanyo.co.jp]

[关闭][返回]