外设寻址及内存映射

1. 地址总线与外设接口

1.1 地址总线

整个系统中的总线分为各种类型,这里我们只关心CPU地址总线和各类外设的地址总线,CPU的地址总线和CPU的位数相同,32位的CPU有32根地址线,这些地址线是并行的。而外部设备的地址总线有可能是串行的,如IIC设备、PCIE设备(实际上大多数外设的总线都是串行的)。CPU地址总线和外设地址总线的关系如下图1所示。

1.2 接口

从图中可以看到,两种地址总线通过“接口”连接在一起,这里所说的接口是硬件设备,负责数据缓冲、地址锁定、串/并转换等功能。我们这里最关心的是接口的串/并转换的功能,如前所述,CPU为了提高访问速度,其地址总线(当然也包括数据总线,很多CPU地址总线和数据总线是复用的)都是并行的,而外部设备总线为了节省资源,一般都采用串行结构。这样就有一个转换的问题,接口就是为了实现这个功能的,这样做的好处就是CPU可以不关心外部设备的各种电气特性和读写时序,而是采用统一规范来访问各种外部设备。

CPU加上各类外设接口通常被封装在一个芯片中,很多嵌入式芯片就是这么做的,如经典的80C51单片机,当然还有我们的子卡,也是这么做的。

2. 统一编址与独立编址

2.1 物理地址空间

由于CPU的地址总线位数是固定的,而且采用并行结构,所以其能访问的物理设备地址空间也是有限的,对于32位系统,其物理地址空间为2^32=4GB。这里要注意的一点是这4GB是物理地址的访问空间,与应用程序中的逻辑内存空间不是一个概念。这里的4GB是操作系统最多能访问到的空间,是物理意义上的,而逻辑内存空间是虚拟地址空间,是一个进程最大的可用内存,如一个系统中有10个进程,则会有400G的虚拟内存空间,这400G虚拟内存空间都会通过硬件及操作系统的映射,最终映射到4GB物理地址空间上,其中的映射关系比较复杂,不在这里讨论。

2.2 编址方式

由于CPU访问物理地址空间有限,而外部设备也需要一个地址让CPU来访问,这就会有一个争夺物理地址空间的问题。本来4GB的物理地址空间都是给内存使用的,但现在多了很多外部设备,这些外部设备中的寄存器也需要空间。CPU给这些外部设备分配空间的方式有两种:统一编址与独立编址。

统一编址是指所有外部设备和内存放到一起编址,共同瓜分这4GB的物理地址空间。显然,这样做会使得内存分到的地址空间减小,好处是CPU可以通过统一的指令来访问所有外设和内存。

独立编址是指采用一根单独的控制线来区分此时是访问内存还是访问外设。例如,这根线为高电平时访问的是内存,为低点平时访问的是外设。这么做实际上是增加了一位地址线,所以实际的物理地址空间可以达到8G,但由于外设的寄存器都比较少,所以一般系统仅仅支持64K的空间给所有外设,这64K和4G内存物理空间是独立的。

3. 物理地址空间的映射

3.1 64K物理空间包括什么

前面说到,无论是统一编址还是独立编址,都是对外部设备寄存器的编址,那么就要明确一下这些寄存器到底是哪些寄存器,这里要对外部设备有一些了解。以常见的硬盘或者FLASH为例,其存储容量达几百个G甚至更高,这些地址空间都需要映射吗?这显然是不可能的。其实,给外设寄存器编址中说的寄存器,是外设接口中的寄存器。每种外设接口都有几个或可读或写的寄存器,它们一方面记录了硬件的基本信息,更重要的,是控制整个外设的一个接口,也就是说CPU只要按照外设要求对这几个寄存器进行读写,就可以控制整个外设,这些寄存器一般都比较少,所以对于现在的计算机64K空间是足够用的。IO接口与外设本身的地址空间如下图2所示。

3.2 MMIO技术

MMIO(Memory mapping I/O)即内存映射I/O是一种相对较新的技术,它将外设的地址空间映射到物理内存中。其目的是方便操作系统更方便的访问这些外设中的物理空间。前面提到,在传统的控制方法中,操作系统要根据IO接口中的寄存器及其时序来访问外部设备,而访问物理内存则可以直接读写,那么有没有办法让访问外设空间和访问物理内存同样简单呢?MMIO技术就是做这个用的,以PCIE设备为例,由于访问频繁,所以操作系统干脆将其作为物理内存的一部分来执行读写操作。

这里有两个映射关系要注意区分,一是统一编址方式中映射,二是MMIO映射。二者相同的地方是都是将外部设备中的空间映射到物理内存上,都会减小物理内存的可用物理地址空间。但还是有很多不同的,首先是映射的源不同,统一编址中的映射源是IO接口中的寄存器,这些寄存器是控制整个外设的一个接口,而MMIO映射的是外设实现功能的地址空间,以硬盘为例,统一编址是将几个读写控制寄存器映射到物理空间中,而MMIO是将几百G的硬盘空间映射到物理地址空间。(当然硬盘是不能映射的,这里只是举例说明)。其次是映射的目的地址大小不同,由于源大小不同,映射后所需的物理地址空间肯定也就不同,统一编址中所有外设也就用了几K的空间,而一个PCIe设备通过MMIO映射到物理地址空间上则可能占据几百M。最后也是最重要的是映射的目的不同,统一编址是必须要做的一个步骤(在特定CPU下),否则CPU就无法访问到这个外部设备,而MMIO是为了操作系统更方便、统一的读写外设地址空间而做的。

MMIO技术的一个负面影响是占据了物理地址空间,几百M的设备就会占据同等大小的物理地址空间,这给不富裕的物理地址空间带来了更多压力,这也就是为什么你的电脑装了4G硬盘,而系统只能识别3个多G的主要原因。

4. 虚拟地址空间的映射

虚拟地址空间是一个比较复杂的概念,涉及到硬件中的MMU、操作系统的寻址方法及虚拟内存等概念。简单来说,现代操作系统通过映射将固定的物理内存分配给每个进程使用,而每个进程看到自己可用空间都是4G,而前面我们说到,整个物理内存还不到4G。

将外设地址空间映射到CPU物理地址空间方便了操作系统的访问,那能不能让用户直接访问这些存储空间呢?操作系统为了方便用户操作这些空间,提供了一种ioremap功能,从名字就可以看出,是将外设地址空间重新映射,这里说的第一次映射就是MMIO的映射,而重新映射指的就是从物理地址空间映射到用户可见的虚拟地址空间。两次映射示意图如下图3所示。


将外设空间映射到虚拟地址空间后,用户就可以直接访问了,如在C语言中,*(dev_addr)就可以直接访问到外设中的空间了。另外图中故意将映射到虚拟空间中的地址画的不同,这么做是因为每个进程的虚拟空间都是独立的,一个不知道另一个的存在,所以地址很有可能是不一样的。顺便再多提一句,这么做还是的两个进程公用了同一片物理地址空间,达到了共享内存的目的,可以实现进程间的通讯了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值