首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

U-Boot 詳解(六):關閉 Cache 與 MMU 的必要性與實現

     編輯:關於C++

背景

U-Boot 啟動過程中,設置完時鐘分頻後,調用 cpu_init_crit 彙編函數,核心任務:關閉 Cache 與 MMU,隨後調用 lowlevel_init 初始化總線。

為什麼啟動時必須關閉 Cache 與 MMU?

Cache(高速緩存)

  • CPU 速度 ≫ 內存速度,Cache 緩存常用指令/數據提升性能
  • 啟動早期:內存未初始化、頁表未建立,Cache 內容不可預測
  • 若數據 Cache 開啟,CPU 可能讀到舊的髒數據而非內存真實值 → 數據預取異常
  • 指令 Cache 可選關閉,但數據 Cache 必須關閉

MMU(內存管理單元)

  • 實現虛擬地址 → 物理地址映射、內存保護、權限控制
  • 啟動早期:頁表未建立,MMU 無法正確翻譯地址
  • 若開啟 MMU,程序將在虛擬地址空間運行,導致訪問錯誤
  • 故必須先關閉 MMU,程序在物理地址空間運行

CP15 協處理器寄存器關鍵位(ARM920T/S3C2440)

位名稱功能啟動時設置
0MMMU 啟用0 (關閉)
1A地址對齊檢查1 (開啟)
2C數據 Cache 啟用0 (關閉)
7B大/小端模式0 (小端)
12I指令 Cache 啟用1 (開啟,可選)
13V異常向量基址0 (0x00000000)
30,31nF, iA總線模式配置為 FastBus

關閉 Cache 與 MMU 彙編代碼解析

cpu_init_crit:
    /* 清除 V4 I/D Cache */
    mov r0, #0
    mcr p15, 0, r0, c7, c7, 0  @ 清除 I/D Cache
    mcr p15, 0, r0, c8, c7, 0  @ 清除 V3/V4 Cache
    mcr p15, 0, r0, c8, c7, 0  @ 清除 TLB
    
    /* 禁用 MMU、Cache,啟用對齊檢查、指令 Cache */
    mrc p15, 0, r0, c1, c0, 0  @ 讀取 CP15 c1 (控制寄存器)
    bic r0, r0, #0x00002300    @ 清除位 13(V), 9(R), 8(S)
    bic r0, r0, #0x00000087    @ 清除位 7(B), 2(C), 1(A), 0(M)
    orr r0, r0, #0x00000002    @ 設置位 1(A) = 1 (對齊檢查)
    orr r0, r0, #0x00001000    @ 設置位 12(I) = 1 (指令 Cache)
    mcr p15, 0, r0, c1, c0, 0  @ 寫回 CP15 c1
    
    /* 跳轉到 lowlevel_init */
    mov ip, lr
    bl lowlevel_init
    mov lr, ip
    mov pc, lr

關鍵指令說明

  • mcr (Move to Coprocessor from ARM Register):ARM → CP15
  • mrc (Move to ARM Register from Coprocessor):CP15 → ARM
  • bic (Bit Clear):清除指定位
  • orr (Bit OR):設置指定位
  • 讀-改-寫:mrc → bic/orr → mcr 保證不影響其他位

為什麼先清 Cache 再關閉?

關閉 Cache 前必須清空(Clean/Flush) Cache 內容,將髒數據寫回內存,否則關閉後數據丟失。
c7 操作執行 Cache 清理/無效化,c8 操作 TLB 無效化。

總結

U-Boot 早期初始化的核心原則:在硬件機制就緒前,禁用所有可能導致不可預測行為的優化單元。Cache 與 MMU 是典型代表,必須在內存控制器就緒、頁表建立後才能安全啟用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved