ARM linux解析之压缩内核zImage的启动过程
的重定位后的代码。
blcache_clean_flush
adrr0, BSYM(restart)
addr0, r0, r6
mov pc, r0
这个时候就又会到restart处执行,会把前面的代码再执行一次,不过这次在执行时,会进入图.6所示的代码不用重定位的情况,意料之后的事,接着跳到wont_overwirte执行,如下:
teqr0, #0
beqnot_relocated
这两行代码的意思是,看一下只什么时候跳过来的,如果r0的值为0,说明没有进行代码的重定位,那这个时候跳到no_relocated处执行,这段就会跳过.got符号表的搬移,因为位置没有变啊。代码写得好严谨啊,佩服。
④.我们这种经过代码重定位的情况下,r0的值一定不会零,那么这个时候就要进行.got表的重搬移,如图中所示,代码如下:
1:ldrr1, [r11, #0]@ relocate entries in the GOT
add r1, r1, r0@ table.This fixes up the
strr1, [r11], #4@ C references.
cmpr11, r12
blo 1b
⑤.下面就来初始化我们一直没有进行初始化的.bss段,其实就是清零,位置如图所示。我虽画了一个箭头,但是其实并没有进行任何搬移动作,仅仅清零,代码如下:
not_relocated:movr0, #0
1:strr0, [r2], #4@ clear bss
strr0, [r2], #4
strr0, [r2], #4
strr0, [r2], #4
cmpr2, r3
blo 1b
这里看到我们可爱的not_relocated标号了吧,这个标号就是前面所见到的如果没有进行重定位,就直接跳过来进行bss的初始化。
⑥.设置好64K的解压缓冲区在堆栈之后,代码如下:
mov r0, r4
mov r1, sp@ malloc space above stack
addr2, sp, #0x10@ 64k max
mov r3, r7
⑦.进行内核的解压过程
bldecompress_kernel
arch/arm/boot/compressed/misc.c
voiddecompress_kernel(unsigned longoutput_start, unsigned longfree_mem_ptr_p,
unsigned longfree_mem_ptr_end_p, intarch_id)
这个函数是C下面的函数,那些堆栈的设置啊,.got表啊,64k的解压缓冲啊,都是为它准备的。第一个参数是内核解压后所存放的地址,第二,第三参数是64k解压缓冲起始地址和结束地址,最后一个参数ID号,这个由u-boot传入。
⑧.这是最后一步了,终于到最后一步了。代码如下:
blcache_clean_flush
blcache_off
mov r0, #0@ must be zero
mov r1, r7@ restore architecture number
mov r2, r8@ restore atags pointer
mov pc, r4@ call kernel
这里先进行cache的flush,然后关掉cache,再准备好linux内核要启动的几个参数,最后跳到zreladdr处,进入解压后的内核,到这里压缩内核的使命就完成了。但是它的功劳可不小啊。下面就是真真正正的linux内核的启动过程了,这里会进入到arch/arm/kernel/head.s这个文件的stext这个地址开始执行第一行代码。
ARMlinux解析压缩内核zImage启动过 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)