设为首页 加入收藏

TOP

ARM64启动汇编和内存初始化(上) --- (一)(五)
2023-07-23 13:25:41 】 浏览:131
Tags:ARM64 ---
| PMD_SECT_AF | PMD_SECT_S | PMD_SECT_UXN) #if ARM64_KERNEL_USES_PMD_MAPS #define SWAPPER_MM_MMUFLAGS (PMD_ATTRINDX(MT_NORMAL) | SWAPPER_PMD_FLAGS) //段映射,这里要使用的 #else #define SWAPPER_MM_MMUFLAGS (PTE_ATTRINDX(MT_NORMAL) | SWAPPER_PTE_FLAGS) //页映射 #endif

2.4.4 创建恒等映射

	/*
	 * Create the identity mapping.
	 */
	adrp	x0, idmap_pg_dir                                             ---(1)         
	adrp	x3, __idmap_text_start		// __pa(__idmap_text_start)  ---(2)  

#ifdef CONFIG_ARM64_VA_BITS_52                                               ---(3) 
	mrs_s	x6, SYS_ID_AA64MMFR2_EL1
	and	x6, x6, #(0xf << ID_AA64MMFR2_LVA_SHIFT)
	mov	x5, #52
	cbnz	x6, 1f
#endif
	mov	x5, #VA_BITS_MIN                                             ---(4)                                 
1:
	adr_l	x6, vabits_actual                                            ---(5) 
	str	x5, [x6]
	dmb	sy                                                          //内存屏障
	dc	ivac, x6 // Invalidate potentially stale cache line 把vabits_actual变量对应的缓存给clean掉

	/*
	 * VA_BITS may be too small to allow for an ID mapping to be created
	 * that covers system RAM if that is located sufficiently high in the
	 * physical address space. So for the ID map, use an extended virtual
	 * range in that case, and configure an additional translation level
	 * if needed.
	 *
	 * Calculate the maximum allowed value for TCR_EL1.T0SZ so that the
	 * entire ID map region can be mapped. As T0SZ == (64 - #bits used),
	 * this number conveniently equals the number of leading zeroes in
	 * the physical address of __idmap_text_end.
	 */
	adrp	x5, __idmap_text_end                                           ---(6) 
	clz	x5, x5                     //前导0计数:第一个1前0的个数          ---(6)
	cmp	x5, TCR_T0SZ(VA_BITS_MIN) // default T0SZ small enough?        ---(6)
	b.ge	1f			// .. then skip VA range extension

	adr_l	x6, idmap_t0sz
	str	x5, [x6]
	dmb	sy
	dc	ivac, x6		// Invalidate potentially stale cache line

#if (VA_BITS < 48)
#define EXTRA_SHIFT	(PGDIR_SHIFT + PAGE_SHIFT - 3)
#define EXTRA_PTRS	(1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT))

	/*
	 * If VA_BITS < 48, we have to configure an additional table level.
	 * First, we have to verify our assumption that the current value of
	 * VA_BITS was chosen such that all translation levels are fully
	 * utilised, and that lowering T0SZ will always result in an additional
	 * translation level to be configured.
	 */
#if VA_BITS != EXTRA_SHIFT
#error "Mismatch between VA_BITS and page size/number of translation levels"
#endif

	mov	x4, EXTRA_PTRS
	create_table_entry x0, x3, EXTRA_SHIFT, x4, x5, x6
#else
	/*
	 * If VA_BITS == 48, we don't have to configure an additional
	 * translation level, but the top-level table has more entries.
	 */
	mov	x4, #1 << (PHYS_MASK_SHIFT - PGDIR_SHIFT)
	str_l	x4, idmap_ptrs_per_pgd, x5
#endif
1:
	ldr_l	x4, idmap_ptrs_per_pgd                                       ---(7) 
	adr_l	x6, __idmap_text_end		// __pa(__idmap_text_end)    ---(8) 

	map_memory x0, x1, x3, x6, x7, x3, x4, x10, x11, x12, x13, x14       ---(9) 
  1. 将加载idmap_pg_dir的物理地址x0寄存器idmap_pg_dir是恒等映射的一级页表起始地址,其定义在vmlinux.lds.S链接文件中
	idmap_pg_dir = .;
	. += IDMAP_DIR_SIZE;
	idmap_pg_end = .;

??这里分配给idmap_pg_dir的页面大小为IDMAP_DIR_SIZE,而IDMAP_DIR_SIZE实现在arch/arm64/include/asm/kernel-pgtable.h头文件中,通常是3个连续的大小为4K页面。计算参考如下:

<1>#arch/arm64/include/asm/pgtable-hwdef.h
/*
 * Number of page-table levels required to address 'va_bits' wide
 * address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
 * bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
 *
 *  levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
 *
 * where DIV_ROUND_UP(n, d) => (((n) + (d) - 1) / (d))
 *
 * We cannot include linux/kernel.h which defines DIV
首页 上一页 2 3 4 5 6 7 8 下一页 尾页 5/8/8
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇沁恒 CH32V208(一): CH32V208WBU6.. 下一篇微控制器实时操作系统实践5选择IDE

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目