日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【嵌入式开发】 ARM 关闭 MMU ( 存储体系 | I/D-Cache | MMU | CP15 寄存器 | C1 控制寄存器 | C7 寄存器 | 关闭 MMU )

發布時間:2025/6/17 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【嵌入式开发】 ARM 关闭 MMU ( 存储体系 | I/D-Cache | MMU | CP15 寄存器 | C1 控制寄存器 | C7 寄存器 | 关闭 MMU ) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  • 一. MMU 概念
    • 1. ARM 存儲
      • (1) ARM 的存儲體系
      • (2) Cache 由來
      • (3) Cache 定義
    • 2. MMU
      • (1) 虛擬地址 與 物理地址
      • (2) MMU 作用 及 關閉原因
  • 二. 關閉 MMU 和 Cache
    • 1. 關閉 MMU 和 Cache 的方法簡介
      • (1) 關閉方法
      • (2) C1 控制寄存器 ( 打開關閉 Cache )
      • (3) C7 Cache 操作寄存器 ( 使 Cache 失效 )
    • 2. 關閉 MMU 和 Cache 代碼編寫
  • 三. 關閉 MMU 和 Cache 完整可編譯執行代碼
    • 1. 匯編代碼
    • 2. 鏈接器腳本
    • 3. Makefile 編譯腳本
    • 4. 編譯輸出可執行文件


本博客的參考文章及相關資料下載 :

  • 1.本博客代碼及參考手冊下載 : https://download.csdn.net/download/han1202012/10455643




一. MMU 概念




1. ARM 存儲


(1) ARM 的存儲體系


ARM 存儲 體系 簡介 : ARM 處理器分為三個等級, 處理器寄存器 -> TCM 存儲器 -> 輔助存儲器, 由上到下, 處理速度依次變慢, 但是存儲空間依次增加 ;

  • 1.處理器內部寄存器 : 處理器內部的 通用寄存器 和 狀態字寄存器 等, 這些寄存器 訪問速度很快, 但是數量很少 ;
  • 2.TCM 緊耦合存儲器 : Cache, 內存 等存儲器;
  • 3.輔助存儲器 : 開發板上的 NandFlash 達到 1G 大小的數量級別, SD 卡 等存儲 設備; 該類型存儲器 訪問速度最慢, 但是數量最大;



(2) Cache 由來


Cache 的由來 : Cache 用于解決 處理器 與 存儲器 之間 數據傳輸效率低下的問題;

  • 1.沒有 Cache 的 情況 : 處理器直接訪問主存儲器, 兩者之間的 處理速度差別巨大, 處理器的訪問效率會被大大的拉低 ;
  • 2.有 Cache 的 情況 : Cache 位于 處理器 與 主存儲器 之間, Cache 中存放主存儲器的一些拷貝, 當處理器需要讀取指定內容時, 先到 Cache 中去查看, 如果沒有, 就 直接從主存儲器中讀取, 同時將數據也讀取到 Cache 中, 當處理器下一次在讀取該數據的時候, 就可以直接從 Cache 中獲取該數據;


(3) Cache 定義


Cache 定義 :

  • 1.定義 : Cache 是 小容量 高速度 的 存儲器, 其速度 低于 處理器 高于 主存儲器;
  • 2.對外透明 : Cache 的功能對外是透明的, 在 Cache 中, 保存哪些數據, 覆蓋哪些數據都是操作系統決定的;
  • 3.Cache 功能劃分 : 分為兩類, ① I-Cache 指令 Cache, 用于存放指令; ② D-Cache 數據 Cache, 用于存放數據 ;
  • 4.圖示 : 下圖是 S3C6410X.pdf 芯片手冊 1.2 章節 中的 I-Cache 和 D-Cache 的描述, 下圖紅框部分, I/D-Cache 都是 16KB 大小;





2. MMU


(1) 虛擬地址 與 物理地址


虛擬機地址 與 物理地址 :

  • 1.虛擬地址概念 : 程序中使用的地址 是 虛擬地址 ;
  • 2.物理地址概念 : 存儲器物理存儲單元的實際物理地址 ;
  • 3.虛擬地址的優勢 : ① 應用程序可以使用更大的存儲空間, ② 解決不同程序之間的地址沖突問題; 如果沒有虛擬地址, 程序中直接使用物理地址, 那么程序必須使用指定的物理地址, 會產生沖突; 同時程序中使用的存儲空間也被限制 了; 因此程序中直接使用實際的物理地址 是不可行的 ;
  • 4.MMU 作用 : MMU 可以 實現 物理地址 到 虛擬地址 之間的轉換 ;


(2) MMU 作用 及 關閉原因


MMU 作用 : 實現 物理地址 到 虛擬地址 的轉換 ;

  • 1.MMU 與 Cache 的 位置 : ① ARM 11 之前, 處理器 -> Cache -> MMU -> 存儲器, ② ARM 11 及 ARM 11 之后, 處理器 -> MMU -> Cache -> 存儲器, 訪問 Cache 必須通過 MMU 將虛擬地址映射成物理地址后訪問;
  • 2.關閉 MMU 原因 : 使用 MMU 和 Cache 必須經過一系列的配置, 之后才能正確的使用, 在 ARM 初始化 時, 還沒有配置 MMU 和 Cache, 如果不關閉會出現錯誤;






二. 關閉 MMU 和 Cache


參考手冊 : ARM核 手冊 Arm1176jzfs.pdf ( 基于 6410 開發板 ARM 11 )

  • 1.手冊對應章節 : 3.2.7 章節 c1, Control Register;
  • 2.Arm1176jzfs.pdf手冊下載地址 :https://download.csdn.net/download/han1202012/10412045


1. 關閉 MMU 和 Cache 的方法簡介


(1) 關閉方法


關閉 MMU 和 Cache 簡介 :

  • 1.關閉 Cache 和 MMU 步驟 : ① 設置 ICache 和 DCache 失效; ② 關閉 ICache 和 DCache 以及 MMU ;
  • 2.操作方法 : MMU 和 Cache 關閉操作都是通過 CP15 協處理器 控制的, ① C1 控制寄存器 控制 Cache 和 MMU 開啟 / 關閉 , ② C7 寄存器 控制 Cache 的的 失效 操作 ;


(2) C1 控制寄存器 ( 打開關閉 Cache )


C1 控制寄存器簡介 :

  • 1.文檔位置 : Arm1176jzfs.pdf 第 3.2.7 章節 c1, Control Register ;
  • 2.I-Cache ( Instruction Cache ) 控制位 : 第 12 位 控制 I-Cache 的開啟 / 關閉, 設置成 0 即 I-Cache 失效, 設置成 1 即 I-Cache 生效;
  • 3.D-Cache ( Data Cache ) 控制位 : 第 2 位 控制 D-Cache 的開啟 / 關閉, 設置成 0 即 I-Cache 失效, 設置成 1 即 I-Cache 生效;
  • 4.MMU 控制位 : 第 0 位 控制 MMU 生效 / 失效, 設置成 0 即 MMU 失效, 設置成 1 即 MMU 生效;


(3) C7 Cache 操作寄存器 ( 使 Cache 失效 )


C7 寄存器 簡介 :

  • 1.文檔位置 : Arm1176jzfs.pdf 第 3.2.22 章節 c7, Cache operations ;
  • 2.使 Cache 失效 的指令 : MCR p15, 0, <Rd>, c7, c7, 0, 這是 文檔 中表格 3-71 Cache 操作 中給出的;


2. 關閉 MMU 和 Cache 代碼編寫



關閉 MMU 和 Cache 代碼編寫 :

  • 1.設置標號 : 為本段代碼設置一個標號, 讓程序可以跳轉到該處執行以下代碼, disable_mmu : ;
  • 2.設置 I-Cache 和 D-Cache 失效 : 使 兩個 Cache 都失效, 文檔中 Arm1176jzfs.pdf 第 3.2.22 章節 給出的代碼格式為 MCR p15, 0, <Rd>, c7, c7, 0, 其中 Rd 通用寄存器 設置為 R0, 最終代碼為 MCR p15, 0, R0, c7, c7, 0 ;
  • 3.關閉 I-Cache 和 D-Cache 及 MMU :
    • ① 修改方式 : C1 控制寄存器中的 [0] 位 控制 MMU 開啟/關閉, [2] 位控制 D-Cache 開啟/關閉, [12] 位控制 I-Cache 開啟/關閉; 上述位 設置為 0 關閉, 設置為 1 開啟;
    • ② C1 寄存器讀寫方式 : CP15 寄存器不能直接讀取, 需要使用 MRC 來將協處理器中的內容讀取到通用寄存器中, 語法格式為 MRC{cond} P15,<Opcode_1>,<Rd>,<CRn>,<CRm>,<Opcode_2> , 使用 MCR 將 Rd 寄存器中的值傳送到 CP15 協處理器中, 語法格式為 MCR{cond} P15,<Opcode_1>,<Rd>,<CRn>,<CRm>,<Opcode_2> ;
    • ③ 位計算 : 關閉 I/D-Cache 和 MMU 需要將 C1 寄存器的 [0](MMU), [2](D-Cache), [12] (I-Cache) 三位 設置為0; 其中 I-Cache 可以關閉, 也可以開啟, 不是必須的; 但是 D-Cache 和 MMU 必須關閉, Bootloader 主要作用是將 Linux 內核下載到內存中, 如果下載的過程中 D-Cache 沒有配置, 可能就將數據下載到了 Cache 中, 這樣就會出現問題, 影響內核運行; 因此這里我們只需要將 第 [0] 位 和 第 [1] 位 設置成 0, 將 MMU 和 D-Cache 關閉, I-Cache 不作設置;
    • ④ 讀取 C1 寄存器的值 : 使用 MRC p15, 0, R0, c1, c0, 0 將 c1 寄存器中的值 讀取到 R0 通用寄存器中;
    • ⑤ 將指定位設置為 0 : 使用 bic 位清除指令, 將 R0 寄存器中的 第 0, 1, 2 三位 設置成0, 這里 第 1 位選擇性設置, 為了方便計算 順便將 第 1 位 也設置成 0, 代碼為 bic r0, r0, #0x7 ;
    • ⑥ 將 R0 寄存器中的值寫回到 C1 寄存器中 : 使用 MRC p15, 0, r0, c1, c0, 0 指令, 將 R0 寄存器中的值 寫回到 C1 寄存器中;
  • 4.設置程序跳轉到返回點繼續執行 : 使用 BL 指令跳轉到 disable_mmu 標號處執行, 同時將返回地址存儲到了 LR 寄存器中, 返回時跳轉到 LR 寄存器中的地址執行即可, 使用 mov pc, lr 指令, 執行 lr 中地址指向的位置的代碼;
  • 5.代碼示例 :
disable_mmu : mcr p15,0,r0,c7,c7,0 @ 設置 I-Cache 和 D-Cache 失效mrc p15,0,r0,c1,c0,0 @ 將 c1 寄存器中的值 讀取到 R0 通用寄存器中bic r0, r0, #0x00000007 @ 使用 bic 位清除指令, 將 R0 寄存器中的 第 0, 1, 2 三位 設置成0, 代表 關閉 MMU 和 D-Cachemcr p15,0,r0,c1,c0,0 @ 將 R0 寄存器中的值寫回到 C1 寄存器中mov pc, lr @ 返回到 返回點處 繼續執行后面的代碼






三. 關閉 MMU 和 Cache 完整可編譯執行代碼




1. 匯編代碼



匯編代碼示例 : Bootloader 流程 : ① 初始化異常向量表 , ② 設置 svc 模式 , ③ 關閉看門狗, ④ 關閉中斷, ⑤ 關閉 MMU ;

@**************************** @File:start.S @ @BootLoader 初始化代碼 @**************************** .text @ 宏 指明代碼段 .global _start @ 偽指令聲明全局開始符號 _start: @ 程序入口標志 b reset @ reset 復位異常 ldr pc, _undefined_instruction @ 未定義異常, 將 _undefined_instruction 值裝載到 pc 指針中 ldr pc, _software_interrupt @ 軟中斷異常 ldr pc, _prefetch_abort @ 預取指令異常 ldr pc, _data_abort @ 數據讀取異常 ldr pc, _not_used @ 占用 0x00000014 地址 ldr pc, _irq @ 普通中斷異常 ldr pc, _fiq @ 軟中斷異常 _undefined_instruction: .word undefined_instruction @ _undefined_instruction 標號存放了一個值, 該值是 32 位地址 undefined_instruction, undefined_instruction 是一個地址 _software_interrupt: .word software_interrupt @ 軟中斷異常 _prefetch_abort: .word prefetch_abort @ 預取指令異常 處理 _data_abort: .word data_abort @ 數據讀取異常 _not_used: .word not_used @ 空位處理 _irq: .word irq @ 普通中斷處理 _fiq: .word fiq @ 快速中斷處理 undefined_instruction: @ undefined_instruction 地址存放要執行的內容 nop software_interrupt: @ software_interrupt 地址存放要執行的內容 nop prefetch_abort: @ prefetch_abort 地址存放要執行的內容 nop data_abort: @ data_abort 地址存放要執行的內容 nop not_used: @ not_used 地址存放要執行的內容 nop irq: @ irq 地址存放要執行的內容 nop fiq: @ fiq 地址存放要執行的內容 nop reset: @ reset 地址存放要執行的內容 bl set_svc @ 跳轉到 set_svc 標號處執行bl disable_watchdog @ 跳轉到 disable_watchdog 標號執行, 關閉看門狗bl disable_interrupt @ 跳轉到 disable_interrupt 標號執行, 關閉中斷bl disable_mmu @ 跳轉到 disable_mmu 標號執行, 關閉 MMU set_svc:mrs r0, cpsr @ 將 CPSR 寄存器中的值 導出到 R0 寄存器中bic r0, r0, #0x1f @ 將 R0 寄存器中的值 與 #0x1f 立即數 進行與操作, 并將結果保存到 R0 寄存器中, 實際是將寄存器的 0 ~ 4 位 置 0orr r0, r0, #0xd3 @ 將 R0 寄存器中的值 與 #0xd3 立即數 進行或操作, 并將結果保存到 R0 寄存器中, 實際是設置 0 ~ 4 位 寄存器值 的處理器工作模式代碼msr cpsr, r0 @ 將 R0 寄存器中的值 保存到 CPSR 寄存器中mov pc, lr @ 返回到 返回點處 繼續執行后面的代碼#define pWTCON 0x7e004000 @ 定義看門狗控制寄存器 地址 ( 6410開發板 ) disable_watchdog: ldr r0, =pWTCON @ 先將控制寄存器地址保存到通用寄存器中mov r1, #0x0 @ 準備一個 0 值, 看門狗控制寄存器都設置為0 , 即看門狗也關閉了str r1, [r0] @ 將 0 值 設置到 看門狗控制寄存器中 mov pc, lr @ 返回到 返回點處 繼續執行后面的代碼disable_interrupt:mvn r1,#0x0 @ 將 0x0 按位取反, 獲取 全 1 的數據, 設置到 R1 寄存器中ldr r0,=0x71200014 @ 設置第一個中斷屏蔽寄存器, 先將 寄存器 地址裝載到 通用寄存器 R0 中 str r1,[r0] @ 再將 全 1 的值設置到 寄存器中, 該寄存器的內存地址已經裝載到了 R0 通用寄存器中ldr r0,=0x71300014 @ 設置第二個中斷屏蔽寄存器, 先將 寄存器 地址裝載到 通用寄存器 R0 中 str r1,[r0] @ 再將 全 1 的值設置到 寄存器中, 該寄存器的內存地址已經裝載到了 R0 通用寄存器中mov pc, lr @ 返回到 返回點處 繼續執行后面的代碼disable_mmu : mcr p15,0,r0,c7,c7,0 @ 設置 I-Cache 和 D-Cache 失效mrc p15,0,r0,c1,c0,0 @ 將 c1 寄存器中的值 讀取到 R0 通用寄存器中bic r0, r0, #0x00000007 @ 使用 bic 位清除指令, 將 R0 寄存器中的 第 0, 1, 2 三位 設置成0, 代表 關閉 MMU 和 D-Cachemcr p15,0,r0,c1,c0,0 @ 將 R0 寄存器中的值寫回到 C1 寄存器中mov pc, lr @ 返回到 返回點處 繼續執行后面的代碼




2. 鏈接器腳本


gboot.lds 鏈接器腳本 代碼解析 :

  • 1.指明輸出格式 ( 處理器架構 ) : 使用 OUTPUT_ARCH(架構名稱) 指明輸出格式, 即處理器的架構, 這里是 arm 架構的, OUTPUT_ARCH(arm) ;
  • 2.指明輸出程序的入口 : 設置編譯輸出的程序入口位置, 語法為 ENTRY(入口位置), 在上面的 Start.S 中設置的程序入口是 _start, 代碼為 ENTRY(_start) ;
  • 3.設置代碼段 : 使用 .text : 設置代碼段;
  • 4.設置數據段 : 使用 .data : 設置數據段;
  • 5.設置 BSS 段 : 使用 .bss : 設置 BSS 段;
    • ( 1 ) 記錄 BSS 段的起始地址 : bss_start = .; ;
    • ( 2 ) 記錄 BSS 段的結束地址 : bss_end = .; ;
  • 6.對齊 : 每個段都需要設置內存的對齊格式, 使用 . = ALIGN(4); 設置四字節對齊即可;
  • 7.代碼示例 :
OUTPUT_ARCH(arm) /*指明處理器結構*/ ENTRY(_start) /*指明程序入口 在 _start 標號處*/ SECTIONS { . = 0x50008000; /*整個程序鏈接的起始位置, 根據開發板確定, 不同開發板地址不一致*/ . = ALIGN(4); /*對齊處理, 每段開始之前進行 4 字節對齊*/ .text : /*代碼段*/ { start.o (.text) /*start.S 轉化來的代碼段*/ *(.text) /*其它代碼段*/ } . = ALIGN(4); /*對齊處理, 每段開始之前進行 4 字節對齊*/ .data : /*數據段*/ { *(.data) } . = ALIGN(4); /*對齊處理, 每段開始之前進行 4 字節對齊*/ bss_start = .; /*記錄 bss 段起始位置*/ .bss : /*bss 段*/ { *(.bss) } bss_end = .; /*記錄 bss 段結束位置*/ }




3. Makefile 編譯腳本


makefile 文件編寫 :

  • 1.通用規則 ( 匯編文件編譯規則 ) : 匯編文件 編譯 成同名的 .o 文件, 文件名稱相同, 后綴不同, %.o : %.S, 產生過程是 arm-linux-gcc -g -c $^ , 其中 ^ 標識是所有的依賴文件, 在該規則下 start.S 會被變異成 start.o ;
  • 2.通用規則 ( C 文件編譯規則 ) : C 代碼編譯成同名的 .o 文件, %.o : %.c , 產生過程是 arm-linux-gcc -g -c $^ ;
  • 3.設置最終目標 : 使用 all: 設置最終編譯目標;
    • ( 1 ) 依賴文件 : 產生最終目標需要依賴 start.o 文件, 使用 all: start.o 表示最終目標需要依賴該文件;
    • ( 2 ) 鏈接過程 : arm-linux-ld -Tgboot.lds -o gboot.elf $^, 需要使用鏈接器腳本進行連接, ①鏈接工具是 arm-linux-ld 工具, ②使用 -Tgboot.lds 設置鏈接器腳本 是剛寫的 gboot.lds 鏈接器腳本, ③輸出文件是 gboot.elf 這是個中間文件, ④ 依賴文件是 $^ 代表所有的依賴;
    • ( 3 ) 轉換成可執行二進制文件 : arm-linux-objcopy -O binary gboot.elf gboot.bin, 使用 -O binary 設置輸出二進制文件, 依賴文件是 gboot.elf, 輸出的可執行二進制文件 即 結果是 gboot.bin ;
  • 4.makefile 文件內容 :
all: start.o #依賴于 start.o arm-linux-ld -Tgboot.lds -o gboot.elf $^ #使用鏈接器腳本, 將 start.o 轉為 gboot.elf arm-linux-objcopy -O binary gboot.elf gboot.bin #將 gboot.elf 轉化為可以直接在板子上執行的 gboot.bin 文件 %.o : %.S #通用規則, 如 start.o 是由 start.S 編譯來的, -c 是只編譯不鏈接 arm-linux-gcc -g -c $^ %.o : %.c #通用規則, 如 start.o 是由 start.c 編譯來的, -c 是只編譯不鏈接 arm-linux-gcc -g -c $^ .PHONY: clean clean: #清除編譯信息 rm *.o *.elf *.bin




4. 編譯輸出可執行文件


編譯過程 :

  • 1.文件準備 : 將 匯編代碼 ( start.S ) 鏈接器腳本 ( gboot.lds ) makefile 文件 拷貝到編譯目錄 ;
  • 2.執行編譯命令 : make ;
  • 3.編譯結果 : 可以看到 生成了 編譯目標文件 start.o, 鏈接文件 gboot.elf, 可執行的二進制文件 gboot.bin ;

本博客的參考文章及相關資料下載 :

  • 1.本博客代碼及參考手冊下載 : https://download.csdn.net/download/han1202012/10455643

總結

以上是生活随笔為你收集整理的【嵌入式开发】 ARM 关闭 MMU ( 存储体系 | I/D-Cache | MMU | CP15 寄存器 | C1 控制寄存器 | C7 寄存器 | 关闭 MMU )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。