Armv8-A Memory management

本文介紹Armv8-A的內存管理。內存管理指的是在系統中,內存訪問是如何實現的。程序員

使用內存管理機制,可讓每一個應用之間的內存地址分離,即sandbox application,也可讓多個在物理內存上碎片化的地址造成虛擬地址空間一個連續的地址,同時可讓程序員編程更爲方便。編程

image-20200802152342377

虛擬地址到物理地址的轉換經過mapping的方式來進行,其關鍵爲Translation tables,存儲在memory中,而且被OS或者hypervisor來管理。緩存

Memory Management Unit(MMU)

虛擬地址到物理地址的translation由MMU來執行,其包含兩個部分:架構

  1. The table walk unit, which contains logic that reads the translation tables from memory.
  2. Translation Lookaside Buffers (TLBs), which cache recently used translations ,是被映射的地址,而不是地址對應的內容。

當一個虛擬地址來臨的時候,MMU先是查找TLBs,看是否有cached translation,若是沒有,那麼table walk unit就memory中讀取對應的table entry或者table entries(大塊內存可能就須要多個entry)app

image-20200802154658528

Table entry

translation tabls經過把整個虛擬地址空間劃分爲多個大小相同的block/page,而後每一個page對應一個entry。less

image-20200802164144863

Table lookup

對於一個單一層級的查找來講,當對某個虛擬地址來查找table的時候,會把虛擬地址分城兩部分,高位的用來定位對應的entry,而低位的則用來表示該地址在查找到的該block中的偏置大小。ide

image-20200802162320897

Multilevel translation

在實踐使用中,通常使用的是分級table。每一級的訪問都像前面介紹的table lookup同樣訪問。性能

在armv8中,最多能夠分爲4級,每級分別被標記爲0-3. 這種分級方案支持larger blocks和 smaller blocks:spa

  • larger blocks:相比smaller blocks,它只要更少層級的讀取翻譯就能夠獲得對應的物理地址。同時,在TLB中的緩存效率也更高
  • small block:能夠提供對內存分配fine-grain的控制。可是在TLB中的緩存效率較低,由於須要更多層級的讀取翻譯才能夠獲得物理地址

image-20200802171131536

OS必須作好large block和small block之間的平衡,以達到效率和物理內存使用靈活上的平衡,從而達到最優的性能。Note:在這種狀況下,處理器並不知道這次翻譯對應的block大小,它須要經過table walk的方式來獲得。操作系統

Address spaces in Armv8-A

image-20200802190815094

在arm中,同時存在幾個獨立的虛擬地址空間,好比OS的、Hypervisor的以及Secore Monitor的。每一個虛擬地址空間都有他們本身的setting和tables。從這個圖上咱們能夠看到,OS的虛擬地址實際上是通過了兩層translation的,先是由OS翻譯成IPAs,而後再又hypervisor翻譯成真正的物理地址,這兩次翻譯雖然在表的格式方面可能有所差別,可是大致是基本是一致的。以下圖所示:

image-20200802192245574

Address sizes

雖然Armv8-A是64位的架構,可是並非意味着全部的地址都是64位的

Size of virtual addresses

image-20200802193015118

從這個圖也能夠看出,對於EL0/EL1,kernel space和user space的地址空間是分開的,kernel的位於高地址,user位於低地址。kernel space和user space都有各自的translation table。TCR_ELx registers中表示的TnSZ值用來控制虛擬地址空間:

image-20200802200714262

全部的armv8-a架構都支持48位的虛擬地址,52位的是可選支持。好比上圖的中的0x0000_0000_0000_0000~0x000F_FFFF_FFFF_FFFF表示的就是一個52位的地址空間

Size of physical address

size of物理地址是有實現決定的,最大支持52bits。若是你在table entry中指定一個

Adress Space Identifiers - Tagging translations with the owning process

對於現代操做系統,多個同時運行的進程看起來都是有着相同的虛擬地址的。那麼從MMU的角度來說,它怎麼區分一個相同的虛擬地址是來自哪一個進程呢?同時,理想化的來說,咱們但願不一樣的進程所對應的TLB是互不衝突的,這就不會致使TLB的的刷新以及上下文切換。解決這個問題的手段就是使用Address Space Identifiers (ASIDs)

對於EL0/EL1,即OS,的虛擬地址,translations table entry的屬性字段中的nG位用來標記global或者non-global。kernel對應的是global,也即意味着對於全部的進程都是共用的,而non-global的ranslation則與對應的進程相關。對於non-global的,則匹配TLB中的ASID和當前translations提供的ASID,會選擇匹配了的來進行處理。

image-20200802204452682

Virtual Machine Identifiers - Tagging translations with the owning VM

對於不一樣的VM,和ASID同樣,使用Virtual Machine Identifier (VMID) 來進行tag。這裏講的VM就是EL0 EL1 EL2 EL3這些。

Common not Private

有這樣一個問題,如今CPU都是多核的,同一個ASID和VMID在不一樣的process上有相同的含義嗎?

對Armv8.0-A 版本,答案是否認的。沒有要求對於多個processor之間要求ASID和VMID含義一致,即相同的ASID在不一樣的processor可能表示不一樣的進程。也即意味着,一個processor建立的TLB不能被另外一個processor使用。

可是,在實際中,咱們更傾向於他們是跨processor通用的,所以從Armv8.2-A 開始引入了Common not Private (CnP)bit in the Translation Table Base Register (TTBR) ,若是CnP位被set,那麼就意味着能夠通用。

Controlling address translation

Translation table format

image-20200802210800346

爲何對於level3沒有Next-level Table Address?由於前面也提到過,最多允許四級地址。也即3就是最後一級了,必須輸出硬件地址了,即Output Block Address

爲何level0沒有Output Block Address?由於level0表示的範圍太大了,直接讓其表示blocks沒有意義。

爲何第一個和第三個的descriptor是同樣的?由於這樣允許recursive tables,讓他們相互之間能夠point back。This is useful because it makes it easy to calculate the virtual address of a particular page table entry so that it can be updated .

Translation granule

translation granule,即翻譯粒度,指的是最小可described的block memory大小。Armv8-A 支持4KB, 16KB, and 64KB 。具體是由ID_AA64MMFR0_EL1 所指定。

image-20200802213039482

There are restrictions on using 52-bit addresses. When the selected granule is 4KB or 16KB, the maximum virtual address region size is 48 bits. Similarly, output physical addresses are limited to 48 bits. It is only when the 64KB granule is used that the full 52 bits can be used 。

The starting level of address translation

image-20200802213502181

這張表說明的是,當選擇4KB的 granule時,各個entry level所利用的地址bits。假如你設置TCR_ELx.T0SZ爲32,那麼虛擬地址空間就只有\(64-TOSZ=32\)位,那麼對應上表,你就能夠發現,已經不須要level0了,直接從level1開始就能夠徹底表示整個虛擬地址空間了。而若是虛擬地址空間只有30位,那麼只須要從level2開始就能夠完整表示整個地址空間了。也即,虛擬地址空間越小,那麼所需的level也就越小。

Registers that control address translation

地址翻譯是經過以下這些寄存器來配合控制的:

  • SCTLR_ELx
    • M - Enable Memory Management Unit (MMU).
    • C - Enable for data and unified caches
    • EE - Endianness of translation table walks.
  • 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.
  • 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.
  • MAIR_ELx
    • Attr - Controls the Type and cacheability in Stage 1 tables.

MMU disabled

若是MMU被禁用的話,那麼全部地址都是flat-mapped,即輸入等於輸出。

Translation Lookaside Buffer maintenance

TLB緩存的最近使用的translations,以即可以獲得translation結果而不用去讀tables。注意:TLB換成的translations,即從虛擬地址到硬件地址的直接映射關係,而不是translation tables。我的認爲有三個緣由:一是這樣效率最高,直接讀結果;二是entry有多個level,換成entry的話,會須要更多的空間;三是entry可能會隨着配置寄存器的更改而有不一樣的含義,這也會給緩存的重利用形成更多負擔。

這些狀況下,TLB不會對其進行緩存:

• A translation fault (unmapped address).
• An address size fault (address outside of range).
• An access flag fault.

當你首次mapping一個地址的時候,並不須要issue a TLB invalidate ,而當有下列行爲的時候,必須issue a TLB invalidate :

  • 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.

對應的指令爲TLBI <type><level>{IS|OS} {, <xt>}

Address translation instructions

Address Translation (AT) 能夠用來查詢特定地址的translation結果,翻譯結果和地址屬性,保存在Physical Address Register, PAR_EL1 。同時,AT指令能夠查詢指定regime的結果,好比EL2能夠查詢某個EL1地址的結果,但不能反過來。由於EL2比EL1擁有更高的特權。

Check your knowledge

  • What is the difference between a stage and a level in address translation?

    stage表示的是從輸入到輸出的兩個階段。第一個階段是從虛擬地址VA到中間物理地址IPA,階段二是從IPA到物理地址PA。只有EL1/EL0的纔有兩個stage。

    level表示的給定stage中不一樣級別的tables,從大範圍往小範圍級級縮小。

  • What is the maximum size of a physical address?
    這是implementation決定的,最大爲52bit

  • Which register field controls the size of the virtual address space?
    TCR_ELx.TnSZ, or VTCR_EL2.T0SZ for Stage 2

  • What is a translation granule, and what are the supported sizes?
    表示的是最小的內存描敘分割單元,支持4,16,64KB三種

  • What does the TLBI ALLE3 do?
    刷新全部EL3的虛擬地址空間對應的TLB entries

  • How are addresses mapped when the MMU is disabled?
    採用flat mapped,即輸出等於輸入

  • What is an ASID and when does a TLB entry include an ASID?
    ASID表示的當前地址對應的哪一個application。. Non-Global mappings (nG=1)對應的TLBs使用ASID進行標記。

  • MMU和DMA?
    As well as the Memory Management Unit (MMU) in the processor, it is increasingly common to have MMUs for non-processor masters, such as Direct Memory Access (DMA) engines. These are referred to as SMMUs (System MMUs) in Arm systems, and elsewhere as IOMMU.

參考

內容來自https://developer.arm.com/architectures/learn-the-architecture/memory-management

相關文章
相關標籤/搜索