现在的位置: 首页 >> 操作系统 >> FreeBSD >> FreeBSD 核心 (2)
添加时间:2005-8-21 来源:网教中国 作者:
FreeBSD 核心 (2)

c nfs/nfs_vnops.c
spec_vnodeop_opv_desc miscfs/specfs/spec_vnops.c
umap_vnodeop_opv_desc miscfs/umapfs/umap_vnops.c
union_vnodeop_opv_desc miscfs/union/union_vnops.c
------------------------------------------------------------------------
这个基础上,spec_vnodeop_opv_spec里描述的操作群就是device driver
interface的东西!!

( 本小节完,待本岛主有空再继续 )



FreeBSD核心探讨.6.驱动程序篇

2.3 mount根目录之前的处理概要
mount根目录的时候,main()(@kern/init_main.c)的初始化的过程从xxx_vfs_mountroot()
(@kern/init_mail.c)被调用开始。如果处理过程正常,就对rootvp设定包含了root的
v-node。
。main()的初始化过程中,configure()(@autoconf.c)被调用。在这个,io设备
初始化完了后,就转移到如下两个变量的地址:一个是mountroot,是处理mount的routine,
另一个是mountrootvfsops,是处理虚拟文件系统的routine。在本机磁盘中,就进入变量
rootdev所指定的disk号中。这里就是,假定本机磁盘
mountroot vfs_mountroot
mountrootvfsop &ufs_vfsops
rootdev boot disk number

。xxx_vfs_mountroot()(@kern/init_main.c)
运行(*mountroot)(mountrootvfsops)后,就指明了root file system的mount.
。vfs_mountroot()(@kern/vfs_conf.c)
管理mount的了文件系统的信息的struct mount(@sys/mount.h),对它进行确认
,然后设定传递过来的对虚拟文件系统的操作群(&ufs_vfsops),才进行"root"
标记。根据VFS_MOUNT(mp,...)进行mount这个虚拟文件系统。mount成功后,就
追加file system的list。这里,由于传递了&ufs_vfsops,就可以调用
ffs_mount()(@ufs/ffs/ffs_vfsops.c)
。ffs_mount()
首先调用bdevvp()(@kern/vfs_subr.c),进行VBLK类别,spec_vnodeop_p
(@misc/specfs/spec_vnops.c) v-node操作,保证设定了驱动号的rootdev的
v-node的最新信息,然后设定rootvp。最后,通过ffs_mountfs()调用进行实际
的mount rootvp操作。
。ffs_mountfs()
各种各样的检查完了后,调用VOP_OPEN(),打开rootvp的v-node。在这里,如果
v-node的v_op成员在spec_vnodeop_p存在的话,就调用spec_open()(@misc/
specfs/spec_vnops.c)。
.spec_open
由于VBLK里包含v-node的种类,从v-node指定的device号取得major的
号,调用对应driver的XXopen() routine

续上,由VOP_IOCTL()(还是的通过spec_ioctl()(@misc/specfs/spec_vnops.c))
可以得到partition信息,然后该检查super block的内容。正确的话,就在struct
ufsmount(@ufs/ufs/ufsmount.h)设定unix file system,这样处理过程就完了。

2.2.4 struct buf 和block的输入输出routine
前节的ffs_mountfs()提到使用bread()(@kern/vfs_bio.c)读出partition的
super block。这个接口函数很快就会解释。它主要用于读取block型的device到
kernel内部的buffer中。
bread(struct vnode *vp, /*(in)输入对象的v-node*/
daddr_t blkno, /*(in)block号*/
int size, /*(in)读出的byte数量,block长的倍数*/
struct ucred * cred,/*(in)权限信息*/
struct buf ** bpp)/*(out)存储读来的data*/
同样的buffer link后的block输出的子程序是bwrite()。
bwrite(struct buf *bp) /*(out)可以输出的struct buf*/
两者之间共同的地方就是struct buf(@/sys/buf.h),它用于io处理中给device driver
做桥梁作用的数据结构。它记录了v-node,io的区别,可以io的block位置/byte数,存
储实际data buffer的address,io处理的进展情况等。

bread则通过getblk()对block输入的结构struct buf进行操作。getblk()调用在核心
管理buffer link和返回指定大小的block的struct buf。这个(缓冲区)内容在目的
block是否存在与指定v-node的指定位置block是否已经构成缓冲环有关。struct buf
里面有一个标志位,当缓冲环内容变化是,这个标志位就会改变。bread()根据这个
flag判断block是否已经缓冲,如果已经完成,它就终止退出。如果不是这样,则在
struct buf的mark里面标志,然后调用VOP_STRATEGY()。在v-node登记的strategy
routine记录了io处理的过程,所以bread()当实际的处理完了后,就调用biowait()
进入等待状态。然后,就转移到别的进程A。io处理完了后,调用biodone(),进程A
也可以继续进行。还有,调用bread()的一边,当完成操作后,就调用brelse(),在
里面对struct buf的flag重新设置,让它对别的程序开放。

bwrite也是同样的通过VOP_STRATEGY()对io处理要求进行登记,同时也调用biowait()
进入等待状态,同样,当实际操作完了后,也设置flag进行复位,使得其他程序可以
使用io,当空闲的时候,io就挂起,转向其他进程处理。
进程等待进入的时候,当然不限于只是调用biowait()。在bread()或者bwrite()之前,
系统必须分配足够的资源供它使用,比如一些缓冲区等。当进行实际io时候,1个block
也可以,多个block也可以,而且这样可以获得更高的效率,这样看起来,就象实际上
是连续操作了。
(代续)



FreeBSD核心探讨.7.驱动程序篇

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(

上一页 [1] [2] [3] [4]  下一页


上一篇:FreeBSD 核心 (1) 下一篇:FreeBSD内核定制参考
大部分文章摘自网上,如有侵犯您的权益请与我们联系,我们会第一时间进行处理,谢谢! [ 打印文章 ] [ 关闭窗口 ]
推荐文章
·FreeBSD handbook中文版 9 配制F
·FreeBSD 升级系统
·Ports & Package
·FreeBSD kernel 编译大法(二)ker
·FreeBSD 上使用Kerberos 5认证
·FreeBSD 5.x 中 gbfs 的修正,及
·FreeBSD 安装Linuxigd
·FreeBSD 使用cvsd创建安全的cvs
·FreeBSD trafcount命令介绍
·FreeBSD入门安装及汉化
相关文章
·FreeBSD 核心 (1)
·FreeBSD4.8 IPFW How to!
·FreeBSD下的内存文件系统
·FreeBSD内核定制参考
·freebsd系统日志与备份
·关于FreeBSD4.4网络源代码接口层
·FreeBSD 5.2.1 boot0(启动扇区代
·FreeBSD中的设备命名规则
·FreeBSD 5内核源代码分析之copyi
·FreeBSD 5内核源代码分析之系统
最新文章
·FreeBSD连载(94):基于NAT的负载
·FreeBSD连载(93):反向代理负载
·FreeBSD连载(92):基于DNS的负载
·FreeBSD连载(91):提升静态网页
·FreeBSD连载(90):单服务器性能
·FreeBSD连载(89):CGI和SSI的安
·FreeBSD连载(88):安全连接方式S
·FreeBSD连载(87):基于用户的访
·FreeBSD连载(86):对IP地址和域
·FreeBSD连载(85):配置Apache服(
Google