09-LearnTheArchitecture-MemoryManagement
快速鏈接:
.
👉👉👉 個人博客筆記導讀目錄(全部) 👈👈👈
相關鏈接: (專題:《learn-the-architecture系列》)
- 01-Introducing the Arm architecture
- 02-Armv8-A Instruction Set Architecture
- 03_Introduction_to_AMBA_AXI
- 04-TrustZone for Armv8-A
- 05-Exception model
- 06-GICv3_v4_overview
- 07-Armv8-A virtualization
- 08-Isolation using virtualization in the Secure World_Whitepaper
- 09-LearnTheArchitecture-MemoryManagement
- 10-Armv8-A memory model guide–ongoing
- 11-Memory Management Examples
- 12-Generic Timer
- 13-Introduction to security
- 14-Providing protection for complex software
- 15-Arm-Confidential-Compute-Software-Stack
- 16-Understanding the Armv8.x extensions
目錄
- 1 Overview
- 2 What is memory management?
- 2.1. Why is memory management needed?
- 3 Virtual and physical addresses
- 4 The Memory Management Unit (MMU)
- 4.1. Table entry
- 4.2. Multilevel translation
- 5 Address spaces in Armv8-A
- 5.1. Address sizes
- 5.1.1 Size of virtual addresses
- 5.1.2 Size of physical addresses
- 5.1.3 Size of intermediate physical addresses
- 5.2. Address Space Identifiers - Tagging translations with the owning process
- 5.3. Virtual Machine Identifiers - Tagging translations with the owning VM
- 5.4. Common not Private
- 6 Controlling address translation
- 6.1. Translation table format
- 7 Translation granule
- 7.1. The starting level of address translation
- 7.2. Registers that control address translation
- 7.3. MMU disabled
- 8 Translation Lookaside Buffer maintenance
- 8.1. Format of a TLB operation
- 9 Address translation instructions
1 Overview
本文介紹了 Armv8-A 中的內存轉換,這是內存管理的關鍵。 它解釋了虛擬地址如何轉換為物理地址、轉換表格式以及軟件如何管理Translation Lookaside Buffers (TLB)。
這對于開發低級代碼(例如引導代碼或驅動程序)的任何人都很有用。 它與編寫代碼以設置或管理內存管理單元 (MMU) 的任何人都特別相關。
2 What is memory management?
內存管理描述了如何控制對系統內存的訪問。 每次操作系統或應用程序訪問內存時,硬件都會執行內存管理。 內存管理是一種將內存區域動態分配給應用程序的方法。
2.1. Why is memory management needed?
應用處理器旨在運行豐富的操作系統,例如 Linux,并支持虛擬內存系統。 在處理器上執行的軟件只能看到虛擬地址,處理器將其轉換為物理地址。 這些物理地址呈現給內存系統并指向內存中的實際物理位置。
3 Virtual and physical addresses
使用虛擬地址的好處是它允許管理軟件,例如操作系統 (OS),控制呈現給軟件的內存視圖。 操作系統可以控制哪些內存是可見的、該內存可見的虛擬地址以及允許對該內存進行哪些訪問。 這允許操作系統沙盒應用程序(對另一個應用程序隱藏一個應用程序的資源)并提供對底層硬件的抽象。
使用虛擬地址的一個好處是,操作系統可以將多個碎片化的內存物理區域作為單個、連續的虛擬地址空間呈現給應用程序。
虛擬地址也有利于軟件開發人員,他們在編寫應用程序時不會知道系統的確切內存地址。 使用虛擬地址,軟件開發人員無需關心物理內存。 應用程序知道由操作系統和硬件共同完成地址轉換。
實際上,每個應用程序都可以使用自己的一組虛擬地址,這些虛擬地址將映射到物理系統中的不同位置。 當操作系統在不同的應用程序之間切換時,它會重新map。 這意味著當前應用程序的虛擬地址將映射到內存中正確的物理位置。
虛擬地址通過映射轉換為物理地址。 虛擬地址和物理地址之間的映射存儲在轉換表(有時稱為頁表)中,如下圖所示:
Translation tables在內存中并由軟件管理,通常是操作系統或管理程序。 翻譯表不是靜態的,可以隨著軟件需求的變化而更新。 這會更改虛擬地址和物理地址之間的映射。
4 The Memory Management Unit (MMU)
內存管理單元 (MMU) 執行地址翻譯。MMU 包含以下內容:
- The table walk unit : 它從內存中讀取頁表,并完成地址轉換
- Translation Lookaside Buffers (TLBs) : 緩存,相當于cache
軟件看到的所有內存地址都是虛擬的。 這些內存地址被傳遞到 MMU,它檢查最近使用的緩存轉換的 TLB。 如果 MMU 沒有找到最近緩存的翻譯,表遍歷單元從內存中讀取適當的一個或多個表條目,如下所示:
在進行內存訪問之前,必須將虛擬地址轉換為物理地址(因為我們必須知道我們正在訪問哪個物理內存位置)。 這種轉換需要也適用于緩存數據,因為在 Armv6 和更高版本的處理器上,數據緩存使用物理地址(物理標記的地址)存儲數據。 因此,必須先轉換地址,然后才能完成緩存查找。
注意:架構是一種行為規范。 緩存必須表現得就像它們被物理標記一樣。 一個實現可能會做一些不同的事情,只要這不是軟件可見的。
4.1. Table entry
Translation tables 的工作原理是將虛擬地址空間劃分為大小相等的塊,并在表中為每個塊提供一個entry。
Translation tables 中的entry 0 提供block 0 的映射,entry 1 提供block 1 的映射,依此類推。 每個條目都包含相應物理內存塊的地址以及訪問物理地址時要使用的屬性。
4.2. Multilevel translation
在單級查找中,虛擬地址空間被分成大小相等的塊。 在實踐中,使用了表的層次結構。
第一個表(Level 1 表)將虛擬地址空間劃分為大塊。 該表中的每個條目都可以指向一個相等大小的物理內存塊,也可以指向另一個表,該表將該塊細分為更小的塊。 我們稱這種類型的表為“多級表”。 在這里我們可以看到一個具有三個級別的多級表的示例:
在 Armv8-A 中,最大級別數為 4 (扯淡!! 這里是錯誤的,看看就好),級別編號為 0 到 3。這種多級方法允許描述更大的塊和更小的塊。 大小塊的特點如下:
- 大塊需要比小塊更少的讀取級別來翻譯。 此外,在 TLB 中緩存大塊的效率更高。 –這個特點好好理解,就很不錯嘛
- 小塊為軟件提供了對內存分配的細粒度控制。 但是,在 TLB 中緩存小塊的效率較低。 緩存效率較低,因為小塊需要通過級別多次讀取才能進行轉換。
為了管理這種權衡,操作系統必須平衡使用大型映射的效率與使用較小映射以獲得最佳性能的靈活性
注意:處理器在開始查表時不知道翻譯的大小。 處理器通過執行 table walk 計算出正在轉換的塊的大小。
5 Address spaces in Armv8-A
Armv8-A中有幾個獨立的虛擬地址空間。 此圖顯示了這些虛擬地址空間:
圖中展示了三個虛擬地址空間:
- NS.EL0 and NS.EL1 (Non-secure EL0/EL1).
- NS.EL2 (Non-secure EL2).
- EL3.
這些虛擬地址空間中的每一個都是獨立的,并且有自己的設置和表。 我們經常將這些設置和表格稱為“translation regimes”。 Secure EL0、Secure EL1 和 Secure EL2 也有虛擬地址空間,但圖中未顯示。
(注:Armv8.4-A 中添加了對 Secure EL2 的支持)
因為有多個虛擬地址空間,所以指定一個地址所在的地址空間很重要。例如NS.EL2:0x8000指的是Non-secure EL2虛擬地址空間中的地址0x8000。
該圖還顯示來自非安全 EL0 和非安全 EL1 的虛擬地址通過兩組表。 這些表支持虛擬化并允許管理程序虛擬化虛擬機 (VM) 所見的物理內存視圖。
在虛擬化中,我們將操作系統控制的一組轉換稱為stage 1。stage 1 表將虛擬地址轉換為中間物理地址 (IPA)。 在stage 1 ,操作系統認為 IPA 是物理地址空間。 然而,管理程序控制stage 2轉換。stage 轉換將 IPA 轉換為物理地址。 此圖顯示了兩組翻譯的工作原理:
雖然在 table format上有一些細微的差別,但 Stage 1 和 Stage 2 翻譯的過程通常是相同的。
注意:在 Arm,我們在許多示例中使用地址 0x8000。 0x8000 也是與 Arm 鏈接器 armlink 鏈接的默認地址。 該地址來自早期的微型計算機 BBC Micro Model B,它在地址 0x8000 處具有 ROM(和橫向 RAM)。 BBC Micro Model B 是由一家名為 Acorn 的公司制造的,該公司開發了 Acorn RISC Machine (ARM),后來更名為 Arm。
5.1. Address sizes
Armv8-A 是 64 位架構,但這并不意味著所有地址都是 64 位
5.1.1 Size of virtual addresses
虛擬地址以 64 位格式存儲。 因此,加載指令 (LDR) 和存儲指令 (STR) 中的地址始終在 X 寄存器中指定。 但是,并非 X 寄存器中的所有地址都是有效的。 下圖展示了 AArch64 中虛擬地址空間的布局:
EL0/EL1 虛擬地址空間有兩個區域:內核空間和應用程序空間。 這兩個區域顯示在圖的左側,內核空間在頂部,應用程序空間(標記為“用戶空間”)在地址空間的底部。 內核空間和用戶空間有單獨的轉換表,這意味著它們的映射可以分開。
注意:如果您將 HCR_EL2.E2H 設置為 1,則會啟用主機操作系統在 EL2 中運行,而主機操作系統的應用程序在 EL0 中運行的配置。 在這種情況下,EL2 也有upper 和 lower region。
每個region是多大,是根據虛擬地址有效位決定的,即由TCG_EL1.TxSZ配置的
注意:所有 Armv8-A 實現都支持 48 位虛擬地址。 對 52 位虛擬地址的支持是可選的,由 ID_AA64MMFR2_EL1 獲取。
5.1.2 Size of physical addresses
物理地址的大小是實現定義的,最多 52 位。 ID_AA64MMFR0_EL1 寄存器報告處理器實現的大小。 對于 Arm Cortex-A 處理器,這通常是 40 位或 44 位。
注意:在 Armv8.0-A 中,物理地址的最大大小為 48 位。 這在 Armv8.2-A 中擴展到 52 位
5.1.3 Size of intermediate physical addresses
如果在轉換表條目中指定的輸出地址大于實現的最大值,則內存管理單元 (MMU) 將生成異常作為地址大小錯誤。
IPA 空間的大小可以按照與虛擬地址空間相同的方式進行配置。 VTCR_EL2.T0SZ 控制大小。 可配置的最大大小與處理器支持的物理地址大小相同。 這意味著您不能配置比支持的物理地址空間更大的 IPA 空間。
5.2. Address Space Identifiers - Tagging translations with the owning process
許多現代操作系統的所有應用程序似乎都從同一地址區域運行,這就是我們所描述的用戶空間。實際上,不同的應用程序需要不同的映射。例如,這意味著 VA 0x8000 的轉換取決于當前正在運行的應用程序。
理想情況下,我們希望不同應用程序的翻譯在翻譯后備緩沖區 (TLB) 中共存,以防止需要在上下文切換時使 TLB 失效。但是處理器如何知道要使用哪個版本的 VA 0x8000 轉換呢?在 Armv8-A 中,答案是地址空間標識符 (ASID)。
對于 EL0/EL1 虛擬地址空間,可以使用轉換表條目的屬性字段中的 nG 位將轉換標記為全局 (G) 或非全局 (nG)。例如,內核映射是全局轉換,應用程序映射是非全局轉換。全局翻譯適用于當前正在運行的任何應用程序。非全局翻譯僅適用于特定應用程序。
非全局映射在 TLB 中使用 ASID 進行標記。在 TLB 查找中,將 TLB 條目中的 ASID 與當前選擇的 ASID 進行比較。如果它們不匹配,則不使用 TLB 條目。該圖顯示了內核空間中沒有 ASID 標簽的全局映射和用戶空間中帶有 ASID 標簽的非全局映射:
該圖顯示允許多個應用程序的 TLB 條目在緩存中共存,ASID 決定使用哪個條目。 ASID 存儲在兩個 TTBRn_EL1 寄存器之一中。 通常 TTBR0_EL1 用于用戶空間。 因此,單個寄存器更新可以更改 ASID 和它指向的轉換表。
注意:ASID 標記在 EL2 中也可用,當 HCR_EL2.E2H==1 時
5.3. Virtual Machine Identifiers - Tagging translations with the owning VM
EL0/EL1 轉換也可以使用虛擬機標識符 (VMID) 進行標記。 VMID 允許來自不同 VM 的轉換在緩存中共存。 這類似于 ASID 為來自不同應用程序的翻譯工作的方式。 實際上,這意味著某些翻譯將同時使用 VMID 和 ASID 進行標記,并且兩者必須匹配才能使用 TLB 條目。
注意:當安全狀態支持虛擬化時,EL0/EL1 轉換總是用 VMID 標記——即使第 2 階段轉換沒有啟用。 這意味著,如果您正在編寫初始化代碼并且沒有使用虛擬機管理程序,那么在設置 Stage 1 MMU 之前設置一個已知的 VMID 值非常重要。
5.4. Common not Private
如果一個系統包含多個處理器,那么在一個處理器上使用的 ASID 和 VMID 在其他處理器上是否具有相同的含義?
對于 Armv8.0-A,答案是它們不一定意味著相同的事情。不要求軟件以相同的方式跨多個處理器使用給定的 ASID。例如,ASID 5 可能由一個處理器上的計算器和另一個處理器上的 Web 瀏覽器使用。這意味著由一個處理器創建的 TLB 條目不能被另一個處理器使用。
在實踐中,軟件不太可能跨處理器使用不同的 ASID。軟件在給定系統中的所有處理器上以相同方式使用 ASID 和 VMID 更為常見。因此,Armv8.2-A 在轉換表基址寄存器 (TTBR) 中引入了公共非私有 (CnP) 位。當 CnP 位被設置時,軟件承諾在所有處理器上以相同的方式使用 ASID 和 VMID,這允許另一個處理器使用由一個處理器創建的 TLB 條目。
注意:我們一直在談論處理器,但是,從技術上講,我們應該使用術語處理元素 (PE)。 PE 是任何實現 Arm 架構的機器的通用術語。這一點很重要,因為在處理器之間共享 TLB 會很困難,因為存在微體系結構的原因。但是在多線程處理器中,每個硬件線程都是一個 PE,共享 TLB 條目更為可取。
6 Controlling address translation
6.1. Translation table format
在這里,我們可以看到翻譯表entry有4種不同格式(扯淡!!其實就3種,block descriptor和page descriptor其實是一種):
注意:為清楚起見,此圖未指定位字段的寬度。您可以在 Arm 架構參考手冊 Armv8 中找到此信息,適用于 Armv8-A 架構配置文件:VMSAv8-64 轉換表格式描述符。
每個entry是 64 位,底部的兩位確定entry的類型。
請注意,某些表entry僅在特定級別有效。表的最大級別數為四,這就是為什么級別 3(或第四級別)表沒有表描述符的原因。類似地,0 級也沒有塊描述符或頁描述符。因為 0 級entry覆蓋了很大的虛擬地址空間區域,所以允許塊是沒有意義的。
注意:0-2 級表描述符的編碼與級別 3 的頁描述符相同。這種編碼允許“遞歸表”,它們指向自身。這很有用,因為它可以輕松計算特定頁表entry的虛擬地址,以便可以更新
7 Translation granule
翻譯顆粒是可以描述的最小內存塊。 不能描述更小的東西,只能描述更大的塊,它們是顆粒的倍數。
Armv8-A 支持三種不同的粒度:4KB、16KB 和 64KB。
處理器支持的粒度是實現定義的,由 ID_AA64MMFR0_EL1 報告。 所有 Arm Cortex-A 處理器都支持 4KB 和 64KB。 選擇的粒度是最新級別表中可以描述的最小塊。 也可以描述更大的塊。 下表顯示了基于所選粒度的每個級別表的不同塊大小:
(星號*) 使用 52 位地址有限制。 當所選顆粒為4KB或16KB時,最大虛擬地址區域大小為48位。 同樣,輸出物理地址限制為 48 位。 只有在使用64KB顆粒時,才可以使用完整的52位。
注意:TCR_EL1 有兩個單獨的字段,用于控制內核空間和用戶空間虛擬地址范圍的粒度大小。 這些字段對于內核空間稱為 TG1,對于用戶空間稱為 TG0。 程序員的一個潛在問題是這兩個字段具有不同的編碼
7.1. The starting level of address translation
虛擬地址空間的粒度和大小共同控制地址轉換的起始級別。
上表總結了表的每個級別的每個粒度的塊大小(單個條目覆蓋的虛擬地址范圍的大小)。 從塊大小,您可以計算出虛擬地址的哪些位用于索引每個級別的表。
我們以 4KB 顆粒為例。 此圖顯示了用于為 4KB 顆粒索引不同級別表的位:
7.2. Registers that control address translation
地址轉換由系統寄存器的組合控制:
(1)、SCTLR_ELx
- M - Enable Memory Management Unit (MMU).
- C - Enable for data and unified caches.
- EE - Endianness of translation table walks.
(2)、TTBR0_ELx and TTBR1_ELx
- BADDR - Physical address (PA) (or intermediate physical address, IPA, for EL0/EL1) of start of translation table.
- ASID - The Address Space Identifier for Non-Global translations.
(3)、TCR_ELx
- PS/IPS - Size of PA or IPA space, the maximum output addresssize.
- TnSZ - Size of address space covered by table.
- TGn - Granule size.
- SH/IRGN/ORGN - Cacheability and shareability to be used by MMU table walks.
- TBIn - Disabling of table walks to a specific table.
(4)、MAIR_ELx
- Attr - Controls the Type and cacheability in Stage 1 tables.
7.3. MMU disabled
當 MMU 在一個轉換階段被禁用時,所有地址都是一一映射的。 平面映射意味著輸入和輸出地址相同。
8 Translation Lookaside Buffer maintenance
The Translation Lookaside Buffers (TLBs) 緩存最近使用的翻譯。這種緩存允許后續查找重用翻譯,而無需重新讀取表。
注意:TLB 是翻譯緩存,而不是翻譯表緩存。區別很微妙。幾個寄存器字段控制如何解釋轉換表entry。 TLB entry中的內容是在遍歷表時給定配置的轉換表entry的解釋。在 Arm 架構參考手冊 (Arm ARM) 中,此類寄存器字段被描述為“允許緩存在 TLB 中”。
如果更改轉換表entry或影響條目解釋方式的控件,則需要使 TLB 中受影響的條目無效。如果您不使這些條目無效,則處理器可能會繼續使用舊的翻譯。
處理器不允許導致以下任何錯誤的緩存到tlb,:
- A translation fault (unmapped address).
- An address size fault (address outside of range).
- An access flag fault
因此,首次映射地址時無需發出 TLB 無效。 但是,如果您想執行以下任何操作,則確實需要發出 TLB 無效:
- Unmap an address
Take an address that was previously valid or mapped and mark it as faulting - Change the mapping of an address
Change the output address or any of the attributes. For example, change an address from read-only to read-write permissions. - Change the way the tables are interpreted
This is less common. But, for example, if the granule size was changed, then the interpretation of the tables also changes. Therefore, a TLB invalidate would be necessary.
8.1. Format of a TLB operation
TLBI 指令用于使 TLB 中的條目無效。 該指令的語法是:
TLBI <type><level>{IS|OS} {, <xt>}
9 Address translation instructions
地址轉換 (AT) 指令允許軟件查詢特定地址的轉換。 產生的轉換(包括屬性)被寫入物理地址寄存器 PAR_EL1。
AT 指令的語法允許您指定要使用的翻譯機制。 例如,EL2 可以查詢 EL0/EL1 轉換機制。 但是,EL1 不能使用 AT 指令查詢 EL2 轉換機制,因為這是對特權的破壞。
如果請求的翻譯會導致錯誤,則不會生成異常。 相反,將產生的故障類型記錄在 PAR_EL1 中。
總結
以上是生活随笔為你收集整理的09-LearnTheArchitecture-MemoryManagement的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 08-Isolation using v
- 下一篇: 10-Armv8-A memory mo