android启动---lk入口文件crt0.s解析
发布日期:2021-06-30 21:46:49 浏览次数:2 分类:技术文章

本文共 5876 字,大约阅读时间需要 19 分钟。

android启动---lk入口文件crt0.s解析

// .section 伪操作, 用户可以通过.section 伪操作来自定义一个段,每一个段以段名为开始, //以下一个段名或者文件结尾为结束,这里段名是.text.boot。.section ".text.boot"//通过.global把_start声明为一个对链接器可见的全局标识.globl _start//汇编程序缺省入口是 start 标号,也可在连接脚本文件中用 ENTRY 标志指明其它入口点。_start://下面有8种异常情况可以使正常指令顺序中止执行,分别为复位、未定义指令、软件中断、//指令预取中止、数据中止、预留、中断请求、快速中断请求,其中reset在本函数中定义,//其他的在exceptions.s中定义,下面分析reset。	b	reset	b	arm_undefined	b	arm_syscall	b	arm_prefetch_abort	b	arm_data_abort	b	arm_reserved	b	arm_irq	b	arm_fiqreset://lk/makefile定义ENABLE_TRUSTZONE := 0没有使能TRUSTZONE(信任区)。#ifdef ENABLE_TRUSTZONE	/*Add reference to TZ symbol so linker includes it in final image */	ldr r7, =_binary_tzbsp_tzbsp_bin_start#endif	/* do some cpu setup */#if ARM_WITH_CP15        /* Read SCTLR *//*Mrc(Move to ARM Register from Coprocessor)指令是将协处理器寄存器的数据传送到ARM处理器寄存器中。P15表示协处理器15(CP15);0表示协处理器操作码opcode1,对于CP15来说这里为0;r0是目的寄存器,是ARM处理器的寄存器;c1和c0为源寄存器,协处理器的寄存器CRn和CRm,CRn寄存器包含第1个 操作数,CRm协处理器中附加的源操作数寄存器或目标寄存器;最后一个0表示协处理器操作码opcode2,如果不需要设置附加信息,将Crm设置为c0。*///CP15执行操作0(opcode1)和0(opcode2),操作数是c1和c0,其操作结果传送到r0 	mrc		p15, 0, r0, c1, c0, 0		/* XXX this is currently for arm926, revist with armv6 cores */		/* new thumb behavior, low exception vectors, i/d cache disable, mmu disabled *///BIC位清除指令,禁用ICache、选择低端异常中断向量(Normal exception vectors selected) //0x00000000-0x0000001C、保持 ARMv5 以上版本的正常功能。	bic		r0, r0, #(1<<15| 1<<13 | 1<<12)//禁用禁止MMU或者PU、禁用一级整体缓存(unified cache,不分代码和数据,都存在一起)/数据缓存(L1 unified/data cache disabled)	bic		r0, r0, #(1<<2 | 1<<0)		/* disable alignment faults *///禁止地址对齐检查	bic		r0, r0, #(1<<1)/* Enable CP15 barriers by default *///使能 26 位地址异常检查,在lk/platform/msm8953/rules.mk定义了ARM_CORE_V8#ifdef ARM_CORE_V8	orr		r0, r0, #(1<<5)#endif/* Write SCTLR *///将上面设置后的ro的值写入到P15的寄存器c1(控制寄存器1)中	mcr		p15, 0, r0, c1, c0, 0#ifdef ENABLE_TRUSTZONE  /*nkazi: not needed ? Setting VBAR to location of new vector table : 0x80000      *///c12用来设置异常向量基地址,这里把要修改的异常向量基地址保存到r0中。 ldr             r0, =0x00080000 mcr             p15, 0, r0, c12, c0, 0#endif#endif/*WITH_CPU_EARLY_INIT在lk/platform/msm8953/rules.mk赋值为0,ENABLE_TRUSTZONE也是0,这段没有调用,暂不关注*/#if WITH_CPU_EARLY_INIT	/* call platform/arch/etc specific init code */#ifndef ENABLE_TRUSTZONE	/* Not needed when TrustZone is the first bootloader that runs.*/	bl __cpu_early_init#endif	/* declare return address as global to avoid using stack */.globl _cpu_early_init_complete	_cpu_early_init_complete:#endif/*ENABLE_NANDWRITE没有定义,WITH_CPU_WARM_BOOT在lk/platform/msm8953/rules.mk赋值为0,,这段没有调用,暂不关注*/#if (!ENABLE_NANDWRITE)#if WITH_CPU_WARM_BOOT	ldr 	r0, warm_boot_tag	cmp 	r0, #1	/* if set, warm boot */	ldreq 	pc, =BASE_ADDR	mov 	r0, #1	str	r0, warm_boot_tag#endif#endif	/* see if we need to relocate *//*在ARM处理器架构中,PC寄存器通常是指向当前指令后的第三条指令地址,即在ARM指令是+8,这里是把PC寄存器指向的指令地址赋值给r0,因为ARM32一条指令4字节,所以r0的值为.Laddr的内存地址。*/	mov		r0, pc//计算出_start的内存地址,即本段代码的加载位置,保存在r0	sub		r0, r0, #(.Laddr - _start).Laddr:	ldr		r1, =_start //加载复位地址到r1/*比较_start与复位地址是否一致,即本段代码是否加载到复位地址。如相等不需要进行代码重定位,调用Lstack_setup设置stack,否则需要继续进行代码重定位。*/	cmp		r0, r1	beq		.Lstack_setup	/* we need to relocate ourselves to the proper spot */	ldr		r2, =__data_end	.Lrelocate_loop:// 进行循环拷贝,将代码段拷贝到复位地址处// ldr把数据从内存加载到寄存器,r3 = *(r0);r0=r0+4;	ldr		r3, [r0], #4//str把数据从寄存器保存到内存中,*r1 = r3;r1=r1+4;	str		r3, [r1], #4	cmp		r1, r2 // 判断拷贝是否完成	bne		.Lrelocate_loop	/* we're relocated, jump to the right address */	ldr		r0, =.Lstack_setup	bx		r0 //重定位完成,此处使用绝对跳转,跳转到正确的地址。//检测热启动的全局变量.ltorg#if WITH_CPU_WARM_BOOTwarm_boot_tag:	.word 0 //分配一个32bit的内存,并初始化为0#endif.Lstack_setup:	/* set up the stack for irq, fiq, abort, undefined, system/user, and lastly supervisor mode */	mrs     r0, cpsr //将程序状态寄存器cpsr内容传送到通用寄存器r0	bic     r0, r0, #0x1f//清除M[4:0],这几位决定处理器的运行模式,比如user、FIQ等。/* 加载内存地址,堆栈向低地址增长 */	ldr		r2, =abort_stack_top //将abort_stack_top的地址赋给r2	orr     r1, r0, #0x12 // irq	msr     cpsr_c, r1 // 设置irq模式//将全局符号irq_save_spot的地址赋给r13	ldr		r13, =irq_save_spot		/* save a pointer to a temporary dumping spot used during irq delivery *//*堆栈指针r13(SP):每一种异常模式都有其自己独立的r13,它通常指向异常模式所专用的堆栈,也就是说五种异常模式、非异常模式(用户模式和系统模式),都有各自独立的堆栈,用不同的堆栈指针来索引。这样当ARM进入异常模式的时候,程序就可以把一般通用寄存器压入堆栈,返回时再出栈,保证了各种模式下程序的状态的完整性*/    	orr     r1, r0, #0x11 // fiq	msr     cpsr_c, r1	mov		sp, r2 //设置fiq模式的堆栈	            	orr     r1, r0, #0x17 // abort	msr     cpsr_c, r1	mov		sp, r2	    	orr     r1, r0, #0x1b // undefined	msr     cpsr_c, r1	mov		sp, r2	    	orr     r1, r0, #0x1f // system	msr     cpsr_c, r1	mov		sp, r2	orr		r1, r0, #0x13 // supervisor	msr		cpsr_c, r1	mov		sp, r2	/* copy the initialized data segment out of rom if necessary *///__data_start_rom,__data_start,__data_end的定义都在system-onesegment.ld中	ldr		r0, =__data_start_rom	ldr		r1, =__data_start	ldr		r2, =__data_end	cmp		r0, r1/*比较__data_start_rom和__data_start的内存地址是否相等,如果相等则跳转到.L__do_bss处,如果不等(也就是没有静态数据),则执行.L__copy_loop:*/	beq		.L__do_bss//静态数据初始化.L__copy_loop:	cmp		r1, r2	ldrlt	r3, [r0], #4	strlt	r3, [r1], #4	blt		.L__copy_loop//完成数据段的拷贝//bss数据段初始化为0 .L__do_bss:	/* clear out the bss */	ldr		r0, =__bss_start	ldr		r1, =_end	mov		r2, #0// 完成bss段的清零.L__bss_loop:	cmp		r0, r1	strlt	r2, [r0], #4	blt		.L__bss_loop#ifdef ARM_CPU_CORTEX_A8	DSB //数据屏障	ISB //指令屏障#endif	bl		kmain //调用lk的main函数	b		.  //死循环.ltorg.bss.align 2	/* the abort stack is for unrecoverable errors.	 * also note the initial working stack is set to here.	 * when the threading system starts up it'll switch to a new 	 * dynamically allocated stack, so we don't need it for very long	 */abort_stack:	.skip 4096 //异常堆栈的大小4096字节abort_stack_top:

参考链接

LK源码解析 1 crt0.s

 

ARM架构参考手册

 

ARM协处理器(CP15)指令介绍

 

ARM协处理器CP15寄存器详解

https://blog.csdn.net/a815064247/article/details/75238312

 

little-kernel分析.md

 

高通(Qualcomm)LK源码深度分析

https://blog.csdn.net/sdkdlwk/article/details/78291496?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control

转载地址:https://loongembedded.blog.csdn.net/article/details/113803471 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:一个好用的开源在线时序图/波形图(Timing Diagram)绘制网站
下一篇:到底什么是5G CPE?

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月09日 07时30分28秒