UNIX的设备管理.ppt
《UNIX的设备管理.ppt》由会员分享,可在线阅读,更多相关《UNIX的设备管理.ppt(79页珍藏版)》请在三一办公上搜索。
1、第四章 UNIX的设备管理,设备管理的主要任务是管理系统中的所有外部设备。UNIX系统把设备分为两类:(1)块设备。用于存储信息,其对信息的存取是以信息块为单位的,如通常的磁盘、磁带等;(2)字符设备。用于输入/输出程序和数据,其对信息的存取是以字符为单位的,如通常的终端设备、打印机等。,4.1 设备缓冲管理 在现代操作系统中,无论是字符设备还是块设备,在进行I/O操作时,都须借助于缓冲,以缓和 CPU与 I/O设备速度不匹配的矛盾。在UNIX系统中也不例外,该系统分别为字符设备和块设备设置了缓冲池。一 块设备缓冲队列的结构 UNlX系统在文件子系统和块设备驱动程序之间设置了大量的数据缓冲区,
2、供磁盘和磁带机使用,以减少对磁盘的I/O操作次数。每个缓冲区的大小与盘块的大小相当,以便在一个缓冲区中存放一个或多个磁盘块内容。盘块的大小一般在5124096字节之间。由于盘块缓冲区的容量较大,使用上也较复杂,因此UNIX系统中的盘块缓冲区的组成方式不同于字符缓冲区。,1 数据缓冲区及其首部 每一个数据缓冲区均由两部分组成:一部分是用于存放数据本身的数据缓冲区,另一部分是缓冲控制块,也称缓冲首部,用于存放缓冲区的管理信息。两者一一对应,但缓冲首部与缓冲区在物理上并不相连,只是在缓冲首部中用一个指向对应缓冲区的指针,把两者联系起来(如下图所示)。,设备号 快 号状 态 指向数据缓冲区指针指向散列
3、队列上的前一个缓冲区的指针指向散列队列上的后一个缓冲区的指针指向空闲表上的前一个缓冲区的指针 指向空闲表上的后一个缓冲区的指针,1 数据缓冲区及其首部 每一个数据缓冲区均由两部分组成:一部分是用于存放数据本身的数据缓冲区,另一部分是缓冲控制块,也称缓冲首部,用于存放缓冲区的管理信息。两者一一对应,但缓冲首部与缓冲区在物理上并不相连,只是在缓冲首部中用一个指向对应缓冲区的指针,把两者联系起来(如下图所示)。,设备号 快 号状 态 指向数据缓冲区指针指向散列队列上的前一个缓冲区的指针指向散列队列上的后一个缓冲区的指针指向空闲表上的前一个缓冲区的指针 指向空闲表上的后一个缓冲区的指针,缓冲区头部结构
4、struct buf Int b_flags;/是个标志位,含状态信息,包括有B_READ,B_WRITE,等 struct buf*b_forw;/*后面*/struct buf*b_back;struct buf*av_forw;struct buf*av_back;int b_dev;/*主设备号*/int b_wcount;/*传输数据*/char*b_xmem;/*核心地址高字节*/char*b_blkno;/*块号*/char b_error;/*返回字符*/char*b_resid;/*错误后,没有被传输的字*/bufNBUF,缓冲首部还包括设备号和块号,以分别指出对应的文件系统
5、和磁盘上的数据块号。必须说明,在UNIX System V中,设备号并非物理设备号,而是逻辑设备号,核心把每一个文件系统看作一个逻辑设备。缓冲首部中的状态字段用于指出对应缓冲区的当前状态,用于表示缓冲区是否空闲、缓冲区是否为延迟写、是否有进程正在等待该缓冲区变为空闲、核心是否正在读或写该缓冲区等。缓冲首部还包括两个空闲链表指针及两个散列队列指针。前者分别指向空闲链表中的上一个和下一个缓冲区首部;后者分别指向散列队列中的上一个和下一个缓冲区首部。,struct devtab char d_active;/*忙的标志设备状态信息*/char d_errcnt;/*错误返回的数目*/struct b
6、uf*b_forw;/*相应设备相关联的各缓存列表第一个缓冲区*/struct buf*b_back;/*相应设备相关联的各缓存列表最后一个缓冲区*/struct buf*actf;/*空闲链表的头指针*/struct buf*actl;/*空闲链表的尾指针*/,2、缓冲池结构(1)空闲链表。为了对缓冲区进行管理,在核心中设置一个双向链接的空闲链表。系统初启时,将所有的、缓冲首部都链入空闲链表中。当需要一空缓冲区时,从空闲链表的首部摘下一缓冲区;释放一缓冲区时,将它挂在空闲链的末尾。,空闲表头标,缓冲区1,缓冲区2,缓冲区n,空闲表头标,缓冲区2,缓冲区1,向前指针,向后指针,(2)散列队列。
7、为了加速对缓冲区的查找,系统把所有的缓冲区分设备地、按其块号所计算的散列值的不同,组织成多个散列队列,每个散列队列仍是一个双向链,其中缓冲区的数目不断地变化,各块号的散列值用散列函数计算。由于每一缓冲区都在一个散列队列中,而空闲缓冲区又应链入空闲链中,因此一个空缓冲区可同时链入两个从列中,并使对一空缓冲区的查找可通过两种方法来进行:(1)若要求获得任一空缓冲区,从空闲链上去摘取第一个缓冲区是最方便的,(2)若要求寻找一特定的空缓冲区,则搜素散列队列更方便。,blmno 0 mod 4blmno 1 mod 4 blmno 2 mod 4 blmno 3 mod 4,28,17,98,3,4,6
8、4,5,97,50,10,99,35,3 缓冲区的分配 核心调用getblk过程分配缓冲区。当要读磁盘数据时,核心首先检查要读入的盘块内容是否已在某个缓冲区中,若发现已在某个缓冲区中,便不必再从磁盘上读入。仅当数据未在任何缓冲区中时,核心才须从磁盘上将数据读入,这时才须为其分配一空闲缓冲区。类似地,当要把数据写入一特定盘块时,核心应先检查该块内容是否已在某缓冲区中,仅当该块内容尚不在缓冲区中时,才须调用getblk过程,分配一空缓冲区。获取空闲缓冲区时应提供的输入参数是文件系统号和磁盘块号。getblk过程描述如下:,getblk过程分配缓冲区时,可分为五种情况:(1)缓冲块在散列队列上,并且
9、它的缓冲区是空闲的。(2)缓冲块在散列队列上,并且它的缓冲区当前为忙。(3)缓冲块不在散列队列上,从空闲表中分配一缓冲区。(4)缓冲块不在散列队列上,且空闲缓冲区表为空。(5)缓冲块不在散列队列上,且试图从空闲表中分配一缓冲区时,在空闲表中找到一个标为“延迟写”标记的缓冲区。getblk过程描述如下:,getblk(文件系统号,块号)while(没找到缓冲区)if(块在散列队列中)if(块忙)/*第五种情况*/sleep(等候“缓冲区变为空闲”事件);continue;/*回到while循环*/为缓冲区标记上“忙”;/*第一种情况*/从空闲表中摘下缓冲区;return(缓冲区);else if
10、(空闲表上无缓冲区)/*第四种情况*/sleep(等候“任何缓冲区变为空闲”事件);continue;/*回到while循环*/从空闲表上摘下缓冲区;if(缓冲区被标记为“延迟写”)/*第三种情况*/把缓冲区异步写到磁盘上;continue;/*回到while循环 从旧散列队列中摘下缓冲区;把缓冲区投入新散列队列;return(缓冲区);,blmno 0 mod 4blmno 1 mod 4 blmno 2 mod 4 blmno 3 mod 4,28,17,98,3,4,64,5,97,50,10,99,35,blmno 0 mod 4blmno 1 mod 4 blmno 2 mod 4
11、blmno 3 mod 4,28,4,64,98,50,10,99,35,3,17,5,97,空闲表头标,空闲表头标,a)在第一散列队列上搜索第4块,b)在空闲表上摘下第4块,缓冲区分配的第一种情况,blmno 0 mod 4blmno 1 mod 4 blmno 2 mod 4 blmno 3 mod 4,28,17,98,4,64,5,97,50,10,99,35,blmno 0 mod 4blmno 1 mod 4 blmno 2 mod 4 blmno 3 mod 4,28,4,64,98,50,10,99,35,3,17,5,97,空闲表头标,空闲表头标,a)搜索第18块,不在高速缓
12、冲中,b)在空闲表上摘下第1个缓冲区,分配给第18块,缓冲区分配的第二种情况,18,blmno 0 mod 4blmno 1 mod 4 blmno 2 mod 4 blmno 3 mod 4,28,17,98,3,18,64,5,97,50,10,99,35,blmno 0 mod 4blmno 1 mod 4 blmno 2 mod 4 blmno 3 mod 4,28,4,64,98,50,10,99,35,3,17,5,97,空闲表头标,空闲表头标,a)搜索第18块,空闲表上头两个缓冲区标记为延迟写,b)写第3、5块,把原分配给的第4块的缓冲区改为分配给第18块,缓冲区分配的第三种情况
13、,延迟,延迟,写,写,blmno 0 mod 4blmno 1 mod 4 blmno 2 mod 4 blmno 3 mod 4,28,17,98,3,4,64,5,97,50,10,99,35,blmno 0 mod 4blmno 1 mod 4 blmno 2 mod 4 blmno 3 mod 4,28,4,64,98,50,10,99,35,3,17,5,97,空闲表头标,空闲表头标,搜索第18块,空闲表为空,搜索第99块,该块忙,缓冲区分配的第四种情况,忙,缓冲区分配的第五种情况,4、缓冲区的释放 当核心用完某缓冲区时,可调用brelse过程将它释放,此前可能有些进程因等待使用该缓
14、冲区而睡眠,此时释放者进程应将它们唤醒。此外,还可能有进程因空闲链表空而处于等待状态,同样也应将它门唤醒。如果所释放的缓冲区中的数据是有效的,为使以后在某进程需要它时,能直接从缓冲区中读出而不必启动磁盘的I/O操作,可将该缓冲区链入空闲链表的尾部;否则(缓冲区中数据无效)应将它填入空闲队列的头部。空闲链表属于临界资源,为了保证其操作的互斥性,UNIX系统是通过提高处理机执行时的运行级,将中断封锁来实现的。brelse过程的描述如图5所示。,brelse 唤醒等待“无论哪个缓冲区变为空闲”这一事件的所有进程 唤醒等待“这个缓冲区变为空闲”这一事件发生的所有进程 提高处理机的运行级以封锁中断 缓冲
15、区内容是否有效?将缓冲区链入空闲表首部 将缓冲区链入空闲表尾部 降低处理机优先级 给缓冲区解锁 返 回 图5 brelse过程的描述,高速缓冲的优缺点:(1)缓冲区的使用提供了统一的磁盘存取方法,因为内核不凶大勺I/O的原因。(2)系统对进行I/O的用户进程没有做对齐数据限制。(3)高速缓冲的使用可减少访盘次数,从而提高整个系统的吞吐量,减少响应时间。(4)缓冲区算法有助于确保文件系统的完整性,因为它们维护的一个公共的、包含在高速缓冲中的磁盘块的单一映像。(5)高速缓冲的使用,使得当往用户进程中读或从用户进程中写时需要一次额外的数据拷贝过程。,4.2 核心与驱动程序的接口设备开关表 在UNIX
16、系统中,每类设备都有一个驱动程序,用它来控制该类设备。任何一个驱动程序通常都包含了用于执行不同操作的多个函数,如打开、关闭、启动设备、读和写等函数。为使核心能方便地转向各函数,系统为每类设备提供了一个设备开关表,其中含有该类设备的各函数的入口地址。通常,字符设备和块设备的驱动程序有所不同,相应地,它们所包含的函数也不完全相同。由系统中所有字符设备的设备开关组成一张字符设备开关表,由系统中所有块设备的设备开关组成一张块设备开关表。不论是哪种设备开关表,表中的每一行都是一类设备驱动程序的各函数的人口地址;表的每一列是执行相同操作的不同(设备类型)函数。下图给出了设备开关表与系统调用和驱动程序间的关
17、系。从图中可以看出,设备开关表是核心与驱动程序间的接口,系统调用通过设备开关表转向相应驱动程序的函数。,文件子系统,open close read write ioctl,open close mount unmount read write,高速缓存,块 设 备 开 关 表,字 符 设 备 开 关 表,Open close read write ioctl驱 动 程 序设 备 中 断 处 理 程 序,Open close strategy 驱 动 程 序设 备 中 断 处 理 程 序,中断向量,中断向量,设备中断,1 块设备开关表 struct bdevsw int(*d_open)();/
18、open函数的入口函数 int(*d_close)(),int(*d_stragegy)();int d_tab;bdevsw;这些都是函数指针,bedvsw中每一项都代表一个设备类型。这个结构前三个字段是函数指针。这样的结构设计巧妙,知道了这些指针的话,就可以让系统调用不同设备驱动程序的open,close,及策略过程。如果,要增加一个不同的块设备,只需bdevsw数组增加一个bedvswde的结构,就可以了。最后一个应该是一个指向后面将要提到的devtab结构。,系统为每一类块设备设置一个设备开关,如下图所示。其中,第一行为0号块设备的开 表 项关,它包括三个:(1)gdopen:是0号设
19、备专用的打开函数的入口地址,该函数用于在调用进程与被打开设备间,建立起一个连接,并初始化该设备驱动动程序的数据结构;(2)gdclose:是0号设备专用的关闭函数的入口地址,该函数用于终止调用进程与设备之间的连接;(3)gdstrategy:是策略函数的入口地址,该函数用于在数据缓冲区与块设备之间传输数据。块设备开关表的第二行是1号块设备的开关。,块 设 备 开 关 表 表项 open close strategy 0 gdopen gdclose gdstrategy 1 Gtopen gtclose gtstrategy,2 字符设备开关表 下图给出了字符设备开关表。表中共有六行,表明有六
20、类字符设备驱动程序。整个驱动程序含有下述五个函数的入口地址:(1)用于打开特定字符设备的函数,不同字符设备的打开函数不同,(2)关闭特定字符设备的函数,(3)读特定字符设备函数,(4)写特定字符设备函数,(5)用于预置该设备参数的函数及读取该设备预置参数的函数等的入口地址。,块 设 备 开 关 表 表项 open close read write ioctl 0 conopen conclose conread conwrite conioctl 1 dzbopen dzbclose dzbread dzbwrite dzbioctl 2 sysyopen sysclose sysread s
21、yswrite sysioctl 3 nulldev nulldev nulldev nulldev nulldev 4 gdopen gdclose gdread gdwrite gdioctl 5 gtopen gtclose gtread gtwrite gtioctl,4.3 系统调用与驱动程序接口 对于那些使用文件描述符的系统调用,内核从用户文件描述符的指针找到内核文件表以及索引节点,并检查文件类型,根据需要存取块设备或宇符设备开关表。它从索引节点中抽取主设备号和次设备号,使用主设备号作为索引值进人适当的开关表,根据用户所发的系统调用来调用驱动程序中的函数。设备文件与正规文件的系统调
22、用间的一个重要区别是:当内核执行驱动程序时,特殊文件的索引节点是不上锁的。这是因为驱动程序频繁地睡眠,等待着硬连接或数据的到来,因此内核不能确定一个进程要睡眠多长时间。如果对索引节点上锁,则其他存取此索引节点的进程(如通过系统调用stat)会无限期地睡眠下去,因为另一进程正在驱动程序中睡眠。设备驱动程序把系统调用的参数解释为对该设备的适当的参数。一个驱动程序维护着描述它所控制的每一设备单元状态的数据结构,根据该状态以及要做的动作(如输人或输出数据)执行驱动程序中的子程序和中断处理程序。下面,我们将详细的叙述每一个接口。,1系统调用open 为了以系统调用open打开一个设备,内核使用与它打开正
23、规文件同样的过程,即:分配一个内存索引节点,增加其引用数,赋予一个文件表表项和用户文件描述符,内核最后将用户文件描述符返回给调用的进程。所以打开一个设备看上去就像打开一个正规文件。然而,它在返回到用户态以前,调用设备专用的打开过程(下图):对块设备,它调用块设算法备开关表中的打开过程;对字符设备,它调用字符设备开关表中的打开过程。如果一个设备既是一个块设备又是一个字符设备,内核将根据用户所打开的特定的设备文件,调用适当的打开过程。依赖于所用的驱动程序,这两个打开过程甚至可以是相同的。设备专用的打开过程在调用的进程与被打开的设备之间建立起一个连接,并初始化私有的驱动程序数据结构。举例来说,对一个
24、终端,打开过程可以让进程进人睡眠,直到机器检测到一个(硬件)载波信号,该信号指示有个用户正试图注册到机器。然后它根据适当的终端的预置参数(如终端波特率)来初始化驱动程序数据结构。对于软设备如系统存储器,打开过程可能不需要做初始化工作。,算法 open*专为设备驱动程序*/输人:路径名,打开方式 输出:文件描述符 将路径名交换成索引结点,增加索引结点引用数,与正规文件打开一样,分配文件表中表项、用户文件描述符;从索引结点取主、次设备序号;保存上下文(算法 setjmp)以防驱动程序需要执行 Iongjmp;if(块设备)使用主设备号作为块设备开关表的索引;调用相应该索引的驱动程序打开过程:传递参
25、数为次设备号、打开方式;else 使用主设备号作为字符设备开关表索引;调用相应该索引的驱动程序打开过程:传递参数为次设备号、打开方式;if(open在驱动程序中失败)减少文件表、索引结点引用数;,当打开一个设备时,如果由于某种外部的原因进程必须睡眠,可能会发生这样的情况:从睡眠中唤醒该进程的事件可能永远不出现。例如,如果老也没有用户注册到某特定的终端时,打开终端的getty进程会睡眠很长时间,直到一个用户试图注册。内核必须能够从睡眠中唤醒该进程,并在收到一个软中断信号时取消open调用,即:由于未能打开设备,它必须重置索引节点、文件表表项、用户文件描述符这些它在进人驱动程序以前已分配的资源。因
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- UNIX 设备管理

链接地址:https://www.31ppt.com/p-6522535.html