(10)ATF MMU轉換表

MMU簡介

MMU(內存管理單元)負責將軟件使用的虛擬地址轉換為內存系統中使用的物理地址。MMU包括兩個模塊:TLB(Translation Lookaside Buffer)和TWU(Table Walk Unit)。TLB緩存最近使用的轉換(類似cache,將轉換映射放入緩存,提高映射效率),而TWU從內存中讀取轉換表(查表,完成虛擬地址到物理地址的轉換)。

轉換表位于內存中,用于存儲虛擬地址和物理地址之間的映射,另外還包括物理內存位置的屬性。這些轉換表是由內存管理單元MMU訪問。

軟件分配的所有內存地址都是虛擬的。這些內存地址被傳遞到 MMU,MMU 檢查 TLB 中是否有最近使用的緩存轉換。如果 MMU 沒有找到最近緩存的轉換,TWU會從內存中讀取相應的表條目,如下所示:

MMU

轉換(XLAT)表庫

代碼結構

轉換表庫有兩個版本V1和V2,我們這里只關注V2的轉換表庫。

├── aarch64
│   ├── enable_mmu.S
│   └── xlat_tables_arch.c
├── ro_xlat_tables.mk
├── xlat_tables.mk
├── xlat_tables_context.c
├── xlat_tables_core.c
├── xlat_tables_private.h
└── xlat_tables_utils.c
  • 核心模塊:主要是xlat_tables_core.c文件,提供轉換上下文初始化和內存映射等功能
  • 上下文模塊:主要是xlat_tables_context.c文件,提供添加映射區域等接口
  • 工具模塊:主要是xlat_tables_utils.c文件,提供轉換表狀態打印,內存屬性查看等功能
  • 架構模塊:主要是xlat_tables_arch.c文件,提供TLB無效,創建MMU及計算物理地址空間大小等功能

映射區域

mmap regions是對要內存映射區域的抽象。

/** Structure for specifying a single region of memory.*/
typedef struct mmap_region {unsigned long long	base_pa;uintptr_t		base_va;size_t			size;unsigned int		attr;/* Desired granularity. See the MAP_REGION2() macro for more details. */size_t			granularity;
} mmap_region_t;
  • base_pa:物理基地址
  • base_va:虛擬基地址
  • size:大小
  • attr:屬性
  • granularity:映射粒度

為了不直接使用結構體struct mmap_region,使用宏MAP_REGIONMAP_REGION_PLAT定義映射區域。

/** Default granularity size for an mmap_region_t.* Useful when no specific granularity is required.** By default, choose the biggest possible block size allowed by the* architectural state and granule size in order to minimize the number of page* tables required for the mapping.*/
#define REGION_DEFAULT_GRANULARITY	XLAT_BLOCK_SIZE(MIN_LVL_BLOCK_DESC)/* Helper macro to define an mmap_region_t. */
#define MAP_REGION(_pa, _va, _sz, _attr)	\MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, REGION_DEFAULT_GRANULARITY)/* Helper macro to define an mmap_region_t with an identity mapping. */
#define MAP_REGION_FLAT(_adr, _sz, _attr)			\MAP_REGION(_adr, _adr, _sz, _attr)

可以看出,最終展開到宏MAP_REGION_FULL_SPEC,定義如下。

/** Helper macro to define an mmap_region_t.  This macro allows to specify all* the fields of the structure but its parameter list is not guaranteed to* remain stable as we add members to mmap_region_t.*/
#define MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, _gr)		\{							\.base_pa = (_pa),				\.base_va = (_va),				\.size = (_sz),					\.attr = (_attr),				\.granularity = (_gr),				\}

內存屬性

內存屬性包括內存類型、訪問權限、執行權限以及緩存性與共享性等。

/** Memory mapping attributes*//** Memory types supported.* These are organised so that, going down the list, the memory types are* getting weaker; conversely going up the list the memory types are getting* stronger.*/
#define MT_DEVICE		U(0)
#define MT_NON_CACHEABLE	U(1)
#define MT_MEMORY		U(2)
/* Values up to 7 are reserved to add new memory types in the future */#define MT_RO			(U(0) << MT_PERM_SHIFT)
#define MT_RW			(U(1) << MT_PERM_SHIFT)#define MT_SECURE		(U(0) << MT_PAS_SHIFT)
#define MT_NS			(U(1) << MT_PAS_SHIFT)
#define MT_ROOT			(U(2) << MT_PAS_SHIFT)
#define MT_REALM		(U(3) << MT_PAS_SHIFT)/** Access permissions for instruction execution are only relevant for normal* read-only memory, i.e. MT_MEMORY | MT_RO. They are ignored (and potentially* overridden) otherwise:*  - Device memory is always marked as execute-never.*  - Read-write normal memory is always marked as execute-never.*/
#define MT_EXECUTE		(U(0) << MT_EXECUTE_SHIFT)
#define MT_EXECUTE_NEVER	(U(1) << MT_EXECUTE_SHIFT)/** When mapping a region at EL0 or EL1, this attribute will be used to determine* if a User mapping (EL0) will be created or a Privileged mapping (EL1).*/
#define MT_USER			(U(1) << MT_USER_SHIFT)
#define MT_PRIVILEGED		(U(0) << MT_USER_SHIFT)/** Shareability defines the visibility of any cache changes to* all masters belonging to a shareable domain.** MT_SHAREABILITY_ISH: For inner shareable domain* MT_SHAREABILITY_OSH: For outer shareable domain* MT_SHAREABILITY_NSH: For non shareable domain*/
#define MT_SHAREABILITY_ISH	(U(1) << MT_SHAREABILITY_SHIFT)
#define MT_SHAREABILITY_OSH	(U(2) << MT_SHAREABILITY_SHIFT)
#define MT_SHAREABILITY_NSH	(U(3) << MT_SHAREABILITY_SHIFT)/* Compound attributes for most common usages */
#define MT_CODE			(MT_MEMORY | MT_RO | MT_EXECUTE)
#define MT_RO_DATA		(MT_MEMORY | MT_RO | MT_EXECUTE_NEVER)
#define MT_RW_DATA		(MT_MEMORY | MT_RW | MT_EXECUTE_NEVER)
  1. 內存類型:設備內存(MT_DEVICE),不帶Cache普通內存(MT_NON_CACHEABLE),普通內存(MT_MEMORY)。
  2. 訪問權限:只讀(RO),讀寫(RW)。
  3. 物理地址空間安全屬性:安全(MT_SECURE),非安全(MT_NS),ROOT(MT_ROOT),REALM(MT_REALM),后面兩種是Armv9新增的RME。
  4. 指令執行權限:可執行(MT_EXECUTE),不可執行(MT_EXECUTE_NEVER)。執行權限僅對普通只讀內存有效,即MT_MEMORY | MT_RO。設備內存和讀寫內存始終標記為不可執行,即忽略執行權限。
  5. EL0/EL1虛擬地址空間有兩個區域布局:內核空間和應用空間,下面定義了轉換表選擇:用戶空間映射(MT_USER),內核空間映射(MT_PRIVILEGED)。
  6. 對于屬于一個共享域中的Master,定義了緩存共享性:內部共享(MT_SHAREABILITY_ISH),外部共享(MT_SHAREABILITY_OSH),沒有共享性(MT_SHAREABILITY_NSH)。
  7. 最后結合上面定義了一些常用的屬性:代碼(MT_CODE),只讀數據(MT_RO_DATA),讀寫數據(MT_RW_DATA)。

另外還定義了EL3下的內存類型,如果使能了RME,EL3的PAS(物理地址空間)屬性是ROOT,否則是SECURE。

/* Memory type for EL3 regions. With RME, EL3 is in ROOT PAS */
#if ENABLE_RME
#define EL3_PAS			MT_ROOT
#else
#define EL3_PAS			MT_SECURE
#endif /* ENABLE_RME */

轉換上下文

轉換上下文存放了轉換表的所有信息,結構體定義如下:

/* Struct that holds all information about the translation tables. */
struct xlat_ctx {/** Max allowed Virtual and Physical Addresses.*/unsigned long long pa_max_address;uintptr_t va_max_address;/** Array of all memory regions stored in order of ascending end address* and ascending size to simplify the code that allows overlapping* regions. The list is terminated by the first entry with size == 0.* The max size of the list is stored in `mmap_num`. `mmap` points to an* array of mmap_num + 1 elements, so that there is space for the final* null entry.*/struct mmap_region *mmap;int mmap_num;/** Array of finer-grain translation tables.* For example, if the initial lookup level is 1 then this array would* contain both level-2 and level-3 entries.*/uint64_t (*tables)[XLAT_TABLE_ENTRIES];int tables_num;
#if PLAT_RO_XLAT_TABLESbool readonly_tables;
#endif/** Keep track of how many regions are mapped in each table. The base* table can't be unmapped so it isn't needed to keep track of it.*/
#if PLAT_XLAT_TABLES_DYNAMICint *tables_mapped_regions;
#endif /* PLAT_XLAT_TABLES_DYNAMIC */int next_table;/** Base translation table. It doesn't need to have the same amount of* entries as the ones used for other levels.*/uint64_t *base_table;unsigned int base_table_entries;/** Max Physical and Virtual addresses currently in use by the* translation tables. These might get updated as we map/unmap memory* regions but they will never go beyond pa/va_max_address.*/unsigned long long max_pa;uintptr_t max_va;/* Level of the base translation table. */unsigned int base_level;/* Set to true when the translation tables are initialized. */bool initialized;/** Translation regime managed by this xlat_ctx_t. It should be one of* the EL*_REGIME defines.*/int xlat_regime;
};
  • pa_max_address & va_max_address:允許的最大虛擬地址和物理地址。
  • mmap & mmap_num:存放內存映射區域數組及數組大小,按結束地址和大小升序排列。
  • tables & tables_num:多級轉換表項,比如如果查詢頁表等級L1,該數組存放L2頁表項和L3頁表項。
  • base_table & base_table_entries:轉換表基地址和表項數量。
  • max_pa & max_va:當前轉換表中最大的物理地址和虛擬地址。
  • base_level:基本轉換表等級。
  • initialized:轉換表是否初始化。
  • xlat_regime:轉換機制,包括:EL1&EL0(EL1_EL0_REGIME),EL2(EL2_REGIME),EL3(EL3_REGIME),INVALID(EL_REGIME_INVALID),INVALID表示運行時決定。

對于啟動階段,創建分配了一個默認轉換上下文,使用宏REGISTER_XLAT_CONTEXT定義。

REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES,PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE);#define REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \_virt_addr_space_size, _phy_addr_space_size) \REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, (_mmap_count),	\(_xlat_tables_count),		\(_virt_addr_space_size),	\(_phy_addr_space_size),	\EL_REGIME_INVALID,		\"xlat_table", "base_xlat_table")

該宏需要提供如下參數:

  • _ctx_name:上下文名字
  • _mmap_count:需要分配的最大映射區域數
  • _xlat_tables_count:需要分配的次級頁表數量
  • _virt_addr_space_size:虛擬地址空間大小
  • _phy_addr_space_size:物理地址空間大小

通用轉換表API

每個API都有兩種接口類型:用于BL啟動鏡像的當前轉換上下文;用于給定的上下文,以_ctx結尾。

初始化轉換表

根據當前映射區域初始化轉換表。在調用該API之后,只允許添加動態內存區域。

/** Initialize translation tables from the current list of mmap regions. Calling* this function marks the transition point after which static regions can no* longer be added.*/
void init_xlat_tables(void);
void init_xlat_tables_ctx(xlat_ctx_t *ctx);

init_xlat_tables最終也是調用init_xlat_tables_ctx函數,只是先獲取當前的運行異常等級,配置使用哪個轉換機制。

void __init init_xlat_tables(void)
{assert(tf_xlat_ctx.xlat_regime == EL_REGIME_INVALID);unsigned int current_el = xlat_arch_current_el();if (current_el == 1U) {tf_xlat_ctx.xlat_regime = EL1_EL0_REGIME;} else if (current_el == 2U) {tf_xlat_ctx.xlat_regime = EL2_REGIME;} else {assert(current_el == 3U);tf_xlat_ctx.xlat_regime = EL3_REGIME;}init_xlat_tables_ctx(&tf_xlat_ctx);
}

init_xlat_tables_ctx主要功能是將映射區域添加到轉換表中,定義如下,關鍵函數為xlat_tables_map_region

void __init init_xlat_tables_ctx(xlat_ctx_t *ctx)
{assert(ctx != NULL);assert(!ctx->initialized);assert((ctx->xlat_regime == EL3_REGIME) ||(ctx->xlat_regime == EL2_REGIME) ||(ctx->xlat_regime == EL1_EL0_REGIME));assert(!is_mmu_enabled_ctx(ctx));mmap_region_t *mm = ctx->mmap;assert(ctx->va_max_address >=(xlat_get_min_virt_addr_space_size() - 1U));assert(ctx->va_max_address <= (MAX_VIRT_ADDR_SPACE_SIZE - 1U));assert(IS_POWER_OF_TWO(ctx->va_max_address + 1U));xlat_mmap_print(mm);/* All tables must be zeroed before mapping any region. */for (unsigned int i = 0U; i < ctx->base_table_entries; i++)ctx->base_table[i] = INVALID_DESC;for (int j = 0; j < ctx->tables_num; j++) {
#if PLAT_XLAT_TABLES_DYNAMICctx->tables_mapped_regions[j] = 0;
#endiffor (unsigned int i = 0U; i < XLAT_TABLE_ENTRIES; i++)ctx->tables[j][i] = INVALID_DESC;}while (mm->size != 0U) {uintptr_t end_va = xlat_tables_map_region(ctx, mm, 0U,ctx->base_table, ctx->base_table_entries,ctx->base_level);
#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)xlat_clean_dcache_range((uintptr_t)ctx->base_table,ctx->base_table_entries * sizeof(uint64_t));
#endifif (end_va != (mm->base_va + mm->size - 1U)) {ERROR("Not enough memory to map region:\n"" VA:0x%lx  PA:0x%llx  size:0x%zx  attr:0x%x\n",mm->base_va, mm->base_pa, mm->size, mm->attr);panic();}mm++;}assert(ctx->pa_max_address <= xlat_arch_get_max_supported_pa());assert(ctx->max_va <= ctx->va_max_address);assert(ctx->max_pa <= ctx->pa_max_address);ctx->initialized = true;xlat_tables_print(ctx);
}

添加映射區域

上面兩個API是根據PA和VA添加映射區域,下面兩個是以數組形式進行添加映射區域。

/** Add a static region with defined base PA and base VA. This function can only* be used before initializing the translation tables. The region cannot be* removed afterwards.*/
void mmap_add_region(unsigned long long base_pa, uintptr_t base_va,size_t size, unsigned int attr);
void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm);/** Add an array of static regions with defined base PA and base VA. This* function can only be used before initializing the translation tables. The* regions cannot be removed afterwards.*/
void mmap_add(const mmap_region_t *mm);
void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm);

在啟動階段定義了一個默認的轉換上下文:

/** Allocate and initialise the default translation context for the BL image* currently executing.*/
REGISTER_XLAT_CONTEXT(tf, MAX_MMAP_REGIONS, MAX_XLAT_TABLES,PLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE);

mmap_add_regionmmap_add都是添加到這個默認的轉換上下文中。

void mmap_add_region(unsigned long long base_pa, uintptr_t base_va, size_t size,unsigned int attr)
{mmap_region_t mm = MAP_REGION(base_pa, base_va, size, attr);mmap_add_region_ctx(&tf_xlat_ctx, &mm);
}void mmap_add(const mmap_region_t *mm)
{mmap_add_ctx(&tf_xlat_ctx, mm);
}

上面最終都會調用mmap_add_region_ctx函數,將定義的映射區域添加到轉換上下文定義的數組中,其是就是整合到一個映射區域數組中,虛擬地址小和區域大小小的排在前面。

void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
{mmap_region_t *mm_cursor = ctx->mmap, *mm_destination;const mmap_region_t *mm_end = ctx->mmap + ctx->mmap_num;const mmap_region_t *mm_last;unsigned long long end_pa = mm->base_pa + mm->size - 1U;uintptr_t end_va = mm->base_va + mm->size - 1U;int ret;/* Ignore empty regions */if (mm->size == 0U)return;/* Static regions must be added before initializing the xlat tables. */assert(!ctx->initialized);ret = mmap_add_region_check(ctx, mm);if (ret != 0) {ERROR("mmap_add_region_check() failed. error %d\n", ret);assert(false);return;}/** Find correct place in mmap to insert new region.** 1 - Lower region VA end first.* 2 - Smaller region size first.** VA  0                                   0xFF** 1st |------|* 2nd |------------|* 3rd                 |------|* 4th                            |---|* 5th                                   |---|* 6th                            |----------|* 7th |-------------------------------------|** This is required for overlapping regions only. It simplifies adding* regions with the loop in xlat_tables_init_internal because the outer* ones won't overwrite block or page descriptors of regions added* previously.** Overlapping is only allowed for static regions.*/while (((mm_cursor->base_va + mm_cursor->size - 1U) < end_va)&& (mm_cursor->size != 0U)) {++mm_cursor;}while (((mm_cursor->base_va + mm_cursor->size - 1U) == end_va) &&(mm_cursor->size != 0U) && (mm_cursor->size < mm->size)) {++mm_cursor;}/** Find the last entry marker in the mmap*/mm_last = ctx->mmap;while ((mm_last->size != 0U) && (mm_last < mm_end)) {++mm_last;}/** Check if we have enough space in the memory mapping table.* This shouldn't happen as we have checked in mmap_add_region_check* that there is free space.*/assert(mm_last->size == 0U);/* Make room for new region by moving other regions up by one place */mm_destination = mm_cursor + 1;(void)memmove(mm_destination, mm_cursor,(uintptr_t)mm_last - (uintptr_t)mm_cursor);/** Check we haven't lost the empty sentinel from the end of the array.* This shouldn't happen as we have checked in mmap_add_region_check* that there is free space.*/assert(mm_end->size == 0U);*mm_cursor = *mm;if (end_pa > ctx->max_pa)ctx->max_pa = end_pa;if (end_va > ctx->max_va)ctx->max_va = end_va;
}

啟用MMU

啟用MMU有兩個函數:setup_mmu_cfgenable_mmu_direct_el*。定義了一個與MMU配置寄存器相對應的數組,每個元素都是64位:

/** MMU configuration register values for the active translation context. Used* from the MMU assembly helpers.*/
uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];

setup_mmu_cfg是將轉換上下文中信息存儲到上面的配置寄存器數組中。

void setup_mmu_cfg(uint64_t *params, unsigned int flags,const uint64_t *base_table, unsigned long long max_pa,uintptr_t max_va, int xlat_regime)
{uint64_t mair, ttbr0, tcr;uintptr_t virtual_addr_space_size;/* Set attributes in the right indices of the MAIR. */mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, ATTR_IWBWA_OWBWA_NTR_INDEX);mair |= MAIR_ATTR_SET(ATTR_NON_CACHEABLE, ATTR_NON_CACHEABLE_INDEX);/** Limit the input address ranges and memory region sizes translated* using TTBR0 to the given virtual address space size.*/assert(max_va < ((uint64_t)UINTPTR_MAX));virtual_addr_space_size = (uintptr_t)max_va + 1U;assert(virtual_addr_space_size >=xlat_get_min_virt_addr_space_size());assert(virtual_addr_space_size <= MAX_VIRT_ADDR_SPACE_SIZE);assert(IS_POWER_OF_TWO(virtual_addr_space_size));/** __builtin_ctzll(0) is undefined but here we are guaranteed that* virtual_addr_space_size is in the range [1,UINTPTR_MAX].*/int t0sz = 64 - __builtin_ctzll(virtual_addr_space_size);tcr = (uint64_t)t0sz << TCR_T0SZ_SHIFT;/** Set the cacheability and shareability attributes for memory* associated with translation table walks.*/if ((flags & XLAT_TABLE_NC) != 0U) {/* Inner & outer non-cacheable non-shareable. */tcr |= TCR_SH_NON_SHAREABLE |TCR_RGN_OUTER_NC | TCR_RGN_INNER_NC;} else {/* Inner & outer WBWA & shareable. */tcr |= TCR_SH_INNER_SHAREABLE |TCR_RGN_OUTER_WBA | TCR_RGN_INNER_WBA;}/** It is safer to restrict the max physical address accessible by the* hardware as much as possible.*/unsigned long long tcr_ps_bits = tcr_physical_addr_size_bits(max_pa);if (xlat_regime == EL1_EL0_REGIME) {/** TCR_EL1.EPD1: Disable translation table walk for addresses* that are translated using TTBR1_EL1.*/tcr |= TCR_EPD1_BIT | (tcr_ps_bits << TCR_EL1_IPS_SHIFT);} else if (xlat_regime == EL2_REGIME) {tcr |= TCR_EL2_RES1 | (tcr_ps_bits << TCR_EL2_PS_SHIFT);} else {assert(xlat_regime == EL3_REGIME);tcr |= TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT);}/* Set TTBR bits as well */ttbr0 = (uint64_t) base_table;if (is_armv8_2_ttcnp_present()) {/* Enable CnP bit so as to share page tables with all PEs. */ttbr0 |= TTBR_CNP_BIT;}params[MMU_CFG_MAIR] = mair;params[MMU_CFG_TCR] = tcr;params[MMU_CFG_TTBR0] = ttbr0;
}

首先是設置內存屬性到MAIR寄存器,這里配置設備內存屬性ATTR_DEVICEDevice_nGnRE,即聚合、不重排和提前寫應答;普通內存屬性為兩種:ATTR_NON_CACHEABLE即普通內存、高速緩存的回寫策略為直寫策略、內部無高速緩存,ATTR_IWBWA_OWBWA_NTR即普通內存、內外均直寫策略。

接著設置TCR_ELx寄存器,TCR_ELx 寄存器中的 TnSZ 字段控制虛擬地址空間的大小,其值為64 - 虛地址空間大小;RGN字段控制共享性和緩存性;PS/IPS控制PA或者IPA空間大小。

最后配置TTBR寄存器,存放了頁表的基地址,這里使用了低位虛擬地址空間TTBR0。

enable_mmu_direct_elx是一段匯編實現,將上面的數組配置到相應的MMU寄存器中,然后使能MMU,以enable_mmu_direct_el3為例,實現如下。

	func enable_mmu_direct_\()el\el
#if ENABLE_ASSERTIONS_mrs	x1, sctlr, \eltst	x1, #SCTLR_M_BITASM_ASSERT(eq)
#endif/* Invalidate all TLB entries */tlbi_invalidate_all \elmov	x7, x0adrp	x0, mmu_cfg_paramsadd	x0, x0, :lo12:mmu_cfg_params/* MAIR */ldr	x1, [x0, #(MMU_CFG_MAIR << 3)]_msr	mair, \el, x1/* TCR */ldr	x2, [x0, #(MMU_CFG_TCR << 3)]_msr	tcr, \el, x2/* TTBR */ldr	x3, [x0, #(MMU_CFG_TTBR0 << 3)]_msr	ttbr0, \el, x3/** Ensure all translation table writes have drained into memory, the TLB* invalidation is complete, and translation register writes are* committed before enabling the MMU*/dsb	ishisb/* Set and clear required fields of SCTLR */_mrs	x4, sctlr, \elmov_imm	x5, SCTLR_WXN_BIT | SCTLR_C_BIT | SCTLR_M_BITorr	x4, x4, x5/* Additionally, amend SCTLR fields based on flags */bic	x5, x4, #SCTLR_C_BITtst	x7, #DISABLE_DCACHEcsel	x4, x5, x4, ne_msr	sctlr, \el, x4isbretendfunc enable_mmu_direct_\()el\el

示例

以ARM FVP平臺BL1階段為例,并假設不支持RME。在arm_bl1_plat_arch_setup函數中會創建MMU頁表,并啟用MMU。

void arm_bl1_plat_arch_setup(void)
{...const mmap_region_t bl_regions[] = {MAP_BL1_TOTAL,MAP_BL1_RO,{0}};setup_page_tables(bl_regions, plat_arm_get_mmap());enable_mmu_el3(0);...
}

內存映射區域

頁表創建包括兩種類型:通用內存區域和特定平臺內存區域。

通用內存區域

MAP_BL1_TOTAL定義了BL1可見的所有可信RAM空間,屬性為:普通內存,可讀性,安全。其宏展開如下:

#define MAP_BL1_TOTAL		MAP_REGION_FLAT(			\bl1_tzram_layout.total_base,	\bl1_tzram_layout.total_size,	\MT_MEMORY | MT_RW | EL3_PAS)

MAP_BL1_RO定義了BL1的代碼段內存,屬性為:代碼(普通內存,只讀,可執行),安全。

#define MAP_BL1_RO		MAP_REGION_FLAT(			\BL_CODE_BASE,			\BL1_CODE_END - BL_CODE_BASE,	\MT_CODE | EL3_PAS)

特定平臺內存區域

對于不同的平臺,也需要創建平臺相關的頁表(主要是外設),并映射內存區域。FVP平臺BL1階段的plat_arm_get_mmap()定義為:

/** Table of memory regions for various BL stages to map using the MMU.* This doesn't include Trusted SRAM as setup_page_tables() already takes care* of mapping it.*/
#ifdef IMAGE_BL1
const mmap_region_t plat_arm_mmap[] = {ARM_MAP_SHARED_RAM,V2M_MAP_FLASH0_RO,V2M_MAP_IOFPGA,MAP_DEVICE0,
#if FVP_INTERCONNECT_DRIVER == FVP_CCNMAP_DEVICE1,
#endif
#if TRUSTED_BOARD_BOOT/* To access the Root of Trust Public Key registers. */MAP_DEVICE2,/* Map DRAM to authenticate NS_BL2U image. */ARM_MAP_NS_DRAM1,
#endif{0}
};
#endif

對于ARM_MAP_SHARED_RAM定義了共享內存區域,屬性為:設備內存,讀寫,安全。其展開如下:

#define ARM_MAP_SHARED_RAM	MAP_REGION_FLAT(			\ARM_SHARED_RAM_BASE,		\ARM_SHARED_RAM_SIZE,		\MT_DEVICE | MT_RW | EL3_PAS)

如果使能安全啟動,MAP_DEVICE2定義了訪問設備根公鑰寄存器內存區域,屬性為:設備內存,讀寫,安全。其展開如下:

#define MAP_DEVICE2	MAP_REGION_FLAT(DEVICE2_BASE,			\DEVICE2_SIZE,			\MT_DEVICE | MT_RW | MT_SECURE)

頁表創建

setup_page_tables函數用于創建頁表,定義如下:

/** Set up the page tables for the generic and platform-specific memory regions.* The size of the Trusted SRAM seen by the BL image must be specified as well* as an array specifying the generic memory regions which can be;* - Code section;* - Read-only data section;* - Init code section, if applicable* - Coherent memory region, if applicable.*/void __init setup_page_tables(const mmap_region_t *bl_regions,const mmap_region_t *plat_regions)
{/** Map the Trusted SRAM with appropriate memory attributes.* Subsequent mappings will adjust the attributes for specific regions.*/mmap_add(bl_regions);/* Now (re-)map the platform-specific memory regions */mmap_add(plat_regions);/* Create the page tables to reflect the above mappings */init_xlat_tables();
}

分別將BL區域和平臺自定義區域添加到轉換表中,然后創建頁表,添加映射關系。

啟用MMU

由于BL1處于EL3等級,調用enable_mmu_el3函數,使能MMU。

void enable_mmu_el3(unsigned int flags)
{setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags,tf_xlat_ctx.base_table, MAX_PHYS_ADDR,tf_xlat_ctx.va_max_address, EL3_REGIME);enable_mmu_direct_el3(flags);
}

參考

  1. 萬字長文帶你搞定MMU&TLB&TWU

歡迎關注“安全有理”微信公眾號。

安全有理

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/166844.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/166844.shtml
英文地址,請注明出處:http://en.pswp.cn/news/166844.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring Beans;Spring Bean的生命周期;spring Bean的作用域,spring處理線程并發問題

文章目錄 Spring Beans請解釋Spring Bean的生命周期解釋Spring支持的幾種bean的作用域Spring容器中的bean可以分為5個范圍&#xff1a; Spring如何處理線程并發問題&#xff1f; 在現在的項目開發中經常使用到spring bean&#xff0c;那么來談談spring bean的生命周期&#xff…

APP軟件線上排查方法

在線上環境中排查APP軟件的問題是一項關鍵任務&#xff0c;需要使用一系列方法和工具來識別、定位和解決問題。以下是一些建議的排查方法&#xff0c;希望對大家有所幫助。北京木奇移動技術有限公司&#xff0c;專業的軟件外包開發公司&#xff0c;歡迎交流合作。 1.監控和日志…

linux如何查看文件的hash數值

在Linux系統中&#xff0c;你可以使用各種工具來查看文件的哈希值。下面是一些常見的方法&#xff1a; md5sum命令&#xff1a; md5sum 文件名例如&#xff1a; md5sum example.txtsha1sum命令&#xff1a; sha1sum 文件名例如&#xff1a; sha1sum example.txtsha256sum命令&a…

SQLServer的常用數據類型

常用數據類型 關于數據類型大家可能并不陌生&#xff0c;因為我們在C#中學了常用的數據類型&#xff0c;在數據庫中其實也差不多&#xff0c;大部分都有對應關系的&#xff0c;只是關鍵字上有差別&#xff0c;接下來我們講一下&#xff0c;請大家記住常用的就行。 第一、文本…

代碼規范有用嗎?聽聽100W年薪谷歌大佬怎么說!

谷歌內部的 python 代碼規范 熟悉 python 一般都會努力遵循 pep8 規范&#xff0c;也會有一些公司制定內部的代碼規范。大公司制定規范的目的不是說你一定要怎樣去使用編程語言&#xff0c;而是讓大家遵守同一套規則&#xff0c;節省其他人閱讀代碼的成本&#xff0c;方便協作…

紅酒按照糖含量怎么分類?

我們常聽人們形容葡萄酒為干型或甜型&#xff0c;這指的是葡萄酒的含糖量。不含糖就是干型&#xff0c;含糖少就是半干型&#xff0c;含糖多就是甜型&#xff0c;這是葡萄酒分類的一種——按糖量分。云倉酒莊的品牌雷盛紅酒分享一般分為干型、半干型、半甜型、甜型四種。 云倉…

get data from Nacos error,dataId:服務名

2023-11-23 09:44:35.595 ERROR 169 — [ main] c.a.n.client.config.impl.ClientWorker : [fixed-100.66.12.65_8848] [sub-server-error] no right, dataIdcampaign-task-service, groupcampaign, tenant 2023-11-23 09:44:35.598 ERROR 169 — [ main] c.a.c.n.c.NacosPrope…

Jetson orin(Ubuntu20.04)不接顯示器無法輸出VNC圖像解決辦法以及vnc安裝記錄

sudo apt install vino 好像Jetpack 5.0中已經自帶了。。 配置VNC server: gsettings set org.gnome.Vino prompt-enabled false gsettings set org.gnome.Vino require-encryption false 編輯org.gnome,增加一個“enabled key”的參數&#xff1a; cd /usr/share/glib-2…

氮化鎵的晶體學濕式化學蝕刻法

引言 目前&#xff0c;大多數III族氮化物的加工都是通過干法等離子體蝕刻完成的。干法蝕刻有幾個缺點&#xff0c;包括產生離子誘導損傷和難以獲得激光器所需的光滑蝕刻側壁。干法蝕刻產生的側壁典型均方根(rms)粗糙度約為50納米&#xff0c;雖然已經發現KOH基溶液可以蝕刻AlN…

Android:Google三方庫之Firebase集成詳細步驟(三)

Cloud Messaging 1、清單文件配置 a、&#xff08;可選&#xff09;一項擴展 FirebaseMessagingService 的服務。除了接收通知外&#xff0c;如果您還希望在后臺應用中進行消息處理&#xff0c;則必須添加此服務。例如&#xff0c;您需要在前臺應用中接收通知、接收數據載荷以及…

服務臺需要跟蹤的3個重要指標MTBF+MTTF+MTTR

衡量標準是IT服務管理的核心&#xff0c;可提供有關運營的見解&#xff0c;并幫助確定需要持續改進的領域。通常的服務臺指標有助于展示內部運營效率。例如&#xff0c;衡量在規定時間內解決問題的工單數量的 SLA 是展示服務臺效率的關鍵因素。另一方面&#xff0c;故障指標可幫…

阿里云服務器(vgn7i-vws) anaconda(py39)+pytorch1.12.0(cu113)

安裝anaconda 2022 10 py3.9 wget https://repo.anaconda.com/archive/Anaconda3-2022.10-Linux-x86_64.sh sha256sum Anaconda3-2022.10-Linux-x86_64.sh #校驗數據完整性 chmod ux Anaconda3-2022.10-Linux-x86_64.sh #添加執行權限 bash Anaconda3-2022.10-Linux-x86_…

ate測試原理及ate測試系統(軟件)知識科普 -納米軟件

ATE(Automatic Test Equipment)測試也叫自動化測試&#xff0c;通過計算機控制測試儀器對被測對象進行測試。以計算機編程代替人工測試&#xff0c;基于測試程序控制儀器并對待測品進行輸入和輸出信號檢測分析&#xff0c;從而判斷待測品的性能是否符合要求。 ATE測試需要根據測…

linux進程調度(一)-進程概述

一、什么是進程 進程是指計算機已運行的程序。程序本身只是指令、數據及其組織形式的描述。進程就是一個程序的執行實例&#xff0c;也就是正在執行的程序。在linux操作系統的中&#xff0c;進程就是一個擔當分配系統資源CPU時間、內存的實體。進程控制的主要功能是對系統中的所…

Kafka報錯under-replicated partitions

1 under-replicated partitions異常原因 Kafka報錯under replicated partitions意味著某些分區的副本數量未達到預期的復制因子。 主要有兩種原因&#xff0c; Broker故障 如果某個Kafka Broker發生故障&#xff0c;導致其中一些分區的副本不再可用&#xff0c;那么這些分區就…

2023年微軟開源八個人工智能項目

自2001年軟件巨頭微軟前首席執行官史蒂夫鮑爾默對開源&#xff08;尤其是Linux&#xff09;發表尖刻言論以來&#xff0c;微軟正在開源方面取得了長足的進步。繼ChatGPT于去年年底發布了后&#xff0c;微軟的整個2023年&#xff0c;大多數技術都是面向開發人員和研究人員公開發…

Towhee介紹

官方網站&#xff1a;Towhee | Home - Towhee Towhee 是一個尖端框架&#xff0c;旨在通過使用基于大型語言模型 &#xff08;LLM&#xff09; 的管道編排來簡化非結構化數據的處理。它具有獨特的優勢&#xff0c;可以從各種非結構化數據類型&#xff08;包括冗長的文本、圖像…

淺談進程與線程

文章目錄 一. 進程&#x1f34e;什么是程序&#xff1f;什么是進程&#xff1f;&#x1f34b;程序的并發性和并行性&#x1f349;進程誕生的原因&#x1f351;PCB 二. 線程&#x1f365;什么是線程&#xff1f;&#x1f366;為什么引入線程&#xff1f; 三. 進程與線程的區別與…

HarmonyOS 設備管理開發:USB 服務開發指導

基本概念 USB 服務是應用訪問底層的一種設備抽象概念。開發者根據提供的 USB API&#xff0c;可以獲取設備列表、控制設備訪問權限、以及與連接的設備進行數據傳輸、控制命令傳輸等。 運作機制 USB 服務系統包含 USB API、USB Service、USB HAL。 圖 1 USB 服務運作機制 ●…

【SpringBoot3+Vue3】五【完】【實戰篇】-前端(配合后端)

目錄 一、環境準備 1、創建Vue工程 2、安裝依賴 2.1 安裝項目所需要的vue依賴 2.2 安裝element-plus依賴 2.2.1 安裝 2.2.2 項目導入element-plus 2.3 安裝axios依賴 2.4 安裝sass依賴 3、目錄調整 3.1 刪除部分默認目錄下文件 3.1.1 src/components下自動生成的…