一个系统要能正确工作,必须要有数据通道(data paths)的机制,软件和硬件系统都概莫能外。对于计算机系统而言,必须要有data paths的机制来确保CPU, RAM和I/O设备之间的信息数据能正确的流动。这些data paths,通常被称为总线(BUS),是计算机内部主要的通信通道。
为什么英文总线叫bus呢?我们知道:公共汽车BUS会在每个站台上停靠并让乘客搭乘。总线也有类似的功能,它会在每个挂接在它身上的设备停靠或收集(pick up)设备的信息。因为这种功能的类似 性,所以总线英文为bus.
计算机内部一般有系统总线来连接内部所有的硬件设备。一个典型的系统总线是PCI((Peripheral Component Interconnect)总线。其他类型的用得较多的总线还有ISA,EISA, MCA, SCSI, 和USB。一个计算机有多个不同类型的总线,这些总线由桥(bridge)链接起来。有以下两种高速总线处理到达或出自内存芯片的数据传输:
(1)前端总线FSB:连接CPU和RAM控制器;
(2)后端总线:连接CPU和外部硬件设备CACHE.
主机桥(HostBridge,俗称北桥)连接系统总线和前端总线。
连接I/O设备和CPU的数据通道可统称为I/O总线。外设是为了用来适配一个外设总线而存在的, 并且大部分流行的 I/O 总线成型在个人计算机上。可见,总线的类型影响到I/O设备的内部设计同时影响到Linux内核对它的处理方式。
PC的通用I/O架构如下所示:
接下来,我将按照从上而下的顺序(即I/O controller--> I/O Interface--->I/O Port)对该图进行点评。
设备控制器( I/O Controller)的作用有以下两个:
(1)解析从I/O Interface接收到的高层次命令,并通过发送时序正确的电信号给I/O设备,I/O设备则根据这些信号去执行相应的动作。
(2)正确的解析和翻译来自I/O设备的电信号并通过I/O Interface修改相应的I/O 状态寄存器值。(I/O状态寄存器是I/O PORT的一种。)
I/O Interface是一种硬件电路,插入在I/O Port和相应的设备控制器之间。它充当一个解释器的功能,把I/O Port里的值解析为对应设备的命令或数据。相应的,它也会读取设备的状态值,并更新I/O port里的值。
有两种类型的interface:
(1)定制化接口。常用的有键盘接口,图形接口,磁盘接口,总线鼠标接口,网络接口等。
(2)通用接口。常见的有串口,并口,PCMCIA(如硬盘、网卡等)接口,SCSI接口,USB接口等。
为了统一起见,设备的I/O Port也被结构化为一系列专用寄存器:
(1)控制寄存器;
(2)状态寄存器;
(3)输入寄存器;
(4)输出寄存器。
示意图如下:
对于CPU而言,如果它要发数据到某个设备,其实是发到对应的接口(I/O Interface),接口电路里有多个寄存器(也称为端口,即“I/O PORT”),访问设备实际上是读写这些寄存器,所有的信息会由接口转给它的设备。一般来说,CPU会根据需要向设备控制寄存器写入需要执行的命令,并会从设备状态寄存器读取设备的内部状态。CPU也会从输入寄存器获取(Featch or pull)字节数据,或向输出寄存器以推送的方式写入(Push)字节数据。
一个外部设备要想接入系统,就用自己的接口和总线上的某个匹配接口对接。通常会有多个外设,每个外设的接口电路中,又会有多个端口,每个端口都需要一个地址,为他们标识一个具体的地址值,是系统必须解决的事,与此同时,你还有个内存条,可能是512M或1G或更大的金士顿、现代DDR2之类,他们的每一个地址也都需要分配一个标识值,另外,很多外设有自己的内存、缓冲区,就像你的内存条一样,你同样需要为它们分配内存……你的CPU可能需要和它们的每一个字节都打交道,所以:别指望偷懒,它们的每一寸土地都要规划好!
为了规划好I/O端口,有两种编址方式:独立编址和统一编址。
(1)统一编址:
外设接口中的IO寄存器(即IO端口)与主存单元一样看待,每个端口占用一个存储单元的地址,将主存的一部分划出来用作IO地址空间,如,在 PDP-11中,把最高的4K主存作为IO设备寄存器地址。端口占用了存储器的地址空间,使存储量容量减小。统一编址也称为“I/O内存”方式,外设寄存器位于“内存空间”(很多外设有自己的内存、缓冲区,外设的寄存器和内存统称“I/O空间”)。
(2)独立编址(单独编址):
IO地址与存储地址分开独立编址,I/0端口地址不占用存储空间的地址范围,这样,在系统中就存在了另一种与存储地址无关的IO地址,CPU也必须具有专用与输入输出操作的IO指令(IN、OUT等)和控制逻辑。独立编址下,地址总线上过来一个地址,设备不知道是给IO端口的、还是给存储器的,于是处理器通过MEMR/MEMW和IOR/IOW两组控制信号来实现对I/O端口和存储器的不同寻址。如,intel 80x86就采用单独编址,CPU内存和I/O是一起编址的,就是说内存一部分的地址和I/O地址是重叠的。独立编址也称为“I/O端口”方式,外设寄存器位于“I/O(地址)空间”。