【转】基于mips架构的uboot 启动流程 (2)连载五:

5)         钻石时代:专题篇

下面是一些个人学习的专题。记录备忘。

 

/***************************************************************************************/

u MIPS CPU 地址空间简介 ( 整理自《 See MIPS Run 》和 CPU 文档 ) :       

注:首先需要明确的是 CPU 物理地址空间 不仅仅包括 RAM 物理内存的空间,还包括 CPU 内部的一些总线、寄存器的编址。

 

一个 MIPS CPU 可以运行在两种优先级别上,用户态和核心态。 MIPS CPU 从核心态到用户态的变化并不是 CPU 工作不一样,而是对于有些操作认为是非法的。在用户态,任何一个程序地址的首位是 1 的话,这个地址是非法的,对其存取将会导致异常处理。另外,在用户态下,一些特殊的指令将会导致 CPU 进入异常状态。

 

在 32 位 CPU 下,程序地址空间 划分为 4 个大区域。每个区域有一个传统的名字。对于在这些区域的地址,各自有不同的属性:

 

kuseg: 虚拟空间 0x0000 0000 - 0x7FFF FFFF ( 低端 2G) :这些地址是用户态 可用的地址。在有 MMU 的机器里,这些地址将一概被 MMU 作转换 ,除非 MMU 的设置被建立好,否则这 2G 地址是不可用的。对于没有 MMU 的机器,存取这 2G 地址的方法依具体机器相关,你的 CPU 具体厂商提供的手册将会告诉你关于这方面的信息。如果想要你的代码在有或没有 MMU 的 MIPS 处理器之间有兼容性,尽量避免 这块区域的存取。

 

kseg0: 虚拟空间 0x8000 0000 - 0x9FFF FFFF(512M): 这些地址映射到物理地址简单的通过把最高位清零,然后把它们映射到物理地址低段 512M(0x0000 0000 - 0x1FFF FFFF) 。因为这种映射是很简单的,通常称之为“非转换的” 地址区域。几乎全部的对这段地址的存取都会通过快速缓存 (cache) 。因此在 cache 设置好之前,不能随便使用这段地址。通常一个没有 MMU 的系统会使用这段地址作为其绝大多数程序和数据的存放位置。对于有 MMU 的系统,操作系统核心会存放在这个区域。

 

kseg1: 虚拟空间 0xA000 0000 - 0xBFFF FFFF(512M): 这些地址通过把最高 3 位清零的方法来映射到相应的物理地址上,与 kseg0 映射的物理地址一样 。但 kseg1 是非 cache 存取的。 kseg1 是唯一的在系统重启时 能正常工作的地址空间。这也是为什么重新启动时的入口向量是 0xBFC0 0000 。这个向量相应的物理地址是 0x1FC0 0000 。你将使用这段地址空间去存取你的初始化 ROM 。大多数人在这段空间使用 I/O 寄存器。如果你的硬件工程师要把这段地址空间映射到非低段 512M 空间,你得劝说他。

 

kseg2: 虚拟空间 0xC000 0000 - 0xFFFF FFFF (1G): 这段地址空间只能在核心态 下使用并且要经过 MMU 的转换 。在 MMU 设置好之前,不能存取这段区域。除非你在写一个真正的操作系统,一般来说你不需要使用这段地址空间。

 

综上可以看到, MIPS32 CPU 下面的不经过 MMU 转换的内存窗口只有 kseg0 和 kseg1 的 512M 的大小,而且这两个内存窗口映射到同一 512M 的物理地址空间。其余的 3G 虚拟地址空间需要经过 MMU 转换成物理地址,这个转换规则是由 CPU 厂商实现的。还句话说,在 MIPS32 CPU 下面访问高于 512M 的物理地址空间,必须通过 MMU 地址转换。

 

在核心态下 (CPU 启动时 ) , CPU 可以作任何事情。在用户态下, 2G 之上的地址空间是非法的,任何存取将会导致系统异常处理。注意的是,如果一个 CPU 有 MMU ,这意味着所有的用户地址在真正访问到物理地址之前必须经过 MMU 的转换 , 从而使得 OS 可以防止用户程序随便乱用。对於一个没有内存映射的 OS , MIPS CPU 的用户态其实是多余的。在核心态下, CPU 可以存取低段地址空间,这个存取也是通过 MMU 的转换。

 

 

下面来谈谈 MIPS64 CPU 的虚拟地址空间。

64 位 CPU 的地址空间的最低 2G 和最高 2G 区域是和 32 位情况下一样的, 64 位扩展的地址部分在这两者之间。 64 位下那些大块的不需要 MMU 转换的窗口可以克服 kseg0 和 kseg1 512M 的局限,但是 32 位下我们可以通过对 MMU 编程来同样达到这一点。

 

/***************************************************************************************/

u MIPS CPU 内存管理与 TLB( 整理自《 See MIPS Run 》 ) :       

早期的 MIPS CPU 定位于支持运行在 UNIX 工作站与服务器上的应用程序,因此内存管理硬件被构想为一个最小化的能帮助 BSD UNIX ——一个经过完善设计并拥有充分多虚拟存储需求的操作系统的典型——提供内存管理功能的硬件。我们将从 MIPS 的设计起点开始,面对着一个 unix 类型的操作系统以及它的虚存系统的众多需求。我们将会展示一下 MIPS 的硬件是如何满足这些需求的。结尾时,我们会讨论一下在不能像通常一样使用内存管理硬件的嵌入式系统中,您可以采取的几种使用方式。

 

UNIX 内存管理工作的本质是为了能运行众多不同的任务(即 multitasking —— 多进程),并且每个任务各自拥有自己的内存空间。如果这个工作圆满完成,那么各任务的命运将彼此独立开来(操作系统自身也因此得以保护):一个任务自身崩溃或者错误的做某些事不会影响整个系统。显然,对一个使用分布终端来运行学生们程序的大学而言,这是一个很有用的特性;然而不仅如此,甚至是要求最严格的 商业系统环境也需要能够在运行的同时支持实验软件或原型软件一并进行调试和测试。

 

MMU 并不仅仅为了建立巨大而完备的虚拟存储系统,小的嵌入式程序也能在重定位和更有效的内存分配里受益。如果能把应用程序观念上的地址映射到任何可获得的物理地址,系统在不同时刻运行不同程序就会更加容易。

 

嵌入式应用中常常会明确的运用多进程机制,但几乎没有多少嵌入式操作系统使用隔离的地址空间。或许这归咎于这种机制在嵌入式 CPU 以及它们上面的操作系统上用处不大并且带来不稳定性,因而显得不那么重要。

--电子创新网--
粤ICP备12070055号