首页 » 智能 » 操作系统是若何访问IO设备的?_装备_存放器

操作系统是若何访问IO设备的?_装备_存放器

乖囧猫 2024-11-30 15:14:34 0

扫一扫用手机浏览

文章目录 [+]

IO构造层次

因此,本篇文章分为5个部分,逐步阐述操作系统访问IO设备的过程

操作系统是若何访问IO设备的?_装备_存放器 智能

IO设备分类设备掌握器设备驱动程序内核IO子系统操作系统掌握IO设备的流程举例IO设备分类:

IO设备大致分为块设备,字符设备,网络设备,定时器等,本篇文章紧张关注的是块设备,字符设备,网络设备,这些设备是我们程序开拓中常常涉及的部分。

块设备:

块设备将数据分隔成多个固定大小的块进行存储,块是数据存储的最小单位,每个块的大小可以为512字节-65536字节,每个块都有唯一的地址,因此块设备是可以寻址的,每次读写块设备的数据时,都因此块为最小单位读取或者写入连续的多个块。

例如磁盘便是块设备,它的块大小常日是512个字节即是磁盘的一个扇区的大小,因此一个扇区便是一个块,磁盘的数据是由很多个扇区构成。

常日块设备可以顺序访问或者随机访问,运用程序访问块设备时,常日不是直接访问的,而是通过文件系统,文件系统对块设备进行统一管理,将块设备的各种细节封装起来,文件系统管理的是逻辑设备即文件,文件系统统一供应read,write,seek等接口间接访问块设备,文件系统将文件名和块设备的每一个块之间的映射关系隐蔽起来,因此块设备对付运用程序来说是透明。

当然有些分外的运用程序例如数据库管理系统可以直接访问块设备,对块设备的每个块采取专用的数据构造进行管理,以达到最佳的读写效率,这些专用的数据构造有B+树,LSVM树等,这些数据构造都有各自的运用处景。

字符设备:

字符设备是不可以存储和不可以寻址的,字符设备每次读入或者写入一个字符,常见的字符设备包括鼠标,键盘,打印机等,操作系统常日会供应一些get或者put的方法来读取或者写入一个字节,常日会有标准库对操作系统供应的get或者put方法进行封装,例如增加了字符缓冲,支持字符流读写,支持按行读,按行写,编辑缓冲数据等。

网络设备:

网络设备常日用于发送或者接管网络数据,这些网络数据常日是网络包的形式,不同于块设备,操作系统会供应专门的网络接口进行网络数据的发送和接管,网络接口常日便是Socket,这个socket是传输层协议的代理,我们通过socket就可以处理网络数据了。

对付Socket它就像一个电源插座,任何电器都可以插入电源插座,一旦插入电源插座就可以通电,因此运用程序也可以用创建一个Socket,Socket分为做事端Socket和客户端Socket,做事端Socket启动后,会一贯监听来自客户端Socket的来电,一旦接到来电就可以转给一个接线员,这个接线员也是一个Socket,由它来卖力与客户端Socket的通信。

Socket常日支持BIO,NIO,AIO几种模式,不同的操作系统支持的模式不同,常日都支持BIO和NIO,根据不同的运用处景可以选择不同的模式,没有绝对可言。

定时器:

定时器常日分为硬定时器和软定时器。

硬定时器:

硬定时器常日是由晶体震荡器,计数器和存储寄存器组成,当把一块石英晶体适当地切割后,并在它上加上一定的电压后,它就可以非常精确地产生周期性的时钟旗子暗记,这些旗子暗记的频率可以是几百赫兹,几千赫兹等,这个频率值跟所选的晶体类型有关。

硬定时器的基本事理是这样的:

每个定时器会在存储寄存器设置一个计数值,每次定时器启动时,将这个计数值设置到计数器中,每次晶体震荡后,产生一个时钟旗子暗记,该旗子暗记被送入到计数器,计数器就减1,直到计数器变为0,那就表示定时器触发了,它会给CPU发送一个时钟中断,CPU吸收到这个中断后会进入时钟处理程序。

时钟处理程序会进行一些防止进程韶光片超时,进程CPU利用情形记账,掩护打算机韶光,打算机硬件监控,进程性能数据阐发等事情。

硬件定时器可以分为一次性定时器和永久性定时器,一次性定时器表示定时器触发后后,就自动停滞了,永久性定时器则每次定时器触发后,会将存储寄存器中的计数值重新赋值给计数器,然后重新启动定时器,一贯运行,直到打算机关闭。

软定时器:

有些高性能的事情须要高频率地实行,例如一个高性能的网络,网络带宽为千兆级别以上,为了担保高效率地输出,每隔12us就要发送一个数据包,如果采取硬定时器,每隔12us产生中断后,会进行一系列的处理,包括进程高下文,流水线,高速缓冲,TLB,MMU等重新切换等,这一繁杂的切换事情须要的韶光可能已经靠近12us,那么这就意味着从中断开始到真正开始发送数据包,会经由一段韶光,这个韶光对付一个高性能的网络来说是不能容忍的,因此这种场景可以采取软定时器,软定时器不须要中断,每次发送数据包时,会根据硬定时器+12us设置一个超时时间,每次发送完数据包切换到用户态后,用户程序检讨这个超时时间是不是已经由期了,如果过期了就立即发送一个数据包,对付这类高性能的场景,软定时器比较得当,当然如果没有哀求那么高的性能哀求的话,一样平常的硬定时器中断足够搪塞了。

设备掌握器:

操作系统是不直接操作IO设备,常常是通过设备掌握器间接访问IO设备,可以说设备掌握器是CPU与IO设备的桥梁,设备掌握器可以连接单个设备,也可以同时连接多个设备,如果连接多个设备,设备掌握器和设备之间须要增加一个仲裁设备,这个仲裁设备卖力仲裁设备掌握器要和那个IO设备进行交互。

设备掌握器卖力的事情如下:

卖力掌握IO设备,例如设备的读,写,打开,关闭等。
折衷CPU和IO设备速率读写速率的不匹配,例如设备掌握器增加数据缓冲。
CPU和IO设备数据旗子暗记的转换。
CPu时钟频率和IO设备时钟频率的折衷和同步。
IO端口地址的译码,例如翻译IO端口地址到详细的设备寄存器。

设备掌握器供应了4种寄存器即状态寄存器,数据输入寄存器,数据输出寄存器,掌握寄存器,操作系统和设备掌握器之间的交互便是通过这些设备寄存器,因此它们的交互办法类似于生产者和消费者的关系。

数据输出寄存器:

操作系统可以将CPU寄存器的数据发送到数据输出寄存器,设备掌握器得知数据输出寄存器有数据后,就将数据输出寄存器的数据发送给IO设备。

数据输入寄存器:

设备掌握器读入IO设备的数据后,存储在数据输入寄存器,然后操作系统读取数据输入寄存器的数据到CPU寄存器中。

状态寄存器:

存储设备干系的状态,例如设备是否已经就绪,数据输入寄存器是不是有数据了等,操作系统可以读取该寄存器的值来查看设备的各种状态。

掌握寄存器:

操作系统可以写入掌握寄存器从而奉告设备掌握器实行什么IO操作。

其余,为了折衷CPU和IO设备的读写速率差异,设备掌握器常日有数据缓冲,用于缓冲从设备读入的数据,或者从操作系统写入的数据,例如操作系统将数据写入到数据输出寄存器后,设备掌握器将数据输出寄存器的数据直接写入到数据缓冲,而不是直接发送到IO设备,这个很好理解,由于设备掌握器写入数据到IO设备的速率与CPU的发送速率比较差异太大了。

操作系统怎么读写设备寄存器呢,有两种办法

1.IO指令

每个设备寄存器都有一个地址,它与内存的地址不同,这个地址称为IO端口地址,操作系统支持的IO端口地址有65536个即0~64K-1,IO端口地址的范围叫做IO端口空间,内存地址范围叫做内存空间,因此IO端口空间与内存空间是独立的。

如果CPU要读取一个端口地址对应设备寄存器,过程如下:

1.CPU将IO端口地址放到地址总线上,然后在掌握总线上设置一个READ旗子暗记,此时只是CPU只是要表明要读取某个地址的数据了,至于这个地址来自哪个空间,还须要下一步操作。

2.CPU设备其余一条旗子暗记线,设置旗子暗记线要访问IO端口空间。

3.所有的设备掌握器吸收到该旗子暗记线后,创造是访问IO端口空间,就会检讨地址总线上的地址是不是自己的寄存器的地址,总有一个设备掌握器接管这个地址,不是自己的地址设备掌握器直接忽略这个旗子暗记。

下面表格为PC设备中常见的设备IO端口地址分布图

IO端口范围(十六进制)

设备

000-00F

DMA掌握器

020-021

中断掌握器

200-20F

游戏掌握器

320-32F

硬盘掌握器

3D0-3DF

图形掌握器

3F0-3F7

软盘掌握器

其余,CPU供应了专门的IO指令,通过IO指令发送内容到IO端口地址或者从IO端口地址获取内容来实现设备寄存器的读写,

常见的IO指令有IN和OUT

IN AX,DX

DX寄存器存储的是IO端口,该指令表示获取IO端口指向的设备寄存器的内容到AX寄存器。

OUT DX,AX

DX寄存器存储的IO端口,该指令表示将AX寄存器的内容写入到IO端口指向的设备寄存器。

2.内存映射IO

CPU访问任何数据都是通过地址总线,一个32位的地址总线可以寻址的范围是4个G,从上文知道,如果有IO端口地址空间的话,须要单独的一个旗子暗记线表明地址线访问的那个空间,假设该旗子暗记线访问的是内存空间。

这个内存空间内大部分地址分给了主存,还有一小部分地址落在了其它的内存或者设备寄存器,例如图形掌握器的数据缓冲,BIOS的ROM等,常日这部分地址在地址总线范围的低地址处,如下图

内存映射IO

因此通过内存映射IO,我们不须要专门的IO指令,直接通过内存干系的指令例如MOV,LOAD等命令就可以读写设备寄存器或者设备掌握器的数据缓冲,当地址总线上写入了地址后,主存,设备掌握器,BIOS等都会检讨这个地址是不是属于自己的范围,如果是自己的范围内的地址,就会接管这个地址,并且做出相应。

操作系统与设备掌握器交互的办法常日有3种:

程序掌握IO

程序掌握IO也叫轮询,假设CPU写数据到IO设备,常日运用程序会在用户空间分配一个缓冲,用户缓要冲发送的数据,然后进行系统调用,通过系统调用,内核会将用户缓冲拷贝到内核缓冲,这个内存缓冲可以认为是一个发送数组,然后对发送数组的每个字节逐个按照以下流程写入到IO设备,流程如下图所示:

CPU轮询办法会一贯检讨状态寄存器,一贯到状态寄存器不忙时,才会写入发送数组确当前字节到数据输出寄存器,同时设置掌握寄存器的写位和就绪位,关照设备掌握器要实行一个写操作而且数据已经准备好了。

设备掌握器检讨到掌握寄存器的就绪位已经就绪后,会进一步检讨要实行什么操作,创造写位为1,就会从数据输出寄存器获取数据,写到IO设备,完成后,就会打消掌握寄存器的就绪位,忙位,故障位,这样CPU就会连续写入数据了。

IO设备的写速率与CPU比较差的十万八千里,因此CPU大部分的韶光都在检讨状态寄存器的忙位,摧残浪费蹂躏了大量的CPU韶光,这也是轮询办法最大的缺陷。

中断驱动IO

假设CPU写数据到IO设备,常日运用程序会在用户空间分配一个缓冲,用户缓要冲发送的数据,然后进行系统调用,通过系统调用,内核会将用户缓冲拷贝到内核缓冲,这个内存缓冲可以认为是一个发送数组,然后对发送数组的每个字节逐个按照以下流程写入到IO设备,假设发送数组剩余要发送的字节数为count,如下图所示为中断驱动IO的流程图

由上图所示分为3个子流程

CPU写入流程:

CPU写入流程与轮询看起来有点类似,不一样的地方在于,用户进程在写入第一个数据到寄存器后,就被壅塞了,CPU此时调度其它进程运行。

设备掌握器流程:

这个流程与轮询中的设备掌握器流程比较类似,不同的是,设备掌握器写数据到IO设备后,会发送一个设备中断旗子暗记给CPU,关照CPU可以连续发送数据了。

CPU中断处理程序:

每次CPU实行时,会先检讨中断线上是不是有中断旗子暗记,如果有中断旗子暗记,就会去实行中断处理程序,对付设备的中断处理程序,如果没有发送的数据了,就将用户进程加入到CPU的就绪行列步队中,CPU后续会调度用户进程,壅塞就解除了,调用就返回了,如果有发送的数据,就连续发送到设备掌握器的寄存器中。

中断处理程序返回后,会被切换到被中断的进程,连续实行。

中断驱动IO比较轮询来说,不须要CPU一贯等IO设备写入完成,而是可以将写入寄存器后,直接壅塞,调度其它的进程来利用CPU,当IO设备写入完成后,发送中断旗子暗记,关照CPU,CPU实行中断处理程序连续写入下一个字节,终极发送完成后,解除壅塞,这样CPU就可以充分利用,减少了CPU的摧残浪费蹂躏。

DMA

假设CPU写数据到IO设备,常日运用程序会在用户空间分配一个缓冲,用户缓要冲发送的数据,然后进行系统调用,通过系统调用,内核会将用户缓冲拷贝到内核缓冲,这个内存缓冲可以认为是一个发送数组。

DMA的处理流程如下:

DMA

DMA的处理流程也可以分为3个子流程

CPU流程 :

CPU传输发送数组的起始地址,发送数组的大小给DMA,此时用户进程A就从CPU运行行列步队移除,此时用户进程A壅塞,CPU调度其它的进程运行。

DMA流程:

DMA根据发送数组的起始地址,检讨尚未发送的字节数count,如果count<0, 那么便是传输数据给设备寄存器,然后就等待设备掌握器的应答,如果 count=0,那么DMA发送完成了,它会给CPU发送一个中断旗子暗记,CPU收到这个中断旗子暗记后,会实行DMA的中断处理程序,将用户进程A加入到CPU的就绪行列步队,后续CPU会调度用户进程A去运行,这个时候用户进程A调用返回。

设备掌握器流程:

设备掌握器的流程与轮询和中断类似,只是设备掌握器发送完数据后,会发送一个应答给DMA,DMA收到这个应答后,会将coun-1,然后调度发送下一个字节。

可以看出DMA不须要设备掌握器发送中断给CPU,它成为了CPU的代理,CPU可以专注地做其它的事情,只是DMA传输完成后,才会中断一下CPU。

其余DMA每次掌握设备掌握器写数据时,都会先掌握住地址总线,这样就会跟CPU抢时钟周期,这个也是不可以避免的。

DMA掌握器可以连接多个设备掌握器,通过一定的算法,来切换每次掌握的设备掌握器,其余繁芜一些的DMA掌握器也可以一次掌握设备掌握器发送多个字节,这样一次性霸占地址总线的韶光就比较长,这样的效率也会更高,只是CPU如果此时须要用地址总线,那就须要等待一段韶光了,CPU周期被摧残浪费蹂躏了。

设备驱动程序

我们上面阐述操作系统通过掌握设备掌握器来间接掌握IO设备,实在便是设备驱动程序来掌握设备掌握器。

设备驱动程序常日位于内核,它封装对设备掌握器操作的所有细节和差异,并且供应了标准的接口供内核的IO子系统调用,这一点类似于网络协议的分层构造,每一层将数据封装好后供应给上一层利用,上一层不用考虑下一层的实现细节。

可以说设备驱动程序将硬件和IO子系统调用分离开来,每一类设备都须要专门的设备驱动程序进行掌握,一样平常这些设备驱动程序都是由设备供应商来卖力编写,常日不同的操作系统设备驱动程序都有不同的开拓标准,因此只要设备供应商按照操作系统哀求的标准开拓设备驱动程序,增加任何的IO设备和掌握器对付操作系统来说都是透明的,当然这对操作系统来说好处多多,对付设备供应商来说好处不多,他们须要为各种操作系统系统编写驱动程序,这样才能争取不同操作系统的用户。

常日设备驱动程序不添加任何用户策略,只卖力与硬件打交道,它常日会将上层IO子系统发送过来的抽象的读写要求,转化为实际的对硬件的IO操作,担保硬件可用并供应硬件原始数据,原始的数据交由IO子系统进行二次加工,IO子系统再根据根据各种用户策略对原始数据进行处理。

IO子系统

IO子系统位于内核,处于设备驱动程序的上一层,它是设备无关的,紧张供应文件系统,IO调度,缓冲,高速缓冲,设备保护,缺点处理等。

增加新的设备驱动程序对IO子系统没有i影响,由于每个设备驱动程序向IO子系统供应标准的访问接口。

文件系统:

文件系统紧张卖力对块设备进行统一管理,抽象出文件这个逻辑设备的观点,建立文件与块设备的每个块的映射关系等,文件系统也卖力根据文件名定位到设备驱动程序和详细的某个设备,这个往后单独写文章阐述。

IO调度

操作系统为每个设备掩护一个IO要求行列步队,当进程进行IO要求时,会将这些IO要求加入到这个行列步队中,如果按照前辈先出的办法顺序访问设备,从系统总体来讲,并不一定是高效的,常日须要得当的IO调度算法来高效和充分地利用设备。

其余不同的IO要求有不同的优先级,有些IO要求优先级天生比较高,它可以得到优先实行的权利,例如一个缺页IO要求就比其它的普通运用程序的要求更加紧急,也会有更高的优先级。

缓冲

采取缓冲有以下几个情由:

一:设备掌握器常日有单独的数据缓冲,运用程序也须要有自己的缓冲,运用程序写数据时,常日写入到自己的缓冲,而不是直接写到设备掌握器的缓冲,这是由于IO设备处理数据较慢,设备掌握器的缓冲,很随意马虎就满了,因此运用程序设置自己的缓冲,这样纵然设备掌握器缓冲满了,运用程序还是可以写数据,不至于壅塞,其余运用程序设置自己的缓冲,可以灵巧增加缓冲的容量,也可以设置多个缓冲,例如双缓冲,循环缓冲等。

二.常日运用程序自己的缓冲在用户空间,操作系统可以将用户缓冲中的数据发送到设备掌握器上的数据缓冲,设备掌握器再发送数据缓冲的数据到设备,这样有两个问题,一个是:用户空间的缓冲常日是在用户空间的某些页上,一旦这些页被换出了,操作系统读取这些页的数据时创造页不在就会进行缺页处理,这个很影响效率,其余一个是:操作系统发送数据时,用户空间的缓冲被修正了,此时就造成了数据的毁坏,因此常日操作系统会在内核开辟一块空间叫做内核缓冲,运用程序写入数据时,先将用户缓冲复制到内核缓冲,内核缓冲再写入到设备掌握器的数据缓冲,此后内核就可以放心地发送数据了,不用担心页被换出或者数据被修正了,这样的复制非常影响效率,因此有些操作系统会采取虚拟内存映射和写时复制的办法将用户缓冲和内核缓冲指向内核的一块共享缓冲,如果用户修正了共享缓冲,会通过写时复制的办法,拷贝修正的部分到用户空间,不影响原来的共享缓冲。

整体来说缓冲不只是写出的缓冲,读入的缓冲也是同样的道理,这里不再阐述。

高速缓存:

操作系统可以开辟一块内存,用于存储热点的设备数据,采取一定的缓存失落效算法,剔除失落效的缓存,这样可以每次进行IO读取操作时,则可以直接从高速缓存中获取,不在进行任何IO操作。

有时候高速缓存和缓冲可以合二为一,例如一个写缓冲存储了要写出到设备的数据,此时如果再读取这些数据时,就可以把写缓冲当做高速缓冲,直接从写缓冲读取。

设备保护:

IO设备保护有以下几种办法:

1.IO特权指令,IO指令常日都是特权指令,这些指令只有操作系统才可实行,这样就杜绝了运用程序实行IO指令,运用程序可以通过系统调用进行IO操作。

2.通过内存映射IO办法访问设备掌握器数据缓冲或者设备寄存器时,地址总线上一部分地址用于映射到设备掌握器数据缓冲或者设备寄存器,这部分地址由操作系统的内存保护模块进行掌握,禁止用户空间访问这些地址。

3.IO子系统中文件系统中所有的文件都有访问的权限,限定文件的访问就间接地对文件对应的IO设备进行了保护。

缺点处理:

IO设备产生的缺点每每比较多而且杂,当缺点发生时,IO子系统会尽最大努力对这些缺点进行处理,许多IO缺点与特定的设备有关,这类的缺点只能交由设备驱动程序去处理,但IO子系统有个缺点处理的流程,按照这个流程进行处理是通用的和设备无关的,以下为缺点处理框架中的几个关键环节的处理过程。

一:一些IO类的缺点是编程导致的,比如运用程序对键盘,扫描仪,鼠标进行写入操作,这些设备是不支持写入的,还有便是运用程序供应了一个无效的缓冲区或者参数,这些编程导致的缺点,IO子系统直接返回相应的缺点码给运用程序。

二:其余一种IO类的缺点便是设备确实有问题了,例如运用程序试图写入一个破坏的磁盘块,这类缺点交由设备驱动程序办理,如果设备驱动程序实在不知道怎么办理,则再返回IO子系统,由IO子系统返回给运用程序。

三:还有一些IO类缺点可以交由用户去决定怎么去办理,例如一个读磁盘发生缺点,可以由IO子系统奉告用户,例如弹出一个对话框,让用户去选择重试次数,忽略缺点,或者干脆停掉进程。

操作系统访问IO设备的流程举例

假设运用程序进行一个别系调用read读取磁盘数据,这个read是壅塞的,设备驱动程序与设备掌握器交互办法采取DMA,下面来阐述下全体流程如下图所示:

1.IO子系统根据文件名可以定位到设备驱动程序,设备寄存器端口,磁盘物理地址,每个操作系统有各自的实现办法,常日这一部分常日由文件系统来实现。

2.IO子系统根据磁盘物理地址去高速缓冲中查找,如果高速缓冲命中,则将高速缓冲中的数据拷贝到用户空间缓冲,调用返回。

5.IO子系统将运用程序A从CPU的运行行列步队移除,加入到设备的等待行列步队,这个时候运用程序壅塞了。

6~8.IO子系统根据设备寄存器端口和磁盘物理地址封装IO要求,将IO要求加入到设备IO要求行列步队中,IO子系统根据IO要求调度算法,开始调用IO要求,终极将运用进程A的IO要求发送给设备驱动程序。

9~11.设备驱动程序在内核空间开辟一块内存空间,作为内核缓冲,这块内核缓冲用来吸收来自磁盘的数据,然后设备驱动程序掌握DMA,发送掌握要求给DMA,然后设备驱动程序壅塞了,壅塞的方法有很多中,比如wait。

12.DMA掌握磁盘掌握器,完成读取数据后,发送中断旗子暗记给CPU。

13.CPU接管到中断旗子暗记后,开始实行中断处理程序,程序会检讨IO要求是否已经完成,要求的完成状态等,然后封装IO要求结果,发送给IO子系统。

14. IO子系统收到要求结果后,会唤醒设备驱动程序,唤醒的办法比如singal,同时IO子系统会拷贝内核缓冲的数据到用户缓冲,同时将返回结果设置到运用程序A的用户空间。

15.IO子系统将运用程序A从设备行列步队中移除,加入到CPU就绪行列步队中。

16.CPU调度运行运用进程A,运用进程A将返回结果返回。

相关文章