外围设备
和处理器进行交互的硬件有很多,比如:硬盘,显示器、网络设备、扬声器和麦克风、键盘、鼠标等。
根据应用的场合,还会对接一些没见过的设备。
所有连接的硬件设备,都在计算机主机附近,争着跟计算机交互,这样的硬件设备叫做外围设备(Peripheral Equipment)。
一般把这些外围设备分成两种,一种是输入设备,比如键盘、鼠标、麦克风、摄像头等;另一种是输出设备,比如显示器、打印机、扬声器等。
输入设备和输出设备统称为输入输出(Input/Output,I/O)设备。
每种设备的工作方式都不一样。不同的设备,有不同的连线数量,线里面传送的信号也不 一样,而且各自的插头和插孔也千差万别。难么这些设备如何与CPU进行交互呢?
外围设备如何与CPU进行交互:
外围设备和CPU通过一个I/O 接口媒介来进行交互。
I/O 接口:
这个I/O 接口可能是一个电路板,也可能是一块小芯片,这取决于它有多复杂。无论如何,它是一个典型的变换器,或者说是一个翻译器,在一 边,它按处理器的信号规程工作,负责把处理器的信号转换成外围设备能接受的另一种信号;在另一边,它也做同样的工作,把外围设备的信 号变换成处理器可以接受的形式。 例如:显卡接受CPU的信息然后转化成显示器可以接受的来处理。
CPU如何选择I/O接口:
外围设备非常多,所以也就有很多的I/O接口,CPU需要选择I/O接口进行交互。
不可能将所有的I/O 接口直接和处理器相连,设备那么多,而且还有设备现在没有发明出来,将来可能有。所以为了可拓展性,CPU采用总线技术来将所有外部设备捆绑在一起。再有新的设备就直接添加到总线上就行了。
(总线可以认为是一排电线,包含所有的外围设备,包括处理器,都连接到这排电线上。每个连接到这排电线上的器件都必须有开关,以使它们随时进行连接或断开。这就好比是公共车道,当路面上有车时,你就必须退避一下,不能硬冲上去得等别人走完了你才可以,也就是说一个外围设备在进行交互时另外的外围设备不可以进行交互。因此,这排公共电线 就称为总线(Bus))。
比如:
每个设备的I/O 接口都抢着和处理器交互这肯定会导致冲突,于是又引入了输入输出控制设备集中器(I/O Controller Hub,ICH)芯片,该芯片的作用是连接不同的总线,并协调各个I/O 接 口对处理器的访问。
一个外部设备需要将I/O接口插到ICH的总线上,然后ICU通过ICH中提供和外部设备进行对接的的总线进行抉择然后将抉择后的I/O接口和CPU的总线进行对接。这样一来,1是解决了添加设备的问题,2是解决了如何抉择I/O接口的问题。
当处理器想同某个设备交互时时,ICH 会接到通知。然后,提供相应的传输通道和其他辅助支持,并命令所有其他无关设备禁止交互。同样,当某个设备要跟处理器说话,情况也是一样。
I/O 端口
虽然外围设备和处理器之间的交互是通过相应的I/O 接口进行的。但是具体的来说:处理器其实是通过端口(Port)来和外围设备进行交互的。本质上,端口就是一些寄存器,类似于处理器内部的寄存器,类似于缓存。不同之处在于,这些叫做端口的寄存器位于I/O 接口电路中。
端口是处理器和外围设备实际交流的窗口,每一个I/O 接口都可能拥有好几个端口,分别用于不同的目的。
比如,连接硬盘的 PATA/SATA 接口就有几个端口,分别是命令端口(当向该端口写入0x20 时,表明是从硬盘读数据;写入0x30 时,表明是向硬盘写数据)、状态端口(处理器根据这个端口的数据来判断硬盘工作是否正常,操作是否成功,发生了哪种错误)、参数端口(处理器通过这些端口告诉硬盘读写的扇区数量,以及起始的逻辑扇区号)和数据端口(通过这个端口连 续地取得要读出的数据,或者通过这个端口连续地发送要写入硬盘的数 据)。
端口的实现方式:
端口是位于I/O 接口上的寄存器,所以,每个端口有自己的数据宽度。在早期的系统中,端口可以是8 位的,也可以是16 位的,现在有些端口会是32 位的。到底是8 位还是16 位,这是设备和I/O 接口制造者的自由。
端口在不同的计算机系统中有着不同的实现方式。一般分为两种,映射到内存地址空间和独立编址。
映射到内存空间:
计算机将端口号映射到内存地址空间。比如,0xE0001~0xFFFFF 是从很多I/O 接口那里映射过来的,当访问这部分地址时,实际上是在访问I/O 接口。
独立编址:
端口独立编址不和内存发生关系。在这种计算机中,处理器的地址线既连接内存,也连接每一个I/O 接口。但是,处理器还有一个特殊的引脚M/IO#,在这里,“#”表示低电平有效。也就是说,当处理器访问内存时,它会让 M/IO#引脚呈高电平,这里,和内存相关的电路就会打开;相反,如果处 理器访问I/O 端口,那么M/IO#引脚呈低平,内存电路被禁止。与此同时,处理器发出的地址和M/IO#信号一起用于打个某个I/O 接口,如果该 I/O 接口分配的端口号与处理器地址相吻合的话。
如何使用Intel 8086的端口:
Intel 处理器,早期是独立编址的,现在既有内存映射的,也有独立 编址的。在8086中为独立编址的端口。
所有端口都是统一编号的,比如0x0001、0x0002、0x0003、…。每 个I/O 接口电路都分配了若干个端口,比如,I/O 接口A 有3 个端口,端口号分别是0x0021~0x0023。
在Intel 的系统中,只允许65536(十进制数)个端口存在,端口号 从0 到65535(0x0000~0xffff)。因为是独立编址,所以,端口的访问 不能使用类似于mov 这样的指令,取而代之的是in 和out 指令。
所以我们直接采用In/Out指令就可以在8086CPU的世界中操控CPU和外部设备进行读写了。
小结:
CPU如何于外部设备进行交互是一个看试很繁琐的事情,但是如果我们将其一步步细分就不是很麻烦了。
首先CPU通过接口和外部设备进行交互,然后由于外部设备可能很多而且每个都想交互所以需要选择就引入了ICH,然后CPU就通过ICH来和外部设备接口进行交互。
然后接口是一个大的东西,内部还可以细分为端口,端口包含在接口里,就好比Byte 内部包含了8个bit这种关系,所以最终是通过端口来读写。