17-Translation (XLAT) Tables Library
引流關鍵詞: 中斷、同步異常、異步異常、irq、fiq、BL1,BL2,BL3,BL31,BL32,BL33,AP_BL1,AP_BL2,AP_BL3,AP_BL31,AP_BL32,AP_BL33,SCP_BL1,SCP_BL2,BL0,BL30, optee、ATF、TF-A、Trustzone、optee3.14、MMU、VMSA、cache、TLB、arm、armv8、armv9、TEE、安全、內存管理、頁表…
快速鏈接:
.
👉👉👉 個人博客筆記導讀目錄(全部) 👈👈👈
[專欄目錄]-ATF/FF-A/specification學習
17.翻譯(XLAT)表庫
本文檔描述了 Trusted Firmware-A (TF-A) 使用的轉換表庫(版本 2)的設計。該庫提供 API 以根據內存布局的描述創建頁表,以及設置與內存管理單元 (MMU) 相關的系統寄存器并執行所需的轉換后備緩沖區 (TLB) 維護操作。
更具體地說,該庫旨在支持的一些用例是:
-
(1) 根據內存布局的描述靜態分配轉換表并填充它們(在運行時)。內存布局通常由平臺端口作為內存區域列表提供;
-
(2) 支持生成與庫代碼執行的異常級別不同的翻譯制度相關的翻譯表;
-
(3) 支持動態映射和取消映射區域,即使在 MMU 開啟時也是如此。這可用于臨時映射一些內存區域,并在以后不再需要時取消映射它們;
-
(4) 支持非身份的虛擬到物理的映射來壓縮虛擬地址空間;
-
(5) 支持在運行時更改內存區域的內存屬性。
17.1. 關于版本 1、版本 2 和 MPU 庫
本文檔重點介紹該庫的第 2 版,其源代碼可在lib/xlat_tables_v2目錄中找到。仍然可以在lib/xlat_tables目錄中找到該庫的版本 1,但它的靈活性較低并且不支持動態映射。lib/xlat_mpu,它等效地配置了 Arm 的 MPU,也在這里解決。這lib/xlat_mpu是實驗性的,這意味著它的 API 可能會改變。它目前致力于與 xlat_tables_v2 保持一致性和代碼重用。未來的版本可能更特定于 MPU(例如,刪除所有提及的虛擬地址)。盡管潛在的錯誤修復將應用于所有版本的 xlat_* 庫,但未來的功能增強將集中在版本 2 上,可能不會向后移植到版本 1 和 MPU 版本。因此,建議使用版本 2,尤其是對于新平臺端口(除非平臺使用 MPU)。
但是,請注意,版本 2 和 MPU 版本仍在積極開發中,尚未被認為是穩定的。因此,可能會引入兼容性中斷。
從此時起,除非另有說明,否則本文檔將隱含引用該庫的第 2 版。
17.2. 設計概念和界面
本節介紹翻譯表庫中使用的一些關鍵概念和數據結構。
17.2.1. 映射區域
Anmmap_region是一種抽象、簡潔的方式來表示要映射的內存區域。它是圖書館的關鍵接口之一。它通過以下方式識別:
-
它的物理基地址;
-
它的虛擬基地址;
-
它的大小;
-
它的屬性;
-
其映射粒度(可選)。
請參閱 中的類型。struct mmap_regionxlat_tables_v2.h
用戶通常會提供要映射的此類 mmap 區域的列表,并讓庫將其轉置到一組翻譯表中。因此,圖書館可能會創建新的翻譯表,更新或拆分現有的翻譯表。
區域屬性指定內存的類型(例如設備或緩存的普通內存)以及內存訪問權限(只讀或讀寫、可執行與否、安全或非安全等)。在 EL1&0 轉換機制的情況下,屬性還指定區域是用戶區域 (EL0) 還是特權區域 (EL1)。請參閱 中的MT_xxx定義xlat_tables_v2.h。請注意,對于 EL1&0 轉換機制,EL1 和 EL0 同時設置 Execute Never 屬性。
粒度控制映射區域時要下降到的轉換表級別。例如,假設 MMU 已配置為使用 4KB 粒度,則庫可能使用以下兩個選項之一映射 2MB 內存區域:
-
使用單個 2 級轉換表條目;
-
使用 2 級中間條目到 3 級轉換表(包含 512 個條目,每個映射 4KB)。
第一個解決方案可能需要更少的轉換表,因此可能需要更少的內存。但是,如果這個 2MB 區域的一部分稍后被重新映射為不同的內存屬性,則庫可能需要拆分現有的頁表以優化映射。如果這里使用了一個 2 級條目,則需要動態分配一個 3 級表,并將 2 級修改為指向這個新的 3 級表。這在運行時會產生性能成本。
如果用戶預先知道可能會發生這樣的重新映射操作,那么他們可能會從一開始就為這個 2MB 區域強制執行 4KB 映射粒度;動態地重新映射其中一些 4KB 頁面就變成了輕量級操作。
區域的粒度是一個可選字段;如果未指定,則庫將選擇該區域的映射粒度,因為它認為合適(更多詳細信息可以在下面的內存映射算法部分找到)。
MPU 庫也用于指定翻譯,但 MPU 的翻譯僅限于指定有效地址和訪問權限。如果請求的虛擬地址和物理地址不匹配,系統將出現緊急情況。作為基于寄存器的確定性內存引用時序,MPU 硬件不涉及內存駐留轉換表。struct mmap_region
目前,MPU 庫也僅限于 EL2 的 MPU 翻譯,其他 EL 沒有 MMU 翻譯。然而,這些限制有望在未來的庫版本中得到克服。
17.2.2. 翻譯語境
庫可以創建或修改與庫代碼正在執行的異常級別不同的翻譯機制有關的翻譯表。例如,EL3 軟件(例如 BL31)可能使用該庫來創建與 S-EL1&0 翻譯機制相關的翻譯表。
這種靈活性來自于翻譯上下文的使用。翻譯上下文構成了圖書館用來跟蹤給定翻譯制度的一組翻譯表的狀態的信息的超集。
該庫在內部分配了一個默認翻譯上下文,該上下文與當前異常級別的翻譯機制有關。可以使用 REGISTER_XLAT_CONTEXT()宏顯式分配和初始化其他上下文。提供了單獨的 API 以作用于默認翻譯上下文或替代上下文。
要注冊翻譯上下文,用戶必須向圖書館提供以下信息:
-
一個名字。
生成的翻譯上下文變量將在此名稱之后調用,_xlat_ctx并附加到該名稱。例如,如果宏名稱參數為 foo,則上下文變量名稱將為foo_xlat_ctx。 -
要映射的最大mmap區域數。
如果適用,應考慮靜態和動態區域。 -
要分配的子翻譯表的數量。
要為此上下文靜態分配的轉換表的數量,不包括始終分配的初始查找級別轉換表。例如,如果初始查找級別為 1,則此參數將指定要為此上下文預分配的級別 2 和級別 3 轉換表的數量。 -
虛擬地址空間的大小。
使用此上下文映射的虛擬地址空間的大小(以字節為單位)。這將順便確定初始查找級別轉換表中的條目數:庫將分配映射整個虛擬地址空間所需的條目數。 -
物理地址空間的大小。
使用此上下文映射的物理地址空間的大小(以字節為單位)。
默認翻譯上下文是使用來自平臺特定定義的(大部分)信息在內部初始化的:
-
名稱:硬編碼為tf;因此默認上下文變量的名稱是 tf_xlat_ctx;
-
mmap區域的數量: MAX_MMAP_REGIONS;
-
子翻譯表的數量:MAX_XLAT_TABLES;
-
虛擬地址空間的大小:PLAT_VIRT_ADDR_SPACE_SIZE;
-
物理地址空間的大小:PLAT_PHY_ADDR_SPACE_SIZE.
-
有關這些宏的更多詳細信息,請參閱移植指南。
17.2.3. 靜態和動態內存區域
該庫可選擇支持動態內存映射。可以使用PLAT_XLAT_TABLES_DYNAMIC平臺構建標志啟用此功能。
啟用動態內存映射后,庫將 mmap 區域分類為 static或dynamic。
-
靜態區域在系統的生命周期內是固定的。它們只能在創建和填充轉換表之前盡早添加。之后無法刪除它們。
-
可以隨時添加或刪除動態區域。
禁用動態內存映射功能時,僅存在靜態區域。
動態內存映射特征可用于映射和取消映射瞬態內存區域。當用戶需要在固定的時間段內訪問某些內存時,這很有用,之后內存可能會被丟棄和回收。例如,僅在系統初始化時啟動時才需要的內存區域,或者在正常世界和可信世界之間臨時共享內存緩沖區。請注意,由調用者確保在添加或刪除區域時不會同時訪問這些區域。
盡管此功能提供了某種程度的動態內存分配,但這不允許在任意內存位置動態分配任意數量的內存。用戶仍然需要在編譯時聲明這些分配的限制;庫將拒絕任何不適合此預分配內存池的映射請求。
17.3. 庫 API
此庫公開的外部 API 在 xlat_tables_v2.h頭文件中聲明和記錄。這應該是獲取有關此庫提供的不同 API 的使用信息的參考點。本節僅提供一些額外的細節和說明。
盡管mmap_region結構是公開可見的類型,但不建議手動填充這些結構。相反,只要 API 需要 type 的函數參數mmap_region_t,就應該使用MAP_REGION*()輔助宏系列來構造它們。這是為了限制兼容性中斷的風險,如果mmap_region結構類型在未來發展。
和宏不允許指定映射粒度,這使庫實現可以自由選擇它MAP_REGION()。MAP_REGION_FLAT()但是,在需要特定粒度的情況下, MAP_REGION2()可能會使用宏。強烈MAP_REGION_FLAT()建議僅用于定義 MPU 庫的區域。
如本文檔前面所述,當禁用動態映射功能時,沒有動態區域的概念。從概念上講,只有靜態區域。出于這個原因(并保持與庫版本 1 的向后兼容性),映射靜態區域的 API 不會在其函數名稱中嵌入單詞static(例如mmap_add_region()),與動態區域 API(例如 mmap_add_dynamic_region())相反.
雖然靜態和動態區域的定義不是基于 MMU 的狀態,但兩者在某種程度上還是有關聯的。靜態區域只能在init_xlat_tables()調用之前添加,并且init_xlat_tables()必須在 MMU 仍然關閉時調用。因此,一旦啟用 MMU,就無法添加靜態區域。可以在 MMU 打開或關閉時添加動態區域。在實踐中,通常的調用流程如下所示:
-
(1) MMU 最初是關閉的。
-
(2) 添加一些靜態區域,添加一些動態區域。
-
(3) 根據 mmap 區域列表(使用init_xlat_tables*()API 之一)初始化轉換表。
-
(4) 此時,不再可能添加靜態區域。仍然可以添加或刪除動態區域。
-
(5) 啟用 MMU。
-
(6) 可以繼續添加或刪除動態區域。
因為靜態區域是在啟動時早期添加的,并且都在平臺初始化代碼的控制之下,所以mmap_add*()API 系列不會失敗。它們不返回任何錯誤代碼。
盡管如此,這些 API 會在更新翻譯上下文結構之前預先檢查是否可以成功添加區域。如果庫檢測到沒有足夠的內存來滿足請求,或者新區域將以無效的方式與另一個區域重疊,或者遇到任何其他意外錯誤,它們將在 UART 上打印錯誤消息。此外,當啟用斷言時(通常在調試版本中),將觸發斷言。否則,函數調用將立即返回,而不會添加有問題的內存區域。
17.4. 庫限制
動態區域不允許相互重疊。只要其中一個完全包含在另一個靜態區域中,就允許靜態區域重疊。這允許與庫版本 1 中的先前行為向后兼容。
17.5。實施細節
17.5.1. 代碼結構
該庫分為4個模塊:
- 核心模塊
提供庫的主要功能,例如翻譯表上下文的初始化和映射/取消映射內存區域。該模塊提供了一些功能,例如mmap_add_region_ctx讓調用者指定受它們影響的翻譯表上下文。
見xlat_tables_core.c。
- 活動上下文模塊
實例化當前 BL 圖像使用的上下文,并提供幫助器來操作它,將其從其余代碼中抽象出來。該模塊提供mmap_add_region了直接影響使用它們的 BL 圖像的功能。
見xlat_tables_context.c。
- 實用程序模塊
提供附加功能,如翻譯表當前狀態的調試打印和幫助查詢內存屬性并修改它們。
見xlat_tables_utils.c。
- Architectural module
提供依賴于當前執行狀態(AArch32/AArch64)的函數,例如用于 TLB 失效、設置 MMU 或計算物理地址空間大小的函數。他們不需要翻譯上下文來工作。
見aarch32/xlat_tables_arch.c和aarch64/xlat_tables_arch.c。
17.5.2. 從 mmap 區域到轉換表
翻譯上下文包含一個列表mmap_region_t,其中包含在任何給定時間映射的所有區域的信息。每當有映射(resp. unmap)內存區域的請求時,它都會被添加到(resp. 從)mmap_region_t列表中。
mmap 區域列表是一種表示內存布局的概念方式。在某些時候,庫必須將此信息轉換為實際的翻譯表以編程到 MMU 中。
在init_xlat_tables()調用 API 之前,該庫僅作用于 mmap 區域列表。此時通過其中一個mmap_add*()API 添加靜態或動態區域不會以任何方式影響轉換表,它們只會在內部 mmap 區域列表中注冊。只有當用戶調用時init_xlat_tables(),翻譯表才會根據迄今為止注冊的 mmap 區域列表填充到內存中。這是一項優化,允許一次性創建初始轉換表集,而不必在 MMU 禁用時每次都編輯它們。
調用 API后init_xlat_tables(),只能添加動態區域。對轉換表(以及 mmap 區域列表)的更改將立即生效。
17.5.3. 內存映射算法
映射函數被實現為遞歸算法。然而,它受轉換表深度級別的限制(Armv8-A 架構允許多達 4 個查找級別)。
默認情況下1,該算法將嘗試最小化為滿足用戶請求而創建的轉換表的數量。它將傾向于使用盡可能大的塊來映射區域,僅在絕對必要時才創建子表。這是為了減少固件的內存占用。
需要子表的最常見原因是特定映射需要更精細的粒度。未對齊的區域還需要比用戶最初預期的更精細的粒度,使用比預期更多的內存。原因是所有級別的轉換都被限制為與該級別的塊大小相同粒度的地址轉換。例如,對于 4 KiB 的頁面大小,2 級塊條目最多只能轉換為 2 MiB 的粒度。如果物理地址未與 2 MiB 對齊,則還需要額外的 3 級表。
請注意,并非每個翻譯級別都允許任何類型的描述符。根據頁面大小,轉換的級別 0 和 1 可能只允許表描述符。如果一個塊條目能夠描述翻譯,但該級別不允許塊描述符,則必須使用表描述符以及下一級的附加表。
mmap 區域的排序方式簡化了映射它們的代碼。盡管這種排序僅對重疊的靜態區域嚴格需要,但它也必須應用于動態區域以始終保持所有區域的一致順序。在映射每個新區域時,會檢查轉換表中的現有條目以確保一致性。使用的排序算法的更多細節請參考核心模塊源碼中的注釋。
此映射算法不適用于 MPU 庫,因為 MPU 硬件直接通過“基”和“限制”(底部和頂部)地址映射區域。
17.5.4. TLB 維護操作
該庫負責在需要時執行 TLB 維護操作。例如,當用戶請求刪除動態區域時,庫使與該區域關聯的所有 TLB 條目無效,以確保這些更改對使用更改的轉換表條目的后續執行(包括推測執行)可見。
一個反例是轉換表的初始化。在這種情況下,不需要顯式的 TLB 維護。Armv8-A 架構保證所有 TLB 都在復位時被禁用,并且它們的內容對復位2時的地址轉換沒有影響。因此,TLB 失效被推遲到enable_mmu*()函數族,就在 MMU 開啟之前。
關于啟用和禁用內存管理,對于 MPU 庫,為了減少混淆,調用以啟用或禁用 MPUmpu在其名稱中使用代替mmu. 例如,enable_mmu_el2()呼叫更改為 enable_mpu_el2()。
添加動態區域時也不需要 TLB 失效。動態區域不允許與現有內存區域重疊。因此,如果動態映射請求被認為是合法的,它會自動關注未在此轉換機制中映射的內存,并且庫會將其相應的轉換表條目初始化為無效描述符。鑒于 TLB 在架構上不允許保存任何無效的轉換表條目3,這意味著該映射不能緩存在 TLB 中。
總結
以上是生活随笔為你收集整理的17-Translation (XLAT) Tables Library的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 10-Platform Interrup
- 下一篇: 18-Chain of trust bi