写在前头
*.版权声明:本篇文章为原创,可随意转载,转载请注明出处,谢谢!另我创建一个QQ群82642304,欢迎加入!
*.目的:整理一下RIotBoard开发板的启动流程,对自己的所学做一个整理总结,本系列内核代码基于linux-3.0.35-imx。
*.备注:整个系列只是对我所学进行总结,记录我认为是关键的点,另我能力有限,难免出现疏漏错误,如果读者有发现请多指正,以免我误导他人!
接上篇分析:
每个寄存器保存的数据注释已经讲明,需要注意的是r0这个寄存器,根据上面的代码,r0寄存器保存的是运行地址与链接地址的偏移量,如果不一致,需要重新计算BSS段、GOT表、堆栈的地址。
上篇讲到为了避免覆盖,内核将自己移动到原位置的上面,所以在RIotBoard上链接地址与运行地址不一致,需要重新计算值。
计算的时候,只要将原来的值加上r0寄存器所保存的偏移量就可以。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 1
2wont_overwrite:
3/*
4 * If delta is zero, we are running at the address we were linked at.
5 * r0 = delta
6 * r2 = BSS start
7 * r3 = BSS end
8 * r4 = kernel execution address
9 * r7 = architecture ID
10 * r8 = atags pointer
11 * r11 = GOT start
12 * r12 = GOT end
13 * sp = stack pointer
14 */
15 teq r0, #0
16 beq not_relocated ;如果链接与运行地址一致,就跳过计算,直接跳到清楚BSS段
17 add r11, r11, r0
18 add r12, r12, r0
19
20 /*
21 * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
22 * we need to fix up pointers into the BSS region.
23 * Note that the stack pointer has already been fixed up.
24 */
25 add r2, r2, r0
26 add r3, r3, r0
27
28 /*
29 * Relocate all entries in the GOT table.
30 */
311: ldr r1, [r11, #0] @ relocate entries in the GOT
32 add r1, r1, r0 @ table. This fixes up the
33 str r1, [r11], #4 @ C references.
34 cmp r11, r12
35 blo 1b
36;清除BSS段
37not_relocated: mov r0, #0
381: str r0, [r2], #4 @ clear bss
39 str r0, [r2], #4
40 str r0, [r2], #4
41 str r0, [r2], #4
42 cmp r2, r3
43 blo 1b
44
接下代码:
给r0、r1、r2、r3寄存器分布赋值,然后调用decompress_kernel函数。
r0~r3分别是decompress_kernel的4个参数,所以decompress_kernel函数的四个参数分别是内核解压地址、堆栈起始地址、堆栈结束地址以及机器ID
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 1/*
2 * The C runtime environment should now be setup sufficiently.
3 * Set up some pointers, and start decompressing.
4 * r4 = kernel execution address
5 * r7 = architecture ID
6 * r8 = atags pointer
7 */
8 mov r0, r4
9 mov r1, sp @ malloc space above stack
10 add r2, sp, #0x10000 @ 64k max
11 mov r3, r7
12 bl decompress_kernel
13 bl cache_clean_flush
14 bl cache_off
15 mov r0, #0 @ must be zero
16 mov r1, r7 @ restore architecture number
17 mov r2, r8 @ restore atags pointer
18 mov pc, r4 @ call kernel
19
decompress_kernel定义在同目录的misc.c中,我就不研究。
执行完这个函数之后,在r4地址开始的就是内核执行文件,也就是arch/arm/boot/Image文件.
接着给r0、r1、r2、r3寄存器分布赋值,这三个值就是Uboot传进来的三个值,最后跳转到r4处。
总结
截至目前,我们分析了内核的自解压代码,主要要理解运行地址与链接地址和镜像的移动,其余的都是水到渠成的事。
参考
暂无