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

释放双眼,带上耳机,听听看~!

写在前头

*.版权声明:本篇文章为原创,可随意转载,转载请注明出处,谢谢!另我创建一个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处。


总结

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

参考

暂无

给TA打赏
共{{data.count}}人
人已打赏
安全运维

WordPress网站专用docker容器环境带Waf

2020-7-18 20:04:44

安全运维

运维安全-Gitlab管理员权限安全思考

2021-9-19 9:16:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索