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

Android arm Linux Kernel启动流程(6)

Android arm Linux Kernel启动流程(6)

这个过程是判断我们解压出的vmlinx会不会覆盖原来的zImage,这里的final kernel address就是解压后的kernel要存放的地址,而start of this image则是zImage在内存中的地址。根据我们前面的分析,现在这两个地址是重复的,即都是0x00208000。同样r2是我们申请的一段内存空间,因为他是在sp上申请的,而根据vmlinx.lds我们知道stack实际上处与vmlinx的最上面,所以r4>=r2是不可能的,这里首先计算zImage的大小,然后判断r4+r3是不是比r5小,很明显r4和r5的值是一样的,所以这里先将r2的值赋给r0,经kernel先解压到s申请的内存空间上面,具体的解压过程就不描述了,定义在misc.c里面。(这里我所说的上面是指内存地址的高地址,默认载入的时候从低地址往高地址写,所以从内存低地址开始运行,stack处于最后面,所以成说是最上面)
* r0     = decompressed kernel length
* r1-r3  = unused
* r4     = kernel execution address
* r5     = decompressed kernel start
* r6     = processor ID
* r7     = architecture ID
* r8     = atags pointer
* r9-r14 = corrupted
*/
        add r1, r5, r0      @ end of decompressed kernel
        adr r2, reloc_start
        ldr r3, LC1
        add r3, r2, r3
1:      ldmia   r2!, {r9 - r14}     @ copy relocation code
        stmia   r1!, {r9 - r14}
        ldmia   r2!, {r9 - r14}
        stmia   r1!, {r9 - r14}
        cmp r2, r3
        blo 1b
        add sp, r1, #128        @ relocate the stack
        bl  cache_clean_flush
        add pc, r5, r0      @ call relocation code
因为没有将kernel解压在要求的地址,所以必须重定向,说穿了就是要将解压的kernel拷贝到正确的地址,因为正确的地址与zImage的地址是重合的,而要拷贝我们又要执行zImage的重定位代码,所以这里首先将重定位代码reloc_start拷贝到vmlinx上面,然后再将vmlinx拷贝到正确的地址并覆盖掉zImage。这里首先计算出解压后的vmlinux的高地址放在r1里面,r2存放着重定位代码的首地址,r3存放着重定位代码的size,这样通过拷贝就将reloc_start移动到vmlinx后面去了,然后跳转到重定位代码开始执行。
/*
* All code following this line is relocatable.  It is relocated by
* the above code to the end of the decompressed kernel image and
* executed there.  During this time, we have no stacks.
*
* r0     = decompressed kernel length
* r1-r3  = unused
* r4     = kernel execution address
* r5     = decompressed kernel start
* r6     = processor ID
* r7     = architecture ID
* r8     = atags pointer
* r9-r14 = corrupted
*/
        .align  5
reloc_start:    add r9, r5, r0
        sub r9, r9, #128        @ do not copy the stack
        debug_reloc_start
        mov r1, r4
1:
        .rept   4
        ldmia   r5!, {r0, r2, r3, r10 - r14}    @ relocate kernel
        stmia   r1!, {r0, r2, r3, r10 - r14}
        .endr
        cmp r5, r9
        blo 1b
        add sp, r1, #128        @ relocate the stack
        debug_reloc_end
call_kernel:    bl  cache_clean_flush
        bl  cache_off
        mov r0, #0          @ must be zero
        mov r1, r7          @ restore architecture number
        mov r2, r8          @ restore atags pointer
        mov pc, r4          @ call kernel
继承事业,薪火相传
返回列表