android启动---lk入口文件crt0.s解析
android啟動(dòng)---lk入口文件crt0.s解析
// .section 偽操作, 用戶可以通過(guò).section 偽操作來(lái)自定義一個(gè)段,每一個(gè)段以段名為開(kāi)始, //以下一個(gè)段名或者文件結(jié)尾為結(jié)束,這里段名是.text.boot。 .section ".text.boot" //通過(guò).global把_start聲明為一個(gè)對(duì)鏈接器可見(jiàn)的全局標(biāo)識(shí) .globl _start //匯編程序缺省入口是 start 標(biāo)號(hào),也可在連接腳本文件中用 ENTRY 標(biāo)志指明其它入口點(diǎn)。 _start: //下面有8種異常情況可以使正常指令順序中止執(zhí)行,分別為復(fù)位、未定義指令、軟件中斷、//指令預(yù)取中止、數(shù)據(jù)中止、預(yù)留、中斷請(qǐng)求、快速中斷請(qǐng)求,其中reset在本函數(shù)中定義,//其他的在exceptions.s中定義,下面分析reset。b resetb arm_undefinedb arm_syscallb arm_prefetch_abortb arm_data_abortb arm_reservedb arm_irqb arm_fiqreset: //lk/makefile定義ENABLE_TRUSTZONE := 0沒(méi)有使能TRUSTZONE(信任區(qū))。 #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)指令是將協(xié)處理器寄存器的數(shù)據(jù)傳送到ARM處理器寄存器中。P15表示協(xié)處理器15(CP15);0表示協(xié)處理器操作碼opcode1,對(duì)于CP15來(lái)說(shuō)這里為0;r0是目的寄存器,是ARM處理器的寄存器;c1和c0為源寄存器,協(xié)處理器的寄存器CRn和CRm,CRn寄存器包含第1個(gè) 操作數(shù),CRm協(xié)處理器中附加的源操作數(shù)寄存器或目標(biāo)寄存器;最后一個(gè)0表示協(xié)處理器操作碼opcode2,如果不需要設(shè)置附加信息,將Crm設(shè)置為c0。 */ //CP15執(zhí)行操作0(opcode1)和0(opcode2),操作數(shù)是c1和c0,其操作結(jié)果傳送到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、禁用一級(jí)整體緩存(unified cache,不分代碼和數(shù)據(jù),都存在一起)/數(shù)據(jù)緩存(L1 unified/data cache disabled)bic r0, r0, #(1<<2 | 1<<0)/* disable alignment faults *///禁止地址對(duì)齊檢查bic r0, r0, #(1<<1) /* Enable CP15 barriers by default */ //使能 26 位地址異常檢查,在lk/platform/msm8953/rules.mk定義了ARM_CORE_V8 #ifdef ARM_CORE_V8orr r0, r0, #(1<<5) #endif /* Write SCTLR *///將上面設(shè)置后的ro的值寫(xiě)入到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用來(lái)設(shè)置異常向量基地址,這里把要修改的異常向量基地址保存到r0中。ldr r0, =0x00080000mcr p15, 0, r0, c12, c0, 0 #endif #endif/*WITH_CPU_EARLY_INIT在lk/platform/msm8953/rules.mk賦值為0,ENABLE_TRUSTZONE也是0,這段沒(méi)有調(diào)用,暫不關(guān)注*/ #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沒(méi)有定義,WITH_CPU_WARM_BOOT在lk/platform/msm8953/rules.mk賦值為0,,這段沒(méi)有調(diào)用,暫不關(guān)注*/ #if (!ENABLE_NANDWRITE) #if WITH_CPU_WARM_BOOTldr r0, warm_boot_tagcmp r0, #1/* if set, warm boot */ldreq pc, =BASE_ADDRmov r0, #1str r0, warm_boot_tag #endif #endif/* see if we need to relocate */ /*在ARM處理器架構(gòu)中,PC寄存器通常是指向當(dāng)前指令后的第三條指令地址,即在ARM指令是+8,這里是把PC寄存器指向的指令地址賦值給r0,因?yàn)锳RM32一條指令4字節(jié),所以r0的值為.Laddr的內(nèi)存地址。 */mov r0, pc //計(jì)算出_start的內(nèi)存地址,即本段代碼的加載位置,保存在r0sub r0, r0, #(.Laddr - _start) .Laddr:ldr r1, =_start //加載復(fù)位地址到r1 /*比較_start與復(fù)位地址是否一致,即本段代碼是否加載到復(fù)位地址。如相等不需要進(jìn)行代碼重定位,調(diào)用Lstack_setup設(shè)置stack,否則需要繼續(xù)進(jìn)行代碼重定位。*/cmp r0, r1beq .Lstack_setup/* we need to relocate ourselves to the proper spot */ldr r2, =__data_end .Lrelocate_loop:// 進(jìn)行循環(huán)拷貝,將代碼段拷貝到復(fù)位地址處 // ldr把數(shù)據(jù)從內(nèi)存加載到寄存器,r3 = *(r0);r0=r0+4;ldr r3, [r0], #4 //str把數(shù)據(jù)從寄存器保存到內(nèi)存中,*r1 = r3;r1=r1+4;str r3, [r1], #4cmp r1, r2 // 判斷拷貝是否完成bne .Lrelocate_loop/* we're relocated, jump to the right address */ldr r0, =.Lstack_setupbx r0 //重定位完成,此處使用絕對(duì)跳轉(zhuǎn),跳轉(zhuǎn)到正確的地址。//檢測(cè)熱啟動(dòng)的全局變量 .ltorg #if WITH_CPU_WARM_BOOT warm_boot_tag:.word 0 //分配一個(gè)32bit的內(nèi)存,并初始化為0 #endif.Lstack_setup:/* set up the stack for irq, fiq, abort, undefined, system/user, and lastly supervisor mode */mrs r0, cpsr //將程序狀態(tài)寄存器cpsr內(nèi)容傳送到通用寄存器r0bic r0, r0, #0x1f//清除M[4:0],這幾位決定處理器的運(yùn)行模式,比如user、FIQ等。 /* 加載內(nèi)存地址,堆棧向低地址增長(zhǎng) */ldr r2, =abort_stack_top //將abort_stack_top的地址賦給r2orr r1, r0, #0x12 // irqmsr cpsr_c, r1 // 設(shè)置irq模式 //將全局符號(hào)irq_save_spot的地址賦給r13ldr r13, =irq_save_spot /* save a pointer to a temporary dumping spot used during irq delivery *//* 堆棧指針r13(SP):每一種異常模式都有其自己獨(dú)立的r13,它通常指向異常模式所專用的堆棧,也就是說(shuō)五種異常模式、非異常模式(用戶模式和系統(tǒng)模式),都有各自獨(dú)立的堆棧,用不同的堆棧指針來(lái)索引。這樣當(dāng)ARM進(jìn)入異常模式的時(shí)候,程序就可以把一般通用寄存器壓入堆棧,返回時(shí)再出棧,保證了各種模式下程序的狀態(tài)的完整性 */ orr r1, r0, #0x11 // fiqmsr cpsr_c, r1mov sp, r2 //設(shè)置fiq模式的堆棧orr r1, r0, #0x17 // abortmsr cpsr_c, r1mov sp, r2orr r1, r0, #0x1b // undefinedmsr cpsr_c, r1mov sp, r2orr r1, r0, #0x1f // systemmsr cpsr_c, r1mov sp, r2orr r1, r0, #0x13 // supervisormsr cpsr_c, r1mov sp, r2/* copy the initialized data segment out of rom if necessary */ //__data_start_rom,__data_start,__data_end的定義都在system-onesegment.ld中l(wèi)dr r0, =__data_start_romldr r1, =__data_startldr r2, =__data_endcmp r0, r1 /*比較__data_start_rom和__data_start的內(nèi)存地址是否相等,如果相等則跳轉(zhuǎn)到.L__do_bss處,如果不等(也就是沒(méi)有靜態(tài)數(shù)據(jù)),則執(zhí)行.L__copy_loop:*/beq .L__do_bss//靜態(tài)數(shù)據(jù)初始化 .L__copy_loop:cmp r1, r2ldrlt r3, [r0], #4strlt r3, [r1], #4blt .L__copy_loop//完成數(shù)據(jù)段的拷貝//bss數(shù)據(jù)段初始化為0 .L__do_bss:/* clear out the bss */ldr r0, =__bss_startldr r1, =_endmov r2, #0// 完成bss段的清零 .L__bss_loop:cmp r0, r1strlt r2, [r0], #4blt .L__bss_loop#ifdef ARM_CPU_CORTEX_A8DSB //數(shù)據(jù)屏障ISB //指令屏障 #endifbl kmain //調(diào)用lk的main函數(shù)b . //死循環(huán).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字節(jié) abort_stack_top:參考鏈接
LK源碼解析 1 crt0.s
https://blog.csdn.net/xichangbao/article/details/51484138
?
ARM架構(gòu)參考手冊(cè)
https://developer.arm.com/documentation/ddi0487/ga
?
ARM協(xié)處理器(CP15)指令介紹
https://blog.csdn.net/u012357001/article/details/88989827
?
ARM協(xié)處理器CP15寄存器詳解
https://blog.csdn.net/a815064247/article/details/75238312
?
little-kernel分析.md
https://github.com/hardenedlinux/embedded-iot_profile/blob/master/docs/arm64/dragonboard410c/little-kernel%E5%88%86%E6%9E%90.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
總結(jié)
以上是生活随笔為你收集整理的android启动---lk入口文件crt0.s解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: android lk DEFINES定义
- 下一篇: 一个好用的开源在线时序图/波形图(Tim