1. 介绍
MIPS处理器是一种RISC处理器,被广泛使用在许多电子产品、网络设备、个人娱乐装置与商业装置上
2. 地址空间
MIPS处理器对地址空间的使用和处理和传统CISC CPU有着微妙的不同;在MIPS CPU里,程序中的地址和实际的物理地址不同,分别称之为程序地址和物理地址
MIPS CPU有用户模式和核心模式两种特权级
从核心态到用户态的变化并不改变操作的行为,只是有时某些操作被认为是非法的
在用户态,地址最高位为1的任何程序地址都是非法的并会导致自陷;还有,有些指令在用户态将会导致异常
对于32位MIPS处理器,程序地址空间4G)划分为四大区域,不同区域有不同的属性,如下图所示
kuseg : 0x00000000 ------ 0x7fffffff 2G) user space
kseg0 : 0x80000000 ------ 0x9fffffff 512M) unmapped, cached
kseg1 : 0xa0000000 ------ 0xbfffffff 512M) unmapped, uncached
kseg2 : 0xc0000000 ------ 0xffffffff 1G) mapped, cached
.csharpcode, .csharpcode pre { font-size: small; color: rgba0, 0, 0, 1); font-family: consolas, “Courier New”, courier, monospace; background-color: rgba255, 255, 255, 1) }
.csharpcode pre { margin: 0 }
.csharpcode .rem { color: rgba0, 128, 0, 1) }
.csharpcode .kwrd { color: rgba0, 0, 255, 1) }
.csharpcode .str { color: rgba0, 96, 128, 1) }
.csharpcode .op { color: rgba0, 0, 192, 1) }
.csharpcode .preproc { color: rgba204, 102, 51, 1) }
.csharpcode .asp { background-color: rgba255, 255, 0, 1) }
.csharpcode .html { color: rgba128, 0, 0, 1) }
.csharpcode .attr { color: rgba255, 0, 0, 1) }
.csharpcode .alt { background-color: rgba244, 244, 244, 1); 100%; margin: 0 }
.csharpcode .lnum { color: rgba96, 96, 96, 1) }
.csharpcode, .csharpcode pre { font-size: small; color: rgba0, 0, 0, 1); font-family: consolas, “Courier New”, courier, monospace; background-color: rgba255, 255, 255, 1) }
.csharpcode pre { margin: 0 }
.csharpcode .rem { color: rgba0, 128, 0, 1) }
.csharpcode .kwrd { color: rgba0, 0, 255, 1) }
.csharpcode .str { color: rgba0, 96, 128, 1) }
.csharpcode .op { color: rgba0, 0, 192, 1) }
.csharpcode .preproc { color: rgba204, 102, 51, 1) }
.csharpcode .asp { background-color: rgba255, 255, 0, 1) }
.csharpcode .html { color: rgba128, 0, 0, 1) }
.csharpcode .attr { color: rgba255, 0, 0, 1) }
.csharpcode .alt { background-color: rgba244, 244, 244, 1); 100%; margin: 0 }
.csharpcode .lnum { color: rgba96, 96, 96, 1) }
不同区域详细信息如下所示:
kuseg: 用户态可用的地址,只有在MMU转换后才可用
kseg0: 将地址最高位清零,即可映射到物理地址段512M0x00000000~0x1FFFFFFF),这种映射关系很简单,通常称之为”非转换的”地址区域,对这段地址的存取必须通过cache。通常一个没有MMU的系统会使用这段地址作为其绝大多数程序和数据的存放位置;对于有MMU的系统,操作系统核心会存放在这个区域.
kseg1: 将地址的高三位清零可映射到相应的物理地址上,与kseg0映射的物理地址一样,但kseg1是非cache存取的。kseg1是唯一在系统重启时能正常工作的地址空间。这也是为什么启动入口向量是0xBFC00000,这个向量对应的物理地址是0x1FC00000,因此要使用这个地址区域去存取初始的程序ROM
kseg2: 这块区域只能在核心态下使用并且要经过MMU的转换。在MMU设置好之前,不能存取该区域。有时该区域被分为kseg2和kseg3,意在强调低半部分kseg2)可供运行在管理态的程序使用
3. 地址映射
以BCM63268为例介绍MIPS处理器地址映射
其中,物理地址分配图和虚拟地址映射图
CPU拿到地址虚拟地址),其转换过程如下步骤:
1) 判断当前是kernel mode还是user mode
2) 如果是kernel mode
A) 访问的地址是kuseg或者kseg2,进行 TLB 查找;如果查找不成功,exception。如果查找成功,得到物理地址
B) 如果访问的地址是 kseg0/kseg1,不进行TLB 查找;通过减去一个偏移量得到物理地址
3) 如果是user mode
A) 访问地址kuseg,进行TLB 查找。如果查找不成功,exception。如果查找成功,得到物理地址
B) 访问kseg0/1/2,exception
4. 引导过程
我们知道,kseg0和kesg1大小均为512MB,且均映射至物理地址[0x0000 0000 ~ 0x2000 0000]范围内,只是映射的方式不同,但是他们的地址不能重叠
kseg0: 虚拟地址 = 物理地址 + 0x8000 0000
kseg1: 虚拟地址 = 物理地址 + 0xA000 0000
.csharpcode, .csharpcode pre { font-size: small; color: rgba0, 0, 0, 1); font-family: consolas, “Courier New”, courier, monospace; background-color: rgba255, 255, 255, 1) }
.csharpcode pre { margin: 0 }
.csharpcode .rem { color: rgba0, 128, 0, 1) }
.csharpcode .kwrd { color: rgba0, 0, 255, 1) }
.csharpcode .str { color: rgba0, 96, 128, 1) }
.csharpcode .op { color: rgba0, 0, 192, 1) }
.csharpcode .preproc { color: rgba204, 102, 51, 1) }
.csharpcode .asp { background-color: rgba255, 255, 0, 1) }
.csharpcode .html { color: rgba128, 0, 0, 1) }
.csharpcode .attr { color: rgba255, 0, 0, 1) }
.csharpcode .alt { background-color: rgba244, 244, 244, 1); 100%; margin: 0 }
.csharpcode .lnum { color: rgba96, 96, 96, 1) }
即所有的外设最大物理寻址空间为512MB
一个典型的 MIPS SOC的物理地址布局分布如下:
0x0000 0000 ~ 0x0FFF FFFF : SDRAM区域, 最大为256MB, 映射至kseg0区域
0x1000 0000 ~ 0x10FF FFFF : 寄存器地址, 映射至kseg1区域
0x1FC0 0000 ~ ? : 启动FLASH, 大小为止映射至kseg1区域
.csharpcode, .csharpcode pre { font-size: small; color: rgba0, 0, 0, 1); font-family: consolas, “Courier New”, courier, monospace; background-color: rgba255, 255, 255, 1) }
.csharpcode pre { margin: 0 }
.csharpcode .rem { color: rgba0, 128, 0, 1) }
.csharpcode .kwrd { color: rgba0, 0, 255, 1) }
.csharpcode .str { color: rgba0, 96, 128, 1) }
.csharpcode .op { color: rgba0, 0, 192, 1) }
.csharpcode .preproc { color: rgba204, 102, 51, 1) }
.csharpcode .asp { background-color: rgba255, 255, 0, 1) }
.csharpcode .html { color: rgba128, 0, 0, 1) }
.csharpcode .attr { color: rgba255, 0, 0, 1) }
.csharpcode .alt { background-color: rgba244, 244, 244, 1); 100%; margin: 0 }
.csharpcode .lnum { color: rgba96, 96, 96, 1) }
从前面可以了解到,外设寻址空间范围最大为0x2000 0000
而从物理内存布局可以看到第一块FLASH的起始地址为0x1FC0 0000,
其距离0x2000 0000只有4MB大小,而FLASH大小一般为8MB或16MB
此处我的理解4MB大小主要是用于BootLoader,完成将内核映像从FLASH搬运至SDRAM
因为启动的时候MMU和Cache均未初始化,只有kseg1这段地址空间可以正常读取并处理,
故在这4MB地址区域上完成搬运及硬件初始化工作,然后跳转到kseg0去执行。
TIP: 对于MIPS24K,其起始地址改到了0xbf000000,距离0x1FFF FFFF有16MB的空间
从上可知,当SDRAM和FLASH较大时,将可能出现无法寻址的情况
对于第二块对FLASH,可挂载至0x10FF FFFF ~ 0x1FC0 0000的地址空间内
5. MIPS寄存器
MIPS体系架构有32个通用寄存器,以及协处理器
5.1 通用寄存器
MIPS通用寄存器在汇编程序中可以用$0 ~ $31来表示,或者用寄存器的名字$sp, $t1, $ra…
堆栈Stack)的增长方向是:从内存高地址向地址
Register Name Usage $0 zero 常量0 $1 $at 保留给汇编器Reserved for assembler) $2-$3 $v0-$v1 函数调用返回值values for results and expression evaluation) $4-$7 $a0-$a3 函数调用参数arguments) $8-$15 $t0-$t7 临时寄存器 $16-$23 $s0-$s7 保存寄存器需要SAVE/RESTORE) $24-$25 $t8-$t9 同$t0-$t7 $26-$27 $k0-$k1 仅供中断interrupt/trap)处理函数使用 $28 $gp 全局指针Global Point) $29 $sp 堆栈指针,指向堆栈的栈顶Stack Point) $30 $fp 帧指针Frame Point) $31 $ra 返回地址return address)
TIP: $30 is stale acutally, and can be simply used as $t8
关于通用寄存器更多内容,参考<MIPS寄存器介绍>
5.2 协处理器
在MIPS体系结构中,最多支持4个协处理器Co-Processor);其中,协处理器CP0起到控制CPU的作用
MMU、异常处理、乘除法等功能,都依赖于协处理器CP0来实现
更多内容参考<Coprocessor 0 – MIPS>
参考:
<MIPS Quick Tutorial>
<A Quick Introduction to SPIM>
<MIPS Assembly Language Programming>
<MIPS Assembly Language Programmer’s Guide>