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