IBM PC/AT 80X86 兼容微机使用两片级联的 8259A 可编程中断控制芯片组成一个中断控制器,用于实现 I/O 设备的中断控制数据存取方式,并且能为 15 个设备提供独立的中断控制功能,如下图所示。
在计算机刚开机初始化期间,ROM BIOS 会分别对两片 8259A 芯片进行初始化,并分别把 15 级中断优先级分配给时钟定时器、键盘、串行口、打印机、软盘控制、协处理器和硬盘等设备或控制器使用。同时在内存开始处 0x000 — 0xFFF 区域内建立一个中断向量表。但是由于这些设置违背了 Intel 公司的要求,因此 Linux 操作系统在内核初始化期间又重新对 8259A 进行了设置。有关中断控制器的工作原理和编程方法的详细说明参见后续章节。
当一台 PC 计算机刚上电开机时,上图中的硬件中断请求号会被 ROM BIOS 设置成下表列出的对应中断向量号。Linux 操作系统并不直接使用这些 PC 机默认设置好的中断向量好,当 Linux 系统执行初始化操作时,他会重新设置中断请求号与中断向量号的对应关系。
中断请求号BIOS设置的中断号用途IRQ00x08(8)8253 发出的 100HZ 时钟中断IRQ10x09(8)键盘中断IRQ20x0A(10)接连从芯片IRQ30x0B(11)串行口 2IRQ40x0C(12)串行口 1IRQ50x0D(13)并行口 2IRQ60x0E(14)软盘驱动器IRQ70x0F(15)并行口 1IRQ80x70(112)实时钟中断IRQ90x71(113)改向至 INT 0x0AIRQ100x72(114)保留IRQ110x73(115)保留(网络接口)IRQ120x74(116)PS/2 鼠标口中断IRQ130x75(117)数学协处理器中断IRQ140x76(118)硬盘中断IRQ150x77(119)保留 在 PC/AT 机中,使用了两片 8237 芯片,因此 DMA 控制器有 8 个独立的通道可使用。其中后 4 个是 16 位通道。软盘控制器被专门指定使用 DMA 通道 2。在使用一个通道之前必须首先对其设置。这牵扯到对三个端口的操作,分别是页面寄存器端口、(偏移)地址寄存器端口和数据计数寄存器端口。由于 DMA 寄存器是 8 位的,而地址和计数值是 16 位值,因此各自需要发送两次。
Intel 8253/8254 是一个可编程定时/计数器(PIT - Progrmmable Interval Timer)芯片,用于处理计算机中的精准时间延迟。该芯片提供了 3 个独立的 16 位计数器通道。每个通道可工作在不同的工作方式下,并且这些工作方式均可以使用软件来设置。在软件中进行延时的一种方法是执行循环操作语句,但这样很耗 CPU 时间。若机器中采用了 8253/8253 芯片,那么程序员就可以设置 8253 以满足自己的要求并且使用其中一个计数器通道达到所期望的延时。在延时到后,8253/8254 会向 CPU 发送一个中断信号。
对于 PC/AT 及其兼容 微机系统采用的是 8254 芯片。3 个定时/计数器通道被分别用于日期时钟计时中断信号、动态内存 DRAM 刷新定时电路和主机扬声器音调合成。Linux 0.11 操作系统只对通道 0 进行了重新设置,使得该计数器工作在方式 3 下,并且每间隔 10 毫秒发出一个信号以产生中断请求信号(IRQ0)。这个间隔定时产生的中断请求就是 Linux 0.11 内核工作的脉搏,它用于定时切换当前执行的任务和统计灭个任务使用的系统资源量(时间)。
我们现在使用的键盘是 IBM 公司于 1984 年 PC/AT 微机的兼容键盘,通常称为 AT-PS/2 兼容键盘并具有 101 到 104 个按键,键盘上有一个称为键盘编码器的处理器(Intel 8048 或兼容芯片)专门用来扫描收集所有按键按下和松开的状态信息(即扫描码),并发送到主机主板上键盘控制器中。当一个键被按下时,键盘发送的扫描码称为接通扫描码(Make code),或简称为接通码;当一个被按下的键放开时发送的扫描码被称为断开扫描码(Break code),或称为断开码。
主机键盘控制器专门用来对接收到的键盘扫描码进行解码,并把解码后的数据发送到操作系统的键盘数据队列中。因为每个按钮的接通和断开码都是不同的,所以键盘控制器根据扫描码就可以确定用户在操作哪个键。整个键盘上所有按键的接通和断开码就形成了键盘的一个扫描码集(Scan Code Set)。根据计算机的发展,目前已有三套扫描码集可供使用。
第一套扫描码集 —— 原始 XT 键盘扫描码集。目前的键盘已经很少发送这类扫描码 第二套扫描码集 —— 现代键盘默认使用的扫描码集,通常称为 AT 键盘扫描码集 第三套扫描码集 —— PS/2 键盘扫描码集。原 IBM 推出 PS/2 微机时使用的扫描码集,已很少使用 AT 键盘默认发送的是第二套扫描码集。虽然如此,主机键盘控制器为了与 PC/XT 机的软件兼容起见,仍然会把所有接收到的第二套扫描码转换成第一套扫描码。如下图所示。因此,我们在为键盘控制器进行编程时通常只需要了解第一套扫描码集挤了。
键盘控制器通常采用 Intel 8042 单片微处理器芯片或其兼容电路。现在的 PC 机都已经将键盘控制器集成在主板芯片组中了,但是功能仍然与使用 8042 芯片的控制器相兼容。键盘控制器接收键盘发送来的 11 位串行格式数据。
第1位 起始位 第2-9位 键盘扫描码 第10位 奇校验校验位 第11位 停止位 键盘控制器在收到 11 位的串行数据后就将键盘扫描码转换成 PC/XT 标准键盘兼容的系统扫描码,然后通过中断控制器 IRQ1 引脚向 CPU 发送中断请求。当 CPU 响应该中断请求后,就会调用键盘中断处理程序来读取控制器中国的 XT 键盘扫描码。
当一个键被按下时,我们可以从键盘控制器端口收到一个 XT 键盘接通码,这个扫描码仅表示键盘上某个位置处的键被按下,但还没有对应到某个字符代码上。接通码通常是一个字节宽度。例如,按下键 ”A“ 的接通码是 30(0x1E)。当一个按下的键被松开时,从键盘控制器端口收到的就是一个断开码。对于 XT 键盘,断开码是其接通码加上 0x80,即最高有效位(位7)置位时的接通码。例如,上述“A”键断开码就是 0x80 + 0x1E = 0x9E。
但是对于那些 PC/XT 标准 83 键键盘以后新添加的(“扩展的”)AT 键盘上的按键 (例如右边的 Ctrl 键和右边的 Alt 键等),则其接通和断开扫描码通常由 2 到 4 个字节,并且第 1 个字节一定是 0xE0。例如,按下左边的非扩展 Ctrl 键时会产生 1 字节接通码 0x1D,而按下右边的 Ctrl 键时就会产生扩展的 2 字节接通码 0xE0、0x1D。对应的断开码是 0xE0、0x9D。下表是几个接通和断开扫描码的例子。
按键接通扫描码断开扫描码说明A0x1E0x9E非扩展的普通键90x0A0x8A非扩展的普通键功能键 F90x430xC3非扩展的普通键方向键向右键0xe0, 0x4D0xe0, 0xCD扩展键右边 Ctrl 键0xe0, 0x1D0xe0, 0x9D扩展键左shift 键 + G 键0x2A, 0x220xAA, 0xA2先按并且后释放 shift 键 另外,键盘控制器 8042 的输出端口 P2 用于其他目的。其 P20 引脚用于实现 CPU 的复位操作, P21 引脚用于控制 A20 信号线的开启与否。当该输出端口位 1 (P21)为 1 时就开启(选通)了 A20 信号线,为 0 则禁止 A20 信号线。现今的主板上已经不再包含独立的 8024 芯片了,但是主板上其他集成电路会为兼容目的而模拟 8042 芯片的功能。因此现在键盘的编码程序仍然采用 8042 的编程方法。
转载于:https://www.cnblogs.com/rock-cc/p/9263642.html
