Linux

如何在 Linux 中禁止訪問物理記憶體?

  • June 25, 2015

我在嵌入式系統上(來自 Xilinx 的 Zynq。它使用 ARMv7、Cortex-A9)並執行 Linux。我需要確保永遠不會訪問某個物理記憶體範圍,無論是核心空間還是使用者意外。我可以發出信號、數據中止或其他任何事情,但硬體嘗試不得超過 MMU。

在裸機模式和 U-Boot 中,我可以直接訪問 TLB 的位置,並且可以通過將 MMU 配置為在發生任何讀取或寫入訪問時數據中止來限制硬體級別的記憶體訪問。我想在 Linux 中執行此操作,即使是 mmap() 也會引發數據中止。

推理:

在 Zynq 中,2GB 的地址空間被分配給在硬體級別上可能永遠不會響應的範圍。ARM 的 AXI/AMBA 協議規定主機永遠不能“放棄”訪問地址的嘗試,即使那裡什麼也沒有。如果我取消引用沒有硬體駐留的指針,整個晶片就會掛起。

我知道我可以“只是不給 sudo”或“只寫好的驅動程序”,但這甚至在那個水平之前。如果我的超級使用者進行了一些錯誤的編碼,我想在早期啟動時將 MMU 的 TLB 設置為完全數據中止。我寧願不破解 boot.S,而是直接修改 TLB,然後使用 API 刷新它。

Linux 核心可以選擇限制它將用作 RAM 的物理地址範圍,但這不會阻止錯誤的驅動程序或通過訪問/dev/mem來逃避這些範圍。在引導階段修改 MMU 配置不會有任何好處,因為無論如何核心都會在此之後控制 MMU。如果您想絕對確定 Linux 系統不會訪問某些記憶體範圍,則需要一些外部控制。

您的架構提供了一種方法來限制 Linux 核心可以訪問的內容:TrustZone(或更準確地說是 TrustZone 加上記憶體防火牆)¹。我懷疑你會為你正在做的事情找到一個交鑰匙解決方案,你需要做一些編碼。幸運的是,有關於 Zync上的 TrustZone 的文件可用。這是基本思想:

  • 處理器以 S 模式啟動。設置 TrustZone 控制寄存器以禁用該壞 2GB 範圍內的非安全訪問。
  • 完成此操作後,切換到 NS 模式並分支到正常的引導載入程序。
  • 如果 Linux 試圖訪問被阻塞的 2GB 範圍,請求將在到達記憶體匯流排之前被阻塞,並且會觸發中止(如果涉及任何記憶體或預取,則中止不精確)。

¹最近的 ARM 處理器提供了另一種方式,即執行管理程序,但這在 Cortex-A9 上不可用。

引用自:https://unix.stackexchange.com/questions/211725