Chapter 1
Linux Kernel 概述
Linux kernel 各版本源代码行数
POSIX (Portable Operating System Interface for Computing System) 是由IEEE和ISO / IEC 开发的一簇标准。该标准是基于现有的UNIX实践和经验,描述了操作系统的调用服务接口。用于保证编制的应用程序可以在源代码一级上在多种操作系统上移植和运行。它是在1980年早期一个UNIX用户组(usr/group)的早期工作基础上取得的。该UNIX用户组原来试图将AT&T的Systcm V操作系统和BerkeleyCSRG的BSD操作系统的调用接口之间的区别重新调和集成.并于1984年定制出了/usr/group标准.
bootimagc.Z和rootimagcZ是压缩的软盘映像(Image)文件。bootimagc是引导启动Image文件.其中主要包括磁盘引导扇区代码、操作系统加载程序和内核执行代码。PC机启动时ROM BIOS中的程序会把默认启动驱动器上的引导扇区代码和数据读入内存,而引导扇区代码则负责把操作系统加载程序和内核执行代码读入内存中,然后把控制权交给操作系统加载程序去进一步准备内核的初始化操作.最终加载程序会把控制权交给内核代码。内核代码若要正常运行就需要文件系统的支持。rootimagc就是用于向内核提供最基本支持的根文件系统,其中包括操作系统最起码的一些配置文件和命令执行程序。对于Linux系统中使用的UNIX类文件系统。其中主要包括一些规定的目录、配置文件、设备驱动程序、开发程序以及所有其他用户数据或文本文件等。这两个盘合起来就相当于一张可启动的〔IOS操作系统盘。
as86.tarz是16位汇编器链接程序软件包。Linux-0.I I.tar.Z是压缩的Linux 0.11内核源代码。INSTALL-0.11是Linux 0.11系统的简单安装说明文档。
目前除了原来的rootimagc.Z文件.其他四个文件均能找到。不过作者已经利用Internet上的资源为Linux 0.11重新制作出了一个完全可以使用的rootimagc-0.II根文件系统。并重新为其编译出能在0.11环境下使用的gcc 1.40编译器,配置出可用的实验开发环境.目前.这些文件均可以从oldlinux.otg网站上下载。具体下载目录位置是:
http://oldlinux.org/Linux.old/images/该目录中含有己经制作好的内核映像文件bootimage和根文件系统映像文件rootimage.
http://oldlinux.org/Linux.old/kcrncls/该目录中含有内核源代码程序,包括本书所描述的Linux0.11内核源代码程序。
http://oldlinux.org/Linux.old/bochs/该目录中含有已经设置好的运行在计算机仿真系统bochs下的Linux系统。
http://oldlinux.org/Linux.old/Linux-0.I1/该目录中含有可以在Linux 0.11系统中使用的其他一些工具程序和原来发布的一些安装说明说明文档。
Linux 内核目录
所有目录结构均是以linux为当前目录。
微型计算机组成结构
对于使用80386 CPU的PC机,其内部地址线和数据线都分别有32根,即都是32位的。因此地址寻址空间范围有2的32 次方字节,从0到4GB.
总线接口标准:
工业标准结构 ISA (Industry Standard Architecture)总线
扩展工业标准结构总线EISA (Extented ISA )
外围组件互连PCI(Peripheral Component Interconnect)总线
加速图形端口AGP(Accelerated Graphics Port)视频总线
除了CPU以外。现代PC机主板主要使用2个超大规模芯片构成的芯片组或芯片集(Chipscts)组成:北桥(Northbridge )芯片和南桥(Southbridge)芯片。北桥芯片用于与CPU、内存和AGP视频接口,这些接口具有很高的传输速率。北桥芯片还起着存储器控制作用.因此
Intel把该芯片标号为MCH (Memory Controller Hub)芯片。南桥芯片用来管理低、中速的组件,例如,PCI总线、IDE硬盘接口、USB端口等,因此南桥芯片的名称为ICH (1/0 Controller Hub)。之所以用“南、北,桥来分别统称这两个芯片.是由于在Intel公司公布的典型PC机主板上.它们分别位于主版的下端和上端(即地图上的南部和北部)位置.并起着与CPU进行通道桥接的作用。
CPU为了访问I/O接口控制器或控制卡上的数据和状态信息.需要首先指定它们的地址。这种地址就称为I/O端口地址或者简称端口。通常一个I/O控制器包含访问数据的数据端口、输出命令的命令端口和访问控制器执行状态的状态端口。端口地址的设置方法一般有两种:统一编址和独立编址。
端口统一编址的原理是把1/O控制器中的端口地址归入存储器寻址地址空间范围内。因此这种编址方式也成为存储器映像编址。CPU访问一个端口的操作与访问内存的操作一样,也使用访问内存的指令。端口独立编址的方法是把I/O控制器和控制卡的寻址空间单独作为一个独立的地址空间对待.称为I/O地址空间。每个端口有一个I/O地址与之对应,并且使用专门的I/O指令来访问端口。
IBM PC及其兼容微机主要使用独立编址方式。采用了一个独立的I/O地址空间对控制设备中的寄存器进行寻址和访问。使用ISA总线结构的传统PC机其I/O地址空间范围是Ox000一Ox3FF,有1024个I/O端口地址可供使用。各个控制器和控制卡所默认分配使用的端口地址范围见表2一所示。关于这些端口的使用和编程方法将在后面具体涉及相关硬件时再详细进行说明。
另外,IBM PC机也部分地使用了统一编址方式。例如,CGA显示卡上显示内存的地址就直接占用了存储器地址空间OxB800 - OxBCOO范围。因此若要让一个字符显示在屏幕上,可以直接使用内存操作指令往这个内存区域执行写操作。
对于使用EISA 或者PCI等总线结构的现代PC机, 有64kB的I/O地址空间可供使用。在普通Linux 系统下通过查看/pro/ioports文件可以得到相关控制器或设置使用的I/O地址范围,见如下图(Ubuntu 12.10 64 bit)
macos@MacOs:~$ cat /proc/ioports
0000-0cf7 : PCI Bus 0000:00
0000-001f : dma1
0020-0021 : pic1
0040-0043 : timer0
0050-0053 : timer1
0060-0060 : keyboard
0062-0062 : EC data
0064-0064 : keyboard
0066-0066 : EC cmd
0070-0071 : rtc0
0080-008f : dma page reg
00a0-00a1 : pic2
00c0-00df : dma2
00f0-00ff : fpu
0220-022f : pnp 00:08
040b-040b : pnp 00:08
04d0-04d1 : pnp 00:08
04d6-04d6 : pnp 00:08
0530-0537 : pnp 00:08
087f-087f : pnp 00:08
0c00-0c01 : pnp 00:08
0c14-0c14 : pnp 00:08
0c50-0c52 : pnp 00:08
0c6c-0c6c : pnp 00:08
0c6f-0c6f : pnp 00:08
0cd0-0cd1 : pnp 00:08
0cd2-0cd3 : pnp 00:08
0cd4-0cd5 : pnp 00:08
0cd6-0cd7 : pnp 00:08
0cd8-0cdf : pnp 00:08
0cf8-0cff : PCI conf1
0d00-ffff : PCI Bus 0000:00
0f40-0f47 : pnp 00:08
8000-805f : pnp 00:08
8000-8003 : ACPI PM1a_EVT_BLK
8004-8005 : ACPI PM1a_CNT_BLK
8008-800b : ACPI PM_TMR
8010-8015 : ACPI CPU throttle
8020-8027 : ACPI GPE0_BLK
8040-8047 : piix4_smbus
8100-81ff : pnp 00:08
8200-82ff : pnp 00:08
8200-8200 : ACPI PM2_CNT_BLK
8400-840f : 0000:00:11.0
8400-840f : ahci
8410-8413 : 0000:00:11.0
8410-8413 : ahci
8414-8417 : 0000:00:11.0
8414-8417 : ahci
8418-841f : 0000:00:11.0
8418-841f : ahci
8420-8427 : 0000:00:11.0
8420-8427 : ahci
9000-9fff : PCI Bus 0000:01
9000-90ff : 0000:01:00.0
a000-bfff : PCI Bus 0000:03
c000-cfff : PCI Bus 0000:09
c000-c0ff : 0000:09:00.0
c000-c0ff : sky2
macos@MacOs:~$
PC机I/O接口数据传愉控制方式一般可采用程序循环查询方式、中断处理方式和DMA传输方式。顾名思义.循环查询方式是折CPU通过在程序中循环查询指定设备控制器中的状态来判断是否可以与设备进行数据交换。这种方式不需要过多硬件支持.使用和编程都比较简单.但是特别耗费CPU宝贵时间。
因此在多任务操作系统中除非等待时间极短或必须.否则就不应该使用这种方式。在Linux操作系统中,只有在设备或控制器能够立刻返回信息时才会在很少的几个地方采用这种方式。 中断处理控制方式需要有中断控制器的支持。在这种控制方式下,只有当I/O设备通过中断向CPU提出处理请求时.CPU才会暂时中断当前执行的程序转而去执行相应的I/O中断处理服务过程。当执行完该中断处理服务过程后.CPU又会继续执行刚才被中断的程序。在I/O控制器或设备发出中断请求时,CPU通过使用中断向量表(或巾断描述符表)来寻址相应的中断处理服务过程的入口地址。因此采用中断控制方式时需要首先设置好中断向量表,并编制好相应的中断处理服务过程。Linux操作系统中大多数设备I/O控制都采用中断处理方式。
直接存储器访问DMA (Ditcct Mcmory人curs)方式用于如设备与系统内存之间进行批量数据传送.整个操作过程需要使用专门的DMA控制器来进行而无需CPU插手。由于在传输过程中无须软件介入,因此操作效率很高。在Linux操作系统中,软盘驱动程序使用中断和DMA方式配合来实现数据的传愉工作。
1981年IBM PC机刚推出时系统只带有640KB的RAM主存储器(简称内存)。由于所采用的8088/8086CPU只有20根地址线.因此内存寻址范围最高为1024KB (I MB)。在当时.DOS操作系统流行年代.640K或IMB内存容量基本上能满足普通应用程序的运行。随着云十算机软件和硬件技术的高速发展,目前的计算机通常都配置有512MB或者更多的物理内存容量.并且都采用Intel 32位CPU.即都是PC/AT计算机。因此CPU的物理内存寻址范围已经高达4GB(通过采用CPU的新特性,系统甚至可以寻址64GB的物理
内存容量)。但是为了与原来的PC机在软件上兼容,系统IMB以下物理内存使用分配上仍然保持与原来的PC机基木一致,只是原来系统ROM中的基本输入输出程序BIOS一直处于CPU能寻址的内存最高端位置处,而BIOS原来所在的位置将在计算机开机初始化时被用作BIOS的影子(Shadow)区域,即BIOS代码仍然会彼复制到这个区域中。
见图2-4所示。
当计算机上电初始化时.物理内存被设置成从地址0开始的连续区域。除了地址从OxA0000到OxFFFFF(640K到IM共384K)和OxFFFE0000到OxFFFFFFFF (4G处的最后一64K)范围以外的所有内存都可用作系统内存。这两个特定范围被用于I/O设备和BIOS程序。假如我们的计算机中有16MB的物理内存.那么在Linux 0.1 x系统中,0-640K将被用作存放内核代码和数据。Linux内核不使用BIOS功能.也不使用BIOS设置的中断向量表。640K-1M之间的384K仍然保留用作图中指明的用途。其中地址OxA0000开始的128K用作显示内存缓冲区,随后部分用于其他控制卡的ROM BIOS或其映射区域,而OxF0000到IM范围用于高端系统ROM BIOS的映射区。
IM-16M将彼内核用于作为可分配的主内存区。
另外高速缓冲区和内存虚拟盘也会占用内核代码和数据后面的一部分内存区域,该区域通常会跨越640K-1M的区域。
存放在ROM中的系统BIOS程序主要用于计算机开机时执行系统各部分的自检,建立起操作系统需要使用的各种配置表,例如中断向量表、硬盘参数表.并且把处理器和系统其余部分初始化到一个已知状态.而且还为DOS等操作系统提供硬件设备接口服务。但是由于BIOS提供的这些服务不具备可重入性(即其中程序不可并发运行).并且从访问效率方面考虑,因此除了在初始化时会利用BIOS提供一些系统参数以外.Linux操作系统在运行时并不使用BIOS中的功能。
当计算机系统上电开机或者按了机箱上的复位按钮时.CPU会自动把代码段寄存器CS设置为OxF000.
其段基地址则被设置为OxFFFF0000.段长度设置为64KB.而IP被设置为OxFFFO,因此此时CPU代码指
针指向OxFFFFFFFO处,即4G空间最后一个64K的最后16字节处。由上图可知.这里正是系统ROM BIOS
存放的位置。井且BIOS会在这里存放一条跳转指令JMP跳转到BIOS代码中 64KB范围内的某一条指令
开始执行。由于目前PC/AT微机中BIOS容量大多有1MB到2MB,井存储在闪存(Flash Memory) ROM
中,因此为了能够执行或访问BIOS中超过64KB范围并且又远远不在0-IM地址空间中的其他BIOS代
码或数据.BIOS程序会首先使用一种称为32位大模式(Big Mode)技术把数据段寄存器的访问范围设置
成4G(而非原来的64K).这样就可以在。到4G范围内执行和操作数据。此后.BIOS在执行了一些列硬
件检侧和初始化操作之后,就会把与原来PC机兼容的64KB BIOS代码和数据复制到内存低端IM末端的
64K处.然后跳转到这个地方井且让CPU进入真正的实地址模式工作,见图2-5所示。最后BIOS就会从
硬盘或其他块设备把操作系统引导程序加载到内存Ox7cOO处。并跳转到这个地方继续执行引导程序。
在PC/AT机中.除需要使用内存和ROM BIOS以外。还使用只有很少存储容量的(只有64或128字节)CMOS (Complementary Metal Oxide Semiconductor,互补金属氧化物半导体)存储器来存放算机的实时时钟信息和系统硬件配置信息。这部分内存通常和实时时钟芯片(Real Time Chip)做在一块集成块中。
CMOS内存的地址空间在基本内存地址空间之外。需要使用1/O指令来访问。
IBM PC/AT 80X86兼容微机使用两片级联的8259A可编程中断控制芯片组成一个中断控制器,用于实
现I/O设备的中断控制数据存取方式,并且能为15个设备提供独立的中断控制功能,见图2-6所示。在计
算机刚开机初始化期间,ROM BIOS会分别对两片8259A芯片进行初始化,并分别把15级中断优先级分
配给时钟定时器、键盘、串行口、打印口、软盘控制、协处理器和硬盘等设备或控制器使用。同时在内存
开始处。x000-OxFFF区域内建立一个中断向量表。但是由于这些设置违背了Intel公司的要求(后面章节将
会详细说明).因此Linux操作系统在内核初始化期间又重新对8259A进行了设置。有关中断控制器工作
原理和编程方法的详细说明请参见后续章节。
当一台PC计算机刚上电开机时.上图中的硬件中断请求号会被ROM BIOS设置成表2-2中列出的对
应中断向量号。Linux操作系统并不直接使用这些PC机默认设置好的中断向量号.当Linux系统执行初始
化操作时.它会重新设置中断请求号与中断向量号的对应关系。
如前所述.DMA控制器的主要功能是通过让外部设备直接与内存传输数据来增强系统的性能。通常
它由机器上的Intel 8237芯片或其兼容芯片实现。通过对DMA控制器进行编程,外设与内存之间的数据
传愉能在不受CPU控制的条件下进行。因此在数据传输期间,CPU可以做其他事倩。
在PC/AT机中,使用了两片8237芯片.因此DMA控制器有8个独立的通道可使用。其中后4个是
16位通道。软盘控制器彼专门指定使用DMA通道2。在使用一个通道之前必须首先对其设置。这牵涉到
对三个端口的操作.分别是页面寄存器端口、(偏移)地址寄存器端口和数据计数寄存器端口。由于DMA
寄存器是8位的。而地址和计数值是16位值.因此各自需要发送两次。
Intel 8253/8254是一个可编程定时l计数器(PIT一Programmable Interval Timer)芯片,用于处理计算机
中的精确时间延迟。该芯片提供了3个独立的16位计数器通道。每个通道可工作在不同的工作方式下,
并且这些工作方式均可以使用软件来设置。在软件中进行延时的一种方法是执行循环操作语句.但这样做
很耗CPU时间。若机器中采用了8253/8254芯片,那么程序员就可以配置8253以满足自己的要求并且使
用其中一个计数器通道达到所期望的延时。在延时到后.8253/8254将会向CPU发送一个中断信号。
对于PC/AT及其兼容微机系统采用的是8254芯片。3个定时/if数器通道被分别用于日时钟计时中断
信号、动态内存DRAM刷新定时电路和主机扬声器音调合成。Linux 0.11操作系统只对通道。进行了重新
设置.使得该计数器工作在方式3下.并且侮间隔10毫秒发出一个信号以产生中断请求信号(IRQO)。这
个间隔定时产生的中断请求就是Linux 0.11内核工作的脉搏.它用于定时切换当前执行的任务和统计每个
任务使用的系统资源量(时间).
我们现在使用的键盘是IBM公司于 1984年PC/AT徽机的兼容键盘,通常称为AT-PS/2兼容键盘井具
有101到104个按键。键盘上有一个称为键盘编码器的处理器(Intel 8048或兼容芯片)专门用来扫描收集
所有按键按下和松开的状态信息(即扫描码).并发送到主机主板上键盘控制器中。当一个键被按下时.
键盘发送的扫描码称为接通扫描码(Make code),或简称为接通码;当一个被按下的键放开时发送的扫描
码被称为断开扫描码(Break code).或简称为断开码。
主机键盘控制器专门用来对接收到的键盘扫描码进行解码.并把解码后的数据发送到操作系统的键盘
数据队列中。因为每个按键的接通和断开码都是不同的,所以键盘控制器根据扫描码就可以确定用户在操
作哪个键。整个键盘上所有按键的接通和断开码就组成了键盘的一个扫描码集(Scan Code Set).根据计算
机的发展.目前已有三套扫描码集可供使用.它们分别是:
n 第一套扫描码集一原始XT键盘扫描码集。目前的键盘已经很少发送这类扫描码;
n 第二套扫描码集一现代键盘默认使用的扫描码集.通常称为AT键盘扫描码集;
n 第三恋扫描码集一PS/2键盘扫描码集。原IBM推出PS/2微机时使用的扫描码集,已很少使用。
AT键盘默认发送的是第二套扫描码集。虽然如此。主机键盘控制器为了与PC/XT机的软件兼容起见.
仍然会把所有接收到的第二套键盘扫描码转换成第一恋扫描码.见图2-7所示。因此,我们在为键盘控制
器进行编程时通常只高要7解第一套扫描码集即可。这也是后而涉及键盘编程内容时只给出XT键盘扫描
码集的原因。
键盘控制器通常采用Intel 8042单片微处理器芯片或其兼容电路。现在的PC机都己经将键盘控制器集
成在主板芯片组中.但是功能仍然与使用8042芯片的控制器相兼容。键盘控制器接收键盘发送来的11位
串行格式数据。其中第1位是起始位。第2-,位是8位键盘扫描码。第10位是奇校验校验位.第11位是
停止位。参见下节对串行控制卡的说明。键盘控制器在收到11位的串行数据后就将键盘扫描码转换成
PC/XT标准键盘兼容的系统扫描码.然后通过中断控制器IRQI引脚向CPU发送中断请求。当CPU响应
该中断请求后.就会调用键盘中断处理程序来读取控制器中的XT键盘扫描码。
当一个键被按下时.我们可以从键盘控制器端口接收到一个XT键盘接通码。这个扫描码仅表示键盘
上某个位置处的键被按下,但还没有对应到某个字符代码上。接通码通常都是一个字节宽度。例如.按下
键“A“的接通码是30 (OxIE)。当一个按下的键被松开时,从键盘控制器端口收到的就是一个断开码。
对于XT键盘(即键盘控制器编程端口收到的扫描码).断开码是其接通码加上0x80.即最高有效位(位7)
置位时的接通码。例如,上述”A“键的断开码就是0x80 + Ox 1 E = Ox9E.
但是对于那些PC/XT标准83键键盘以后新添加的(“扩展的“)AT键盘上的按键(例如右边的Ctrl
键和右边的Alt键等),则其接通和断开扫描码通常有2到4个字节。并且第1个字节一定是OxEO。例如,
按下左边的非扩展Ctrl键时会产生1字节接通码OxID,而按下右边的Ctrl键时就会产生扩展的2字节接
通码OxEO. OxID.对应的断开码是OxEO. Ox9D.表2-3中是几个接通和断开扫描码的例子。另外.附录
中还给出了完整的第一套扫描码集。
1.异步串行通信原理
两台计计算机设备进行数据交换.即通信.就好像人们对话一样使用同一种语言。在计算机通信术语中.
我们把计算机/设备与计算机/设备之间的“语言.称为通信协议。通信协议规定了传送一个有效数据长度
单位的格式。通常我们使用术语“帧“来形容这种格式。为了能让通信双方确定收护发的顺序和进行一些错误检测操作.除了必要的数据以外.在传输的一帧信息中还包含起同步和错误检侧作用的其它信息.例如
在开始传输数据信息之前先发送起始/同步或通信控制信息,并且在发送完需要的数据信息之后再传输一些
校验信息等.见图2一所示。
串行通信是指在线路上以比特位数据流一次一个比特进行传愉的通信方式。串行通信可分为异步和同
步串行通信两种类型。它们之间的主要区别在于传输时同步的通信单位或帧的长度不同。异步串行通信以
一个字符作为一个通信单位或一帧进行传愉.而同步串行通信则以多个字符或字节组成的序列作为一帧数
据进行传输。若再以人们之间的对话作比喻,那么异步通信如同对话双方讲话速度很慢,说话时一个字
(word)一个字地“蹦,出来,在说出每个字后可以停顿任意长时间。而同步通信则如同通信双方以连贯
的一句话作为对话单位。可以看出,实际上如果我们把传输单位缩小到一个比特位时(对话时用字母!).
那么以一个字符进行传输的异步串行通信也可以看作是一种同步传输通信方式。因此异步和同步通信的区
分主要是一种习惯或惯例上的划分。
2.异步串行传输格式
异步串行通信传输的帧格式见图2-9所示。传愉一个字符由起始位、数据位、奇偶校验位和停止位构
成。其中起始位起同步作用.值恒为0.数据位是传愉的实际数据,即一个字符的代码。其长度可以是5-8
个比特。奇偶校验位可有可无,由程序设定。停止位恒为1.可由程序设定为1. 1.5或2个比特位。在通
信开始发送信息之前.双方必须设置成相同的格式。如具有相同数量的数据比特位和停止位。在异步通信
规范中,把传送l称为传号(MARK)。传送。称为空号((SPACE)。因此在下面描述中我们就使用这两个
术语。
当无数据传愉时,发送方处于传号(MARK)状态,持续发送l。若需要发送数据.则发送方需要首
先发送一个比特位间隔时间的空号起始位。接收方收到空号后.就开始与发送方同步.然后接收随后的数
据。若程序中设置了奇偶校验位.那么在数据传输完之后迁需要接收奇偶校验位。最后是停止位。在一个
字符帧发送完后可以立刻发送下一个字符帧.也可以暂时发送传号,等一会再发送字符顿。
在接收一字符帧时,接收方可能会检测到三种错误之一:①奇偶校验错误。此时程序应该要求对方重
新发送该字符:②过速错误。由于程序取字符速度慢于接收速度,就会发生这种错误。此时应该修改程序
加快取字符倾率:⑧顿格式错误。在要求接收的格式信息不正确时会发生这种错误。例如在应该收到停止
位时却收到了空号。通常造成这种错误的情况除了线路干扰以外.很可能是通信双方的顿格式设置的不同。
3.串行控制器
为实现串行通信.PC机上通常都带有2个符合RS-232C标准的串行接口.并使用通用异步接物发送
器控制芯片UART (Universal Asyncronous Reccivcdfransmitter)组成的串行控制器来处理串行数据的收发
工作。PC机上的串行接口通常使用25芯或9芯的DB-25或DB-,连接器。主要用来连接MODEM设备进
行工作.因此RS-232C标准规定了很多MODEM专用接口引线。
以前的PC机都使用国家半导体公司的NS8250或NS 16450 UART芯片,现在的PC机则使用了16650A
及其兼容芯片.但都与NS8 2 5 0/1 64 50芯片兼容。NS8250/16450与16650A芯片的主要区别在于16650A芯
片还另外支持FIFO传输方式。在这种方式下.UART可以在接收或发送了最多16个字符后才引发一次中
断.从而可以减轻系统和CPU的负担。当PC机上电启动时.系统RESET信号通过NS8250的MR引脚
使得UART内部寄存器和控制逻辑复位。此后若要使用UART就需要对其进行初始化编程操作.以设置
UART的工作波特率、数据位数以及工作方式等。
对于IBM PC/AT及其兼容计算机而言,可以使用彩色和单色显示卡。IBM最早推出的PC机视频系统标准有单色MDA标准和彩色CGA标准以及EGA和VGA标准。以后推出的所有高级显示卡(包括现在的AGP显示卡)虽然都具有极高的图形处理速度和智能加速处理功能,但它们还是都支持这几种标准。Linux 0. Ix操作系统仅使用了这几种标准都支持的文本显示方式。
1.MDA显示标准
单色显示适配器MDA (Monochrome Display Adapter)仅支持黑白两色显示。井且只支持独有的文本字符显示方式(BIOS 显示方式7)。其屏幕显示规格是80列X 25行(列号x=0..79:行号y=0..24).共可显示20(M〕个字符。每个字符还带有1个属性字节,因此显示一屏(一帧)内容需要占4KB字节。其中偶地址字节存放字符代码,奇地址字节存放显示属性。MDA卡配置有8KB显示内存。在PC机内存寻址范围中占用从Oxb0000开始的8KB空间(Oxb0000-0x62000).如果显示屏行数是video_ num_lines=25;列数是video_num_colums=80,那么位于屏幕列行值X, y处的字符和属性在内存中的位置是:
2. CGA显示标准
彩色图形适配器CGA (Color Graphics Adapter)支持7种彩色和图形显示方式(BIOS显示方式0--6).在80列X 25列的文木字符显示方式下,有单色和16色彩色两种显示方式(BIOS显示方式2-3). CGA卡标配有16KB显示内存(占用内存地址范围Oxb8000一Oxbc000),因此其中共可存放4(16 / 4k(帧) = 4)帧显示信息。同样,在每一帧4KB显示内存中,偶地址字节存放字符代码.奇地址字节存放字符显示属性。但在console. c程序中只使用了其中8KB显示内存(Oxb800()一Oxba000)。在CGA彩色文本显示方式中,每个显示字符的属性字节格式定义见图2-10所示.
与单色显示一样,图中D7置1用于让显示字符闪烁:D3置1让字符高亮度显示;比特位D6, D5, D4
和D2, Dl, DO可以分别组合出8种颜色。前景色与高亮度比特位组合可以显示另外8种字符颜色。这些
组合的颜色见表2-5所示。
3. EGA/VGA 9示标准
增强型图形适配器EGA (Enhanced Grpahics Adapter)和视频图形阵列VGA (Video Graphics Adapter)
除兼容或支持MBA和CGA的显示方式以外。还支持其他在图形显示方面的增强显示方式。在与MBA和CGA兼容的显示方式下.占用的内存地址起始位置和范围都分别相同。但EGA/VGA都标配有起码32KB的显示内存。在图形方式下占用从Oxa0000开始的物理内存地址空间。
PC机的软盘控制子系统由软盘片和软盘驱动器组成。由于软盘可以存储程序和数据并且携带方便.
因此长期以来软盘驱动器是PC机上的标准配置设备之一。硬盘也是由盘片和驱动器组成,但是通常硬盘
的金属盘片固定在驱动器中,不可拆卸。由于硬盘具有很大的存储容量.并且读写速度很快.因此它是PC
机中最大容量的外部存储设备,通常也被称为外存。软盘和硬盘都是利用磁性介质保存信息,具有类似的
存储工作方式。因此这里我们以硬盘为例来简要说明它们的工作原理。
在盘片上存储数据的基本方式是利用盘片表面上的一层磁性介质在磁化后的刹磁状态.软盘通常使用
聚酌薄膜作基片,而硬盘片则通常使用金属铝合金作基片。一张软盘中含有一张聚配薄膜圆盘片.使用上
下两个磁头在盘片两面读写数据,盘片旋转速率大约在300转了分钟。硬盘中通常起码包括2张或者更多张金属盘片.因此具有多个读写磁头。例如.对于包含2个盘片的硬盘中就具有4个物理磁头,含有4个盘
片的硬盘中有8个读写磁头。见图2-11所示。硬盘旋转速率很快通常在4500转/分钟到10000转/分钟,因
此硬盘数据的传输速度通常可达几十兆比特/秒。
位于磁盘表面的磁头上有分别有一个读线圈和写线圈。在读数据操作过程中,磁头首先移动到旋转着
的磁盘某个位置上。由于磁盘在旋转.磁介质相对磁头作匀速运动.因此磁头实际上在切割磁介质上的磁
力线。从而在读线圈中因感应而产生电流。根据磁盘表面刹磁状态方向的不同,在线圈中感应产生的电流
方向也不同,因此磁盘上记录着的0和l数据就被读出.从而可从磁盘上顺序读出比特数据流。由于磁头
读取的每个磁道上都有存放信息的特定格式.因此通过识别所读比特数据流中的格式.磁盘电路就可以区
分并读取磁道上各扇区中的数据,见图2-12所示。其中,GAP是间隔字段.用于起隔离作用。通常GAP
是12字节的0。每个扇区地址场的地址字段存放着相关扇区的柱面号、磁头号(面号)和扇区号.因此通
过读取地址场中的地址信息就可以唯一地确定一个扇区。
为了读写磁盘(软盘和硬盘)上的数据.就必须使用磁盘控制器。磁盘控制器是CPU与驱动器之间的逻辑接口电路,它从CPU接收请求命令.向驱动器发送寻道、读/写和控制信号,并且控制和转换数据流形式。控制器与驱动器之间传输的数据包如图2-12中的扇区地址信息以及定时和时钟信息。控制器必须从实际读/写数据中分离出这些地址信息和一些编码、解码等控制信息。另外,与驱动器之间的数据传输是串行比特数据流,因此控制器需要在并行字节数据和串行比特流数据之间进行转换。
PC/AT机中软盘驱动控制器FDC (Floppy Disk Controllcr)采用的是NEC pPD765或其兼容芯片。它
主要用于接收CPU发出的命令.并根据命令要求向驱动器输出各种硬件控制信号.见图2-13所示。在执
行读/写操作时.它需要完成数据的转换(串---并)、编码和校验操作.并且时刻监视驱动器的运行状态。
对磁盘控制器的编程过程就是通过I/O端口设置控制器中的相关寄存器内容,并通过寄存器获取操作
的结果信息。至于扇区数据的传输,则软盘控制器与PLAT硬盘控制器不同。软盘控制器电路采用DMA
信号,因此需要使用DMA控制器实施数据传输。而AT硬盘控制器采用高速数据块进行传输,不需要DMA
控制器的介入。
由于软盘片比较容易遭到损坏(发霉或划伤).因此目前计算机中已经逐渐开始不配置软盘驱动器,
起而代之的是使用容最较大并且更容易携带的U盘存储器。
硬件是操作系统运行的基础平台。了解操作系统运行的硬件环境是深入理解运行其上操作系统的必要
条件。本章根据传统微机的硬件组成结构,简单介绍了微机中各个主要部分。下一章我们从软件角度出发
介绍编制Linux内核所使用的两种汇编语言语法和相关编译器,同时也介绍了编制内核使用的GNU gec语
法扩展部分的内容。