首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Android arm Linux Kernel启动流程(4)

Android arm Linux Kernel启动流程(4)

可以看到我们最开始的section就是.start,所以我们是从start段开始执行的。ELF对程序的入口地址是有定义的,这可以参照*.lds的语法规则里面有描述,分别是GNU LD的-E ---> *.lds里面的ENTRY定义  ---> start Symbol  ---> .text section --->0。在这里是没有这些判断的,因为还没有操作系统,bootloader会直接跳到这个start的地址开始执行。
在这里稍微带一句,如果觉得head.S看的不太舒服的话,比如有些跳转并不知道意思,可以直接objdump vmlinx来看,dump出来的汇编的流程就比较清晰了。
1:      mov r7, r1          @ save architecture ID
        mov r8, r2          @ save atags pointer
#ifndef __ARM_ARCH_2__
        /*
         * Booting from Angel - need to enter SVC mode and disable
         * FIQs/IRQs (numeric definitions from angel arm.h source).
         * We only do this if we were in user mode on entry.
         */
        mrs r2, cpsr        @ get current mode
        tst r2, #3          @ not user?
        bne not_angel       @ 如果不是
        mov r0, #0x17       @ angel_SWIreason_EnterSVC
        swi 0x123456        @ angel_SWI_ARM
not_angel:
        mrs r2, cpsr        @ turn off interrupts to
        orr r2, r2, #0xc0       @ prevent angel from running
        msr cpsr_c, r2
上面首先保存r1和r2的值,然后进入超级用户模式,并关闭中断。
        .text
        adr r0, LC0
        ldmia   r0, {r1, r2, r3, r4, r5, r6, ip, sp}
        subs    r0, r0, r1      @ calculate the delta offset
                        @ if delta is zero, we are
        beq not_relocated       @ running at the address we
                        @ were linked at.
这里首先判断LC0当前的运行地址和链接地址是否一样,如果一样就不需要重定位,如果不一样则需要进行重定位。这里肯定是不相等的,因为我们可以通过objdump看到LC0的地址是0x00000138,是一个相对地址,然后adr r0, LC0 实际上就是将LC0当前的运行地址,而我们直接跳到ZTEXTADDR跑的,实际上PC里面现在的地址肯定是0x00208000以后的一个值,adr r0, LC0编译之后实际上为add r0, pc, #208,这个208就是LC0到.text段头部的偏移。
        add r5, r5, r0
        add r6, r6, r0
        add ip, ip, r0
继承事业,薪火相传
返回列表