您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 咨询培训 > 程序员看计算机与操作系统原理
程序员看计算机的启动与运行虚拟地址总线(虚拟地址空间)CPU物理地址总线(内存物理地址空间)TLB页表缓冲MMUDRAMCPU数据总线CPU控制总线IO总线AGP……PCI透明桥(实现将PCI物理地址转发到下属设备)(下属设备共享本桥地址空间如0xF1000000:限长128M)PCI设备(PCI地址空间范围,如0xF0000000:限长1000)CPUPCI控制器(实现将CPU物理地址转发到下属设备)PCI设备(从桥分配得到地址范围0xF1001000~0xF1003000)PCI数据总线/地址总线PCI控制总线PCI设备(从桥分配得到地址范围0xF1001000~0xF1003000)PCIeBIOSCache1)系统上电:挂接到CPU外部总线的BIOS启动,此时CPU的程序指针寄存器IP=0xFFFF:0000,cs段寄存器初始值所有位全部为1,段内偏移为0,因此从0xFFFF0开始装载第一条指令到CPU指令解析系统(BIOS芯片对CPU发出的寻址信息0xFFFF0会进行处理,解析地址并将数据放到数据总线上,并告诉CPU数据准备好),这里intel处理器的初始化状态决定了BIOS应该译码什么地址。而CPU对地址线和数据线的处理决定了可寻址的范围和数据宽度。如果是ARM中,CPU上电后第一步是从0x00000000开始运行,此时必须有存储设备对该地址做出反应(就是给CPU提供数据),而且ARM一开始就可以进入32位模式,可以直接寻址4G空间,同时一次也可以传输32位数据。因为ARM一开始就不需要兼容8位和16位模式。如果没有BIOS芯片呢,那么主板上电后,CPU发出寻址后就处于等待状态,那么此时控制总线和地址总线就处于固定的电平。如果有BIOS芯片,但是BIOS芯片不对0xFFFF0地址进行应答,那么CPU还是一样没有反应。CPU永远都是将指令中的寻址放到地址总线上,并发出读或写命令,如果是写,还要把数据放在数据总线上,总线状态(数据)保持是CPU逻辑修改总线锁存器(寄存器)实现的。2)BIOS应答CPU的寻址,第一条指令被装入CPU运行,一般这条指令就是简单的跳转指令,跳转到BIOS程序的入口,这个入口地址是BIOS程序设计者决定的,程序员编写、编译、链接后下载到BIOS芯片中,BIOS芯片的功能就是将程序存储区的数据放到CPU数据总线上。BIOS就是一个裸机驱动程序。在ARM等处理器系统中,一样会有BIOS系统,如s3c6410,可以设置从IROM启动,这个就是芯片内的BIOS,其中的程序是芯片开发厂家写入的,相对于个人电脑的BIOS来说,IROM中的程序相对比较简单,它负责从设备加载软件到内存运行。就如PC机的BIOS可以从硬盘、光盘、USB等设备中加载程序到内存运行一样。在PC机中可以通过CMOS设置从哪个设备启动,而在s3c6410中通过引脚配置来决定从哪个设备加载程序运行。例如6410配置从NORFlash启动,那么NORFlash芯片必须包含程序,就类似PC机的BIOS芯片,如果配置从NANDFlash或SD卡启动,那么首先运行的是IROM中的程序,IROM中的程序负责从NAND或SD卡启动,因此IROM中至少应该包含对NAND和SD控制器的驱动(这里说的驱动,就是一段程序,程序设计者清楚怎样读写控制器的寄存器来与设备进行数据交换,与操作系统下的驱动程序是两个概念,因为操作系统下的驱动重点在于解决进程共享问题)。无论怎样配置,CPU要么从ROM中执行程序,要么从RAM中执行,其他设备中的程序必须要经过引导程序加载到RAM中才能运行。当然这不是绝对的。如果一个设备可以被随机寻址,那么这个设备就是一个ROM或RAM,如果不能随机寻址,那么就是块设备,所谓随机寻址,就是CPU放一个地址到总线上,那么该设备就马上将数据放到数据总线上,这样CPU的地址与设备的存储空间形成线性对应关系,而且设备可以根据CPU地址做出输出相应地址数据的反应。这样的设备通常比块设备成本高,而通常用来永久存储程序和数据的设备是块设备而不是ROM,块设备的读写是按照块方式进行的,就是一次必须完成一个块的数据交换,例如CPU输出地址0x0001,如果有ROM挂接在这个地址,那么ROM会做出反应,如果是块设备,那么块设备控制器做出反应,块设备做出反应的原因是因为那个地址刚好是自己的寄存器地址,而ROM做出反应的原因是因为那个地址是自己内部存储器的地址。当向ROM写入两个数据A和B,那么可能是两次的MOV指令MOV[0x0001],AMOV[0x0005],B而向块设备写入数据,一样采用MOV指令,MOV[0x0001]A,这里0x0001是块设备的数据寄存器地址,MOV[0x0001]B,当然过程没这么简单,要向块设备控制寄存器输出命令,并向块设备地址寄存器输出块内地址。每次只要输出一个地址,例如写磁盘扇区数据MOV[0x0002],1假设0x0002是磁盘控制器的扇区号寄存器,那么表示要读写磁盘第1号扇区。MOV[0x0003],1假设0x0003是磁盘控制器命令控制器,1表示写,那么接下来就是要向磁盘写一个扇区512字节的数据。然后就可以采用“MOV[0x0001],数据”方式连续输出512字节数据到磁盘。可见,CPU指令操作ROM的地址范围就是ROM的可寻址范围,如ROM有1MB,那么在CPU指令中出现的地址就可以是1M个不同的连续地址。而对于块设备,就是很少的几个寄存器占用了CPU的地址空间,在CPU指令中无论你读写的磁盘有多大,它是固定的几个地址,我们通过循环地使用这几个地址(寄存器)实现向磁盘内部存储空间写入数据或读出数据。这里顺便提下,字符设备,所谓字符设备,就是一次只写或读一个字节,而块设备,必须采用循环指令一次读写规定字节的数据。因此一般字符设备直接将读写的数据通过CPU寄存器来转交给其他程序处理,而块设备因为要一次读写多个字节,因此必须在内存中开辟一个区域来存放数据,这就是块设备的缓冲区。当然字符设备驱动程序也一样可以开辟一个区域来存放多次读写过程的数据,但那不是硬件必须要求的。3)BIOS启动后,会初始化CPU、内存控制器、扫描PCI设备以及其他硬件检测,CPU初始化如高速缓冲功能的启用、运行模式设置,内存控制器初始化必须解决内存位置、类型及大小的检测、扫描PCI就是发现PCI上的设备,PCI是连接外设的桥梁,如声卡、显卡、USB控制器等都连接到PCI总线上。BIOS通过读写PCI控制器IO端口来配置PCI设备,在PCI控制器中会保存一个设备清单表,记录了PCI设备在哪个位置、对应的PCI总线地址。这里要理解CPU总线地址和PCI总线地址的区别:CPU总线地址:是CPU指令中出现的地址,也就是我们汇编程序指令中的地址(如果不考虑虚拟地址概念)。这个地址空间在32位时是4G,等下我们看这4G地址的分布情况。PCI总线地址:因为在PCI控制器两边是独立的电信号,两边是互不影响的,因此PCI控制器就如一个中转站,负责将CPU给出的地址解析输出到PCI外部总线上。对于设备来说,与它打交道的是PCI控制器,而PCI控制器对设备的寻址就是采用PCI总线地址,PCI总线地址可以比CPU总线宽,也可以比CPU总线窄。例如一个PCI控制器下管理的外设使用地址空间如果只有1M,那么,就只要20根地址线就可以寻址全部空间,那么PCI总线完全可以设计成20根地址线。当CPU发出寻址时,如果是在物理内存(内存条)地址范围,那么内存控制器会做出反应,如果是在PCI地址范围,那么PCI控制器就会做出反应。PCI控制器将CPU发出的地址通过查表或直接加上地址偏移放到PCI总线上,那么相应的设备就会对PCI总线地址进行译码并做出反应。设备从数据总线获得或输出数据。如果一个系统中有4G物理内存,PCI设备需要1G地址空间,那么需要5G地址空间,采用32位地址是没法解决的,因此BIOS在系统初始化时,就会检查内存条、PCI控制器,然后设置内存控制器对3G以上地址不做出反应,那么就有1G的内存被浪费了,然后将PCI控制器配置为占用0xC0000000~0xFFFFFFFF,而在这1G空间中,各设备怎样分配地址是BIOS决定的,各个PCI设备的地址必须可以动态配置。当BIOS向PCI设备基址寄存器写入地址后,设备就可以根据基地址对PCI总线地址做出反应。这里注意设备是对PCI总线地址译码,因此其寄存器中保存的也是PCI总线地址。例如一个设备申请0x1000大小的地址空间,BIOS扫描PCI总线时读取到设备的配置空间的数据(这些数据对于PCI板卡一般保存在EEPROM中,对于基地址寄存器BAR的值BIOS是动态分配的,限长limit由设备初始化时给定,BAR寄存器中设备设定的值告诉了BIOS自己需要的是IO地址空间还是内存地址空间),BIOS设置设备的一些参数后,程序就可以直接读写内存地址来访问PCI设备的内存空间。PCI设备的配置空间:所谓配置空间,就是一个数据块,CPU访问这个数据块是通过IO指令访问固定寄存器实现的:如读写0x0CF8和0x0CFC端口来配置设备,在0x0CF8写入要配置的设备参数地址(如OUT0x0CF8,#F1000001),并在0x0CFC写入参数值数据。设备的参数配置好后,我们就可以在程序通过直接的地址读写来访问设备内存空间。配置空间是设备与BIOS交流的场所。设备内存范围:PCI设备通常是一些数据吞吐量的设备,当然也可能是简单的高速设备,一般设备中维护了一个内存块,这个内存块通过控制器直接挂接到了PCI总线上,这个内存块与内存条是一样的,它在PCI总线上有一个地址范围,当PCI总线上出现的地址与自己相同,那么PCI设备会做出应答反应(读写总线数据)。CPU发出的地址是内存寻址,当经过PCI控制器后会转换成PCI总线地址,在x86系统中,CPU地址通常被PCI控制器直接映射为PCI总线地址,也就是说PCI控制器的两端地址相同,但是这也不能说PCI控制器没有对CPU地址进行变换,PCI将并行的CPU的地址总线和数据总线变成了在一个复用总线上传输,同一个时间只能是地址或数据。我们用CPU指令向设备内存地址写入数据时,被PCI控制器转换并广播到PCI总线上,然后设备响应,这个过程是硬件完成的,因此对于程序员来说,PCI设备就好像挂接在CPU总线上一样。设备IO范围:或者叫IO空间,在X86系统中,外设有一个独立的地址空间叫IO空间,在ARM中外设只能通过访问内存指令操作作,因此与内存地址空间共享。而X86系统中PCI设备也一般采用内存地址来操作,但是有些设备也提供独立的IO地址接口,一般读写IO地址空间数据量比较小,但是读写速度可以更快。PCILocalBus协议规定了访问PCI设备配置空间的2个I/O端口寄存器:CONFIG_ADDRESS(地址0CF8h)和CONFIG_DATA(地址0CFCh).它们均为双字寄存器,其中CONFIG_ADDRESS为地址寄存器,用以定位PCI设备并指明待访问的配置空间寄存器地址编号;CONFIG_DATA为数据寄存器,用以储存上述PCI设备指定的配置空间寄存器的内容.CONFIG_ADDRESS寄存器的内部结构如下:B31(EnableBit):访问PCI设备配置空间使能位,1访问允许,0访问禁止;B23:B16(BusNum):PCI设备所在的系统PCI总线编号,范围为0~255;B15:B11(DevNum):PCI设备的设备号,范围为0~31;B10:B8(FunNum):PCI设备的功能号,范围为0~7(若设备支持多功能);B7:B2(RegNum):待访问的配置空间寄存器的地址编号,要求是4的倍数;B1B0两位只读,读出值始终为0,其余位保留。4)BIOS在完成内存控制器初始化后,就可以将自己COPY内存中运行,BIOS完成设备检测及初始化后就开始根据CMOS的boot配置来查询启动设备,此时BIOS可以直接通过读写内存地址来与PCI上的磁盘驱动控制器交互数据(BIOS中硬盘驱动
本文标题:程序员看计算机与操作系统原理
链接地址:https://www.777doc.com/doc-2150895 .html