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
不同區域詳細信息如下所示:
kuseg: 用戶態可用的地址,只有在MMU轉換后才可用
kseg0: 將地址最高位清零,即可映射到物理地址段512M(0x00000000~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
即所有的外設最大物理尋址空間為512MB
一個典型的 MIPS SOC的物理地址布局分布如下:
0x0000 0000 ~ 0x0FFF FFFF : SDRAM區域, 最大為256MB, 映射至kseg0區域
0x1000 0000 ~ 0x10FF FFFF : 寄存器地址, 映射至kseg1區域
0x1FC0 0000 ~ ? : 啟動FLASH, 大小為止映射至kseg1區域
從前面可以了解到,外設尋址空間范圍最大為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>