接上文:系统启动篇(三)[上]
在计算机中,用于数据传输的方式总共分为两种:①串行通信(Serial Communication),传输数据时只用一根线——按位发送和接受字节,速度慢但能够实现远距离通信,使用串行端口的设备有鼠标和USB等。②并行通信(Parallel Communication),使用多条线将每个数据的二进制位同时进行传输,传输速度较快但因为存在干扰而不能实现远距离通信,一般用来连接打印机和扫描仪等,在计算机内部也采用这种方式传输数据。这里我们主要将注意力集中在串行通信上,在这种通信方式中使用的最主要的参数分别为波特率、数据位、停止以及奇偶校验位,这些位的概要解释如下:
- 波特率:表示每秒传送的位的个数,主要用来衡量通信速度。假设波特率被设置为3600,那么对应的时钟周期则为3600Hz,即在数据线上的采样率为3600Hz。波特率通常和距离成反比。
- 数据位:当计算机发送一个信息帧时,实际传输的数据所采用的标准值是5、6、7或8位——这取决于数据位的设置方式。一个信息帧中通常涵盖开始/停止位,数据位和奇偶校验位。
- 停止位:表示一个信息单元的最后一位,可以是1,1.5和2位。停止位的位数越多,数据传输率越慢。
- 奇偶校验位:在通信过程中用于对数据进行检错。
串行端口通信相关设施
在计算机内部实际上存在三块芯片,它们分别是:
- 8250 UART(Universal Asynchronous Receiver/Transmitter) [通用异步发送/接收装置]
- 8259 PIC(Programmable Interrupt Controller) [可编程中断控制器]
- 8086 CPU(Central Processing Unit) [中央处理单元]
以上列出的三者并非指单一型号的芯片,而是涵盖了一类芯片家族,比如8086 CPU实际指的是x86/pentium/core系列等兼容芯片。出于降低设备成本的考虑,它们通常被放置在同一块硅片上。在许多情形下,为早期IBM PC兼容机所写的用于执行串行通信的软件,同样能在安装了最新版本的Windows/Linux系统的现代机器上运行。在这三者中,我们主要关注8250 UART。同8086家族一样,8250 UART也经历了快速的发展,例如至今已发展成为16550 UART系列。使得UART芯片家族快速演化的源动力主要来自于能够跟上CPU越来越快的执行速度的要求。
如前所述,在计算机内部采用并行通信方式,因此在将数据传输至串行外设之前首先需要将其转换为串行数据流,接收数据时也需要做相应的转换,而这项工作正是由UART来完成的。具体的执行方式为:UART将CPU将所要输出的数据封装为一个消息帧,该帧的格式是以一个低位起始位作为开始,后跟5、6、7或8个数据位,一个可用的奇偶位以及一个或多个高位停止位。当消息帧到达目的地后,接收器随即检测起始位,开始接收有效载荷(payload),并尝试与发送装置同步时钟频率,而其后的奇偶位则帮助错误校验。在接收串行外设的输入时,UART除了去掉消息帧中的起始位、停止位并进行相应的校验工作之外,也需要将串行数据流转换为并行数据。控制台的初始化正是根据内核命令行中的选项对数据的传输以及转换进行相应的设置。
即便从理论上来讲可以通过增加串行端口的方式连接更多的外设,但在大多数PC机上仅有两个串行端口——COM1及COM2。其中COM1的物理地址为0x3f8,COM2的物理地址为0x2f8,以这两个I/O端口地址之一起始的连续8个字节的物理内存被映射为UART芯片上12个不同的寄存器,这意味着多个不同的寄存器将共用同一个I/O端口地址,并且当前的I/O端口地址被映射为哪一个寄存器具体取决于当前的上下文环境及UART的配置方式。虽然BIOS为串行通信提供了一些中断例程,但通常都是通过访问寄存器中的位来实施对UART的控制。下表列出了UART中存在的寄存器:
偏移量 | 访问控制 | 概要描述 |
+0 | 只写 | 用于将数据输出外设(Transmitter Data Register) [TXR] |
+0 | 只读 | 从外设接收数据(Receive Data Register) [RXR] |
+0 | 可读/可写 | 波特率除数低位字节(Baud Rate Divisor Latch Low Byte) [DLL] |
+1 | 可读/可写 | 中断允许寄存器(Interrupt Enable Register) [IER) |
+1 | 可读/可写 | 波特率除数高位字节(Baud Rate Divisor Latch High Byte) [DLH) |
+2 | 只读 | 中断识别寄存器(Interrupt Identification Register) [IIR] |
+2 | 只写 | 先进先出控制寄存器(FIFO Control Register) [FCR] |
+3 | 可读/可写 | 行控制寄存器(Line Control Register) [LCR] |
+4 | 可读/可写 | 调制解调控制寄存器(Modem Control Register) [MCR] |
+5 | 只读 | 行状态寄存器(Line Status Register) [LSR] |
+6 | 只读 | 调制解调状态寄存器(Modem Status Register) [MSR] |
+7 | 可读/可写 | 额外备用寄存器(Scratch Register) [SR] |
以下是对各个寄存器的详细描述(除额外备用寄存器Scratch Register之外):
1、传输/接收数据寄存器(Transmitter/Receive Data Register,TXR/RXR)
这两个寄存器就是串行数据通信的“心脏”,数据通过这两个寄存器被传输至串行外设或从外设接收数据,由于其他的计算机对于本机来讲也可看成是一类外设,所以计算机之间的数据传输也是通过这两个寄存器完成的。现在的一类芯片比如16650一次可以发送或接受16个字节的数据,相比早期一次只能处理1个字节的数据,这在多任务处理环境中显得非常有用。这两者共用同一个I/O端口地址——通过写I/O地址0x3f8或0x2f8则自动切换至传输寄存器,读相应的I/O地址切换至数据接收寄存器。为了确定是否可以输出或接收数据,即对应的传输寄存器是否为空或接收寄存器是否已满,可以通过行状态寄存器(Line Status Register,LSR)中的相应位查看。
2、波特率除数占用字(Baud Rate D