计算机组成原理
Linux 操作系统是UNIX 操作系统的一种克隆系统。它诞生于1991 年的10 月5 日(这是第一次正式向外公布的时间)。以后借助于Internet 网络,并经过全世界各地计算机爱好者的共同努力下,现已成为今天世界上使用最多的一种UNIX 类操作系统,并且使用人数还在迅猛增长。当然,对于零基础的同学来说,在学习Linux之前,我们先来了解一些计算机的基础知识。
1946年2月14日,由美国军方定制的世界上第一台电子计算机“电子数字积分计算机”(ENIAC Electronic Numerical And Calculator)在美国宾夕法尼亚大学问世了,自此计算机以惊人的速度发展。
从ENIAC到当前最先进的计算机都采用的是冯·诺依曼体系结构。所以冯·诺依曼被计算机界称为数字计算机之父。冯诺依曼提出将计算机分为5大结构,分别是:控制器,运算器,存储器,输入与输出设备。控制器控制着各大部件的运作,运算器实现算术运算和逻辑运算,存储器用来实现数据的存储,输入输出设备负责数据流的输入与输出。如图1-1
图1-1
计算机的5大部件在控制器的统一指挥下,有条不紊的自动工作。由于运算器和控制器在逻辑关系上联系十分紧密,尤其在大规模集成电路制造工艺出现后,这两大部件往往集成在同一芯片上,我们将它称之为CPU。把输入输出设备称为I/O设备,而且各位要注意的是,我们所说的主机是指:CPU+内存。
要知道的是,计算机只识别二进制,所谓的二进制,简单的理解来说就是表示两种状态,用0或1来表示。所以数据在计算机中的形式就是用二进制来表示的。每一种状态(0或1)我们称作一个位(bit),在计算机中,我们将8位为一个组,称为一个字节。那么数据就是以字节的方式存储在内存单元中。至于到底以多少字节存储,这还要看它的数据类型。
当然,我们不扯那么远,回到正题,那么CPU要想处理数据,必须从内存中取出数据操作的指令。那么什么是指令?说的简单点,计算机指令就是指挥机器工作的指示和命令,程序就是一系列按一定顺序排列的指令,执行程序的过程就是计算机的工作过程。所以我们也可以说,程序是由数据+指令组成。每个CPU都有自己的一套处理数据的指令,这就是指令集,他们的实现方式可能有所不同,所以有可能造成的问题就是,系统移植困难,即平台的不兼容。
常见的CPU类型:x86、x86_64,常见的就是我们电脑通常使用的Intel的CPU和AMD的CPU;IBM公司生产的服务器AIX使用的就是CPU架构是powerpc;HP公司的服务器HP-UX使用的CPU架构是Alpha;还有就是我们手机常见的ARM架构。为什么我要谈这个呢?因为至少现在我们要知道,CPU根据指令的类型分为精简指令集(Reduced Instruction Set Computing )和复杂指令集(Complex Instruction Set Computing)。RISC与CISC的区别在于:RISC是在CISC指令系统基础上发展起来的,有人对CISC机进行测试表明,各种指令的使用频度相当悬殊,最常使用的是一些比较简单的指令,它们仅占指令总数的20%,但在程序中出现的频度却占80%。复杂的指令系统必然增加微处理器的复杂性,使处理器的研制时间长,成本高。并且复杂指令需要复杂的操作,必然会降低计算机的速度。属于RISC类的CPU:powerpc、arm、alpha。那么CISC:Intel、AMD。另外要知道的是,RISC型CPU与Intel和AMD的CPU在软件和硬件上都不兼容。也就是说,由于微指令集的不同,所以将一款CPU的计算机设计的程序放到另一款CPU上的计算机去,可能无法运行。这就是我们应该考虑的CPU的兼容性问题。
好的,到目前为止至少我们知道了,CPU要想处理数据,需要从内存中去获取到处理数据的指令,但是另外要知道的是CPU的处理速度比内存处理的速度要快的多,那怎么办呢?那么为了协调CPU与内存之间的速度匹配问题,我们在其中间加入了缓存。实际工作时,CPU往往需要重复读取同样的数据块,而缓存容量的增大,可以大幅度提升CPU内部读取数据的命中率,而不用再到内存或者硬盘上寻找,以此提高系统性能。但是由于CPU芯片面积和成本的因素来考虑,缓存都很小。所以在CPU内部,缓存又分成了一级缓存,二级缓存等等,这就是为了减少在内存上搜索数据时的CPU等待时间。那CPU从内存或缓存中取出指令,放在哪里呢?CPU从存储器或缓存中取出指令,放入指令寄存器,并对指令译码。它把指令分解成一系列的微操作,然后发出各种控制命令,执行微操作系列,从而完成一条指令的执行。
说了这么多,无非就是想简单的描述一下CPU工作的概念过程,为了便于学习的理解,现在我们重新总结:
第一阶段:CPU从存储器或缓存中检索指令,由程序计数器(Program Counter)指定存储指令的位置。(程序计数器是寄存器的一种,它的作用是存放着下一条指令的地址,程序计数器简称PC)。这个过程是是将内存中的指令复制到寄存器中去,我们称为加载。
第二阶段:CPU根据存储器提取到的指令来决定其执行行为。我们称为操作。
第三阶段:接着进入执行阶段。该阶段中,连接到各种能够进行所需运算的CPU部件。例如,要求一个加法运算,算术逻辑单元(ALU,Arithmetic Logic Unit)将会连接到一组输入和一组输出。输入提供了要相加的数值,而输出将含有总和的结果。ALU内含电路系统,易于输出端完成简单的普通运算和逻辑运算(比如加法和位元运算)。如果加法运算产生一个对该CPU处理而言过大的结果,在标志暂存器里可能会设置运算溢出(Arithmetic Overflow)标志。
第四阶段:运算器运算的结果会被暂时写入到寄存器,再由寄存器写回内存,这个过程我们称之为存储。随之,PC计数器里面的值更新,指向下一条要处理的指令。这个过程称为跳转。
说到这,我们可以发现,CPU和内存可以说是计算机的核心结构了,那么我们现在单独来介绍计算机硬件中一些比较重要的概念。
CPU
CPU可以称作微处理器,它是计算机系统的核心,CPU进行算术运算或者逻辑运算并且管理来自主存的指令并执行它。CPU的操作对象是二进制数据;数据由0 和1 组成。1 和0 对应着电子开关的开路与断路状态。CPU的执行由外部时钟来监控。这个时钟称为系统时钟,它每隔相同的时间间隔就向CPU发送一个脉冲。在每个时钟脉冲上,CPU都会做一些工作。比如,CPU每个时钟脉冲上执行一条指令。CPU的速度一般以系统时钟的速率来描叙,我们称之为主频。一个100MHz 的处理器每秒将接收100,000,000 个时钟滴答,这就意味着CPU可以有100,000,000个指令周期,但是用CPU主频来描叙CPU的工作能力是不正确的,因为它们所包含的指令集不同,所以执行的指令不相同,既然执行的指令不同,所以它的指令周期就不同,所以拿主频来进行不同CPU性能的比较是不合适的。另外,CPU的主频很高,但是内存的速度却无法达到CPU的速度,所以不仅看主频,还要看CPU与内存之间同步的那个频率,这个频率我们叫做外频。此外,要处理的指令必须是从内存中取出来的,至于一次性从内存中取出多少位(bit),关键还是要看CPU的机器字长。如32位的CPU,那么一次性能从内存中取出2^32Bytes,大概就是4G的样子,这也是为什么32位的CPU最大只能支持4G的内存,当然你也可以采取一些技术去扩展内存,但是这里我们就不多解释了。那么指令从内存中出去来之后必须要放在一个合适的地方,这个地方就是我们的寄存器了。寄存器存放着来自内存的指令并且执行其里面存放的指令。不同的CPU,其寄存器的大小,数量,类型也不同。但是大概也差不多。比如我们上面所说的PC(程序计数器),他就是其中的一款寄存器,它的作用是存放着下一条指令的地址。另外,如果需要重复访问内存一些数据,可以临时存储在堆栈指针寄存器(SP)中,它采用先进先出(栈)或先进后出(堆)的方式来进行临时数据的访问。然后,指令的执行结果将保存在状态寄存器(PS)中,当然,为了方便理解,我只是简化了这些寄存器的作用,如果想知道更详细的内容,可以查阅相关资料。
内存
所有计算机系统都有一个由不同速度与大小的存储器组成的层次结构。最快的存储器是高速缓存,它被用来暂存主存中的内容。这种存储器速度非常快但非常昂贵,大多数CPU都含有少量的片上高速缓存或者将其放在主板上。通过加入这种缓存中间层的机制,使得CPU与内存之间更加协调工作。具体我们可以看下图:
一般来说,越靠近寄存器的价格越高,容量越小,并且访问数据的速度快。
总线
主板上分立的部件通过称为总线的线路连接在一起。系统总线的功能在逻辑上被划分为三部分:
地址总线、数据总线和控制总线。地址总线为数据传输指明内存位置(地址)。数据总线包含传输的数据。数据总线是双向的;它允许数据读入CPU也支持从CPU读出来。控制总线则包含几条表示路由分时和系统的控制信号。这些总线通过总线插槽与扩展设备控制器连接,常见的总线接口有:例如ISA 和PCI,总之,总线是将外设连接到系统的常用方式。至于具体内容,可网上浏览。
控制器和外设
外设是一些物理设备,比如说图象卡或者磁盘,它们受控于位于主板或者主板上插槽中的控制芯片。IDE 磁盘被IDE 控制器芯片控制,而SCSI 磁盘由SCSI 磁盘控制器芯片控制。这些控制器通过各种总线连接到CPU 上或相互间互连。目前制造的大多数系统使用PCI 和ISA总线来连接主要系统部件。控制器是一些类似CPU 的处理器,它们可以看做CPU 的智能帮手。CPU 则是系统的总控,而控制器可以理解为是他们管理I/O设备的秘书。在总线上的每个控制器可以被CPU 所单独寻址,这是软件设备驱动程序能写入寄存器并能控制这些控制器的原因。
I/O端寻址
CPU为了访问外设控制器上的数据和状态信息,需要首先指出它们的地址,这种地址称为I/O端口地址,或者简称端口。通常一个I/O控制器的端口包括了访问数据的数据端口,输入命令的命令端口,和控制器执行状态的状态端口。端口地址的设置方法一般有两种:统一编址和独立编址。
端口统一编址的原理是把I/O控制器中的端口地址归入存储器寻址地址空间范围内。因此这种编址方式也称为存储器映像编址。CPU访问一个端口的操作与访问内存的操作一样,也使用访问内存的指令。端口独立编址的方法是把I/O控制器的寻址空间单独作为一个独立的地址空间对待,称为I/O地址空间。每个端口有一个I/O地址与之对应,并且使用专门的I/O指令来访问端口。一般选择采用的是端口独立编址的方式
比如:我要输入echo “hello”命令,让其在屏幕上显示,那么首先,我们要将echo “hello”这些字符用键盘输入,键盘上有一个称为键盘编码器的东西,它专门用来扫描按键所按下和松开的状态信息(我们叫它扫描码),并且将这些扫描码发送到键盘控制器中。每当我们敲入一个按键后,那么CPU就会寻址键盘控制器的端口,然后赋予键盘控制器一些处理权限,于是键盘控制器将接收过来的扫描码进行解码,并把解码的数据发送到操作系统的键盘数据队列中,再由控制器将权利并执行结果的状态信息交还给CPU,CPU根据执行的结果的状态信息并通过寻址找到显卡控制器所对应的端口,然后赋予显卡控制器相应的处理权限,显卡控制器通过I/O操作指令,对其相应的I/O端口区域进行写操作,这样屏幕的内容就显示出来了。还是那句话,这里只是简化了具的工作过程,反正我的理解就是,CPU访问I/O设备,就会将自己的秘书(I/0控制器)叫来,然后把什么事情都交给秘书做就行了,然后做完事情之后,秘书要把做好的结果上报给领导(CPU),然后由领导决定下一件事该做啥。
CPU访问I/O设备的方式
CPU访问I/O设备有三种方式:轮询、中断、DMA(直接访问内存)。下面我们分别来进行介绍:
轮询:就是CPU通过循环查询I/O设备来查看控制器中的状态信息。也就是说,CPU会挨家挨户的查看哪个I/O设备有请求。这种方式耗费了大量的CPU的时间,所以效率不怎么好。
中断:说的通俗点,就是CPU不再挨家挨户去看谁有请求了,而是等待有I/O请求的设备去叫它,也就是说,你需要请求写操作,你就申请,这时候,CPU就会放下手头要处理的事情,马上去响应你的回答,这就是我们所说的中断。当完成中断请求的服务后,CPU又会继续做刚才停下来的事情。Linux大多数I/O设备控制都采用这样的方式。
DMA:直接访问内存,上面的轮询和中断都需要经过CPU的处理,才能将它搬入内存,那么采用DMA技术,数据不需要经过CPU而直接进入内存,这样操作的效率很高。
原创文章,作者:N24_小辉,如若转载,请注明出处:http://www.178linux.com/54900