天天看点

IMX6Solo启动流程-Linux 内核启动 四

写在前头

*.版权声明:本篇文章为原创,可随意转载,转载请注明出处,谢谢!另我创建一个QQ群82642304,欢迎加入!

*.目的:整理一下RIotBoard开发板的启动流程,对自己的所学做一个整理总结,本系列内核代码基于linux-3.0.35-imx。

*.备注:整个系列只是对我所学进行总结,记录我认为是关键的点,另我能力有限,难免出现疏漏错误,如果读者有发现请多指正,以免我误导他人!

接上篇分析:

每个寄存器保存的数据注释已经讲明,需要注意的是r0这个寄存器,根据上面的代码,r0寄存器保存的是运行地址与链接地址的偏移量,如果不一致,需要重新计算BSS段、GOT表、堆栈的地址。

上篇讲到为了避免覆盖,内核将自己移动到原位置的上面,所以在RIotBoard上链接地址与运行地址不一致,需要重新计算值。

计算的时候,只要将原来的值加上r0寄存器所保存的偏移量就可以。

wont_overwrite:
/*
 * If delta is zero, we are running at the address we were linked at.
 *   r0  = delta
 *   r2  = BSS start
 *   r3  = BSS end
 *   r4  = kernel execution address
 *   r7  = architecture ID
 *   r8  = atags pointer
 *   r11 = GOT start
 *   r12 = GOT end
 *   sp  = stack pointer
 */
        teq r0, #0
        beq not_relocated    ;如果链接与运行地址一致,就跳过计算,直接跳到清楚BSS段
        add r11, r11, r0
        add r12, r12, r0

        /*
         * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
         * we need to fix up pointers into the BSS region.
         * Note that the stack pointer has already been fixed up.
         */
        add r2, r2, r0
        add r3, r3, r0

        /*
         * Relocate all entries in the GOT table.
         */
:      ldr r1, [r11, #0]       @ relocate entries in the GOT
        add r1, r1, r0      @ table.  This fixes up the
        str r1, [r11], #4       @ C references.
        cmp r11, r12
        blo b
;清除BSS段
not_relocated:  mov r0, #0
:      str r0, [r2], #4        @ clear bss
        str r0, [r2], #4
        str r0, [r2], #4
        str r0, [r2], #4
        cmp r2, r3
        blo b
           

接下代码:

给r0、r1、r2、r3寄存器分布赋值,然后调用decompress_kernel函数。

r0~r3分别是decompress_kernel的4个参数,所以decompress_kernel函数的四个参数分别是内核解压地址、堆栈起始地址、堆栈结束地址以及机器ID

/*
 * The C runtime environment should now be setup sufficiently.
 * Set up some pointers, and start decompressing.
 *   r4  = kernel execution address
 *   r7  = architecture ID
 *   r8  = atags pointer
 */
        mov r0, r4
        mov r1, sp          @ malloc space above stack
        add r2, sp, #0x10000    @ 64k max
        mov r3, r7
        bl  decompress_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
           

decompress_kernel定义在同目录的misc.c中,我就不研究。

执行完这个函数之后,在r4地址开始的就是内核执行文件,也就是arch/arm/boot/Image文件.

接着给r0、r1、r2、r3寄存器分布赋值,这三个值就是Uboot传进来的三个值,最后跳转到r4处。

总结

截至目前,我们分析了内核的自解压代码,主要要理解运行地址与链接地址和镜像的移动,其余的都是水到渠成的事。

参考

暂无

继续阅读