一、一致编址与独立编址
从CPU连出来一把线:数据总线、地址总线、操控总线,这把线上挂着N个接口,有相同的,有不同的,姓名叫做存储器接口、中止操控接口、DMA接口、并行接口、串行接口、AD接口……一个设备要想接入,就用自己的接口和总线上的某个匹配接口对接……所以总线上呈现了各种设备:内存、硬盘,鼠标、键盘,显示器……
关于CPU而言,假如它要发数据到某个设备,其实是发到对应的接口,接口电路里有多个寄存器(也称为端口),拜访设备实际上是拜访相关的端口,一切的信息会由接口转给它的设备。那么CPU会预备数据到数据总线,可是许多接口,该发给谁呢?这时就须要为各接口分配一个地址,然后把地址放在地址总线上,需求的操控信息放到操控总线上,就能够和设备通讯了。
对一个体系而言,一般会有多个外设,每个外设的接口电路中,又会有多个端口,每个端口都需求一个地址,为他们标识一个详细的地址值,是体系有必要处理的事,与此同时,你还有个内存条,或许是512M或1G或更大的金士顿、现代DDR2之类,他们的每一个地址也都需求分配一个标识值,其他,许多外设有自己的内存、缓冲区,就像你的内存条相同,你相同需求为它们分配内存……你的CPU或许需求和它们的每一个字节都打交道,所以:别盼望偷闲,它们的每一寸土地都要规划好!这听起来就很烦,做起来或许就直接导致脑细胞悉数阵亡。但工作总是得有人去做,ARM或许会这样做:他这次规划的CPU是32位的,最多也就能寻址2^32=4G空间,所以把这4GB空间丢给内存和端口,让他们分割。但英特尔或许有更好的分配方法……
1、地址的概念
1)物理地址:CPU地址总线传来的地址,由硬件电路操控其详细意义。物理地址中很大一部分是留给内存条中的内存的,但也常被映射到其他存储器上(如显存、BIOS等)。在程序指令中的虚拟地址经过段映射和页面映射后,就生成了物理地址,这个物理地址被放到CPU的地址线上。
物理地址空间,一部分给物理RAM(内存)用,一部分给总线用,这是由硬件规划来决议的,因此在32 bits地址线的x86处理器中,物理地址空间是2的32次方,即4GB,但物理RAM一般不能上到4GB,由于还有一部分要给总线用(总线上还挂着其他许多设备)。在PC机中,一般是把低端物理地址给RAM用,高端物理地址给总线用。
2)总线地址:总线的地址线或在地址周期上发生的信号。外设运用的是总线地址,CPU运用的是物理地址。
物理地址与总线地址之间的关系由体系的规划决议的。在x86平台上,物理地址便是总线地址,这是由于它们同享相同的地址空间——这句话有点难了解,详见下面的“独立编址”。在其他平台上,或许需求转化/映射。比方:CPU需求拜访物理地址是0xfa000的单元,那么在x86平台上,会发生一个PCI总线上对0xfa000地址的拜访。由于物理地址和总线地址相同,所以凭眼睛看是不能确认这个地址是用在哪儿的,它或许在内存中,或许是某个卡上的存储单元,乃至或许这个地址上没有对应的存储器。
3)虚拟地址:现代操作体系遍及选用虚拟内存办理(Virtual Memory Management)机制,这需求MMU(Memory Management Unit)的支撑。MMU一般是CPU的一部分,假如处理器没有MMU,或许有MMU但没有启用,CPU履行单元宣布的内存地址将直接传到芯片引脚上,被内存芯片(物理内存)接纳,这称为物理地址(Physical Address),假如处理器启用了MMU,CPU履行单元宣布的内存地址将被MMU截获,从CPU到MMU的地址称为虚拟地址(Virtual Address),而MMU将这个地址翻译成另一个地址发到CPU芯片的外部地址引脚上,也便是将虚拟地址映射成物理地址。
Linux中,进程的4GB(虚拟)内存分为用户空间、内核空间。用户空间散布为0~3GB(即PAGE_OFFSET,在0X86中它等于0xC0000000),剩余的1G为内核空间。程序员只能运用虚拟地址。体系中每个进程有各自的私有用户空间(0~3G),这个空间对体系中的其他进程是不行见的。
CPU宣布取指令恳求时的地址是当时上下文的虚拟地址,MMU再从页表中找到这个虚拟地址的物理地址,完结取指。相同读取数据的也是虚拟地址,比方mov ax, var. 编译时var便是一个虚拟地址,也是经过MMU从也表中来找到物理地址,再发生总线时序,完结取数据的。
2、编址方法
1)外设都是经过读写设备上的寄存器来进行的,外设寄存器也称为“I/O端口”,而IO端口有两种编址方法:独立编址和一致编制。
一致编址:外设接口中的IO寄存器(即IO端口)与主存单元相同看待,每个端口占用一个存储单元的地址,将主存的一部分划出来用作IO地址空间,如,在PDP-11中,把最高的4K主存作为IO设备寄存器地址。端口占用了存储器的地址空间,使存储量容量减小。
一致编址也称为“I/O内存”方法,外设寄存器坐落“内存空间”(许多外设有自己的内存、缓冲区,外设的寄存器和内存总称“I/O空间”)。
如,Samsung的S3C2440,是32位ARM处理器,它的4GB地址空间被外设、RAM等分割:
0x8000 1000 LED 8*8点阵的地址
0x4800 0000 ~ 0x6000 0000 SFR(特别暂存器)地址空间
0x3800 1002 键盘地址
0x3000 0000 ~ 0x3400 0000 SDRAM空间
0x2000 0020 ~ 0x2000 002e IDE
0x1900 0300 CS8900
独立编址(独自编址):IO地址与存储地址分隔独立编址,I/O端口地址不占用存储空间的地址规模,这样,在体系中就存在了另一种与存储地址无关的IO地址,CPU也有必要具有专用与输入输出操作的IO指令(IN、OUT等)和操控逻辑。独立编址下,地址总线上过来一个地址,设备不知道是给IO端口的、仍是给存储器的,所以处理器经过MEMR/MEMW和IOR/IOW两组操控信号来完成对I/O端口和存储器的不同寻址。如,intel 80×86就选用独自编址,CPU内存和I/O是一同编址的,便是说内存一部分的地址和I/O地址是堆叠的。
独立编址也称为“I/O端口”方法,外设寄存器坐落“I/O(地址)空间”。
关于x86架构来说,经过IN/OUT指令拜访。PC架构一共有65536个8bit的I/O端口,组成64K个I/O地址空间,编号从0~0xFFFF,有16位,80×86用低16位地址线A0-A15来寻址。接连两个8bit的端口能够组成一个16bit的端口,接连4个组成一个32bit的端口。I/O地址空间和CPU的物理地址空间是两个不同的概念,例如I/O地址空间为64K,一个32bit的CPU物理地址空间是4G。如,在Intel 8086+Redhat9.0 下用“more /proc/ioports”可看到: