设为首页 加入收藏

TOP

ARM64启动汇编和内存初始化(中) --- (二)(三)
2023-07-23 13:31:20 】 浏览:207
Tags:ARM64 ---
2) #ifdef CONFIG_RELOCATABLE #ifdef CONFIG_RELR mov x24, #0 // no RELR displacement yet #endif bl __relocate_kernel #ifdef CONFIG_RANDOMIZE_BASE ldr x8, =__primary_switched adrp x0, __PHYS_OFFSET blr x8 /* * If we return here, we have a KASLR displacement in x23 which we need * to take into account by discarding the current kernel mapping and * creating a new one. */ pre_disable_mmu_workaround msr sctlr_el1, x20 // disable the MMU isb bl __create_page_tables // recreate kernel mapping tlbi vmalle1 // Remove any stale TLB entries dsb nsh isb set_sctlr_el1 x19 // re-enable the MMU bl __relocate_kernel #endif #endif ldr x8, =__primary_switched //x8 = __primary_switched编译后的链接地址,即虚拟地址【重点关注】 adrp x0, __PHYS_OFFSET //_text的值(kernel image存放的物理地址) br x8 //无条件跳转到芯片支持的所有地址范围,dst→x8 ---(2.6.3) SYM_FUNC_END(__primary_switch)

2.6.1 内核地址空间布局随机化

??主要是为了防止黑客的攻击,在早期阶段内核镜像映射到虚拟地址空间的地址是固定的,黑客利用这个特性很容易进行攻击。

2.6.2 打开MMU

/*
 * Enable the MMU.
 *
 *  x0  = SCTLR_EL1 value for turning on the MMU.  //2.5.11
 *  x1  = TTBR1_EL1 value                          //2.6
 *
 * Returns to the caller via x30/lr. This requires the caller to be covered
 * by the .idmap.text section.
 *
 * Checks if the selected granule size is supported by the CPU.
 * If it isn't, park the CPU
 */
SYM_FUNC_START(__enable_mmu)
	mrs	x2, ID_AA64MMFR0_EL1                     //
	ubfx	x2, x2, #ID_AA64MMFR0_TGRAN_SHIFT, 4     //假设我们定义了CONFIG_ARM64_4K_PAGES:这里就是ID_AA64MMFR0_EL1.TGran4域(bits [31:28])的值赋值给x2寄存器
	cmp     x2, #ID_AA64MMFR0_TGRAN_SUPPORTED_MIN    //ID_AA64MMFR0_TGRAN_SUPPORTED_MIN=0
	b.lt    __no_granule_support                     //非法粒度
	cmp     x2, #ID_AA64MMFR0_TGRAN_SUPPORTED_MAX    //ID_AA64MMFR0_TGRAN_SUPPORTED_MIN=7
	b.gt    __no_granule_support                     //非法粒度
	update_early_cpu_boot_status 0, x2, x3           //把0写入到全局变量__early_cpu_boot_status中
	adrp	x2, idmap_pg_dir                         //加载idmap_pg_dir的物理地址到x2寄存器,idmap_pg_dir是恒等映射的一级页表起始地址【重点关注,下面TTBR0会用这个值】                        
	phys_to_ttbr x1, x1                              //对于48bit不进行操作
	phys_to_ttbr x2, x2                              //对于48bit不进行操作
	msr	ttbr0_el1, x2			         // load TTBR0:Translation Table Base Register 0 (EL1)
	offset_ttbr1 x1, x3
	msr	ttbr1_el1, x1			         // load TTBR1:Translation Table Base Register 0 (EL1)
	isb

	set_sctlr_el1	x0                               //打开mmu

	ret
SYM_FUNC_END(__enable_mmu)

2.6.3 __primary_switched

??此时MMU已经打开,我们运行在虚拟地址空间内。

/*
 * The following fragment of code is executed with the MMU enabled.
 *
 *   x0 = __PHYS_OFFSET
 */
SYM_FUNC_START_LOCAL(__primary_switched)
	adr_l	x4, init_task                  
	init_cpu_task x4, x5, x6                //                          ---(1)

	adr_l	x8, vectors			// load VBAR_EL1 with virtual
	msr	vbar_el1, x8			// vector table address     ---(2)
	isb

	stp	x29, x30, [sp, #-16]!           //                          ---(3)
	mov	x29, sp

	str_l	x21, __fdt_pointer, x5		// Save FDT pointer         ---(4)

	ldr_l	x4, kimage_vaddr		// Save the offset between
	sub	x4, x4, x0			// the kernel virtual and
	str_l	x4, kimage_voffset, x5		// physical mappings        ---(5)

	// Clear BSS                                                        ---(6)
        adr_l   x0, __bss_start // 起始地址
        mov x1, xzr             // 要写入的值,xzr是一个特殊的寄存器,值为64位的0
        adr_l   x2, __bss_stop  // 结束地址
        sub x2, x2, x0          // size = __bss_stop - __bss_start
        bl  __pi_memset         // memset(x0, x1, x2)
        dsb ishst               // Make zero page visible to PTW

#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
	bl	kasan_early_init
#endif
	mov	x0, x21				// pass FDT address in x0
	bl	early_fdt_map			// Try mapping the FDT early ---(7)
	bl	init_feature_override		// Parse cpu feature overrides 根
首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇STM32F7xx外设驱动6-adc(寄存器) 下一篇FreeRtos于嵌入式环境的应用

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目