参考文档:https://blog.csdn.net/haoge921026/article/details/46785995
以下内容基于s5pv210进行分析
zImage由head.o,piggy.gzip.o,misc等链接组成,piggy.gzip.o中包含压缩的内核镜像,zImage的作用实际上就是对内核进行解码。
zImage还是位置无关码,它的链接地址为0,可以在任何地址运行,因为在对其源文件进行编译时编译器参数设置了-fpic,通过反汇编看到编译生成了.got和.got.plt段。.dot.plt为空,查看反汇编得知编译器对c语言函数的调用是通过bl指令实现的,所以c的函数调用是位置无关码;而对于c中全局变量的处理是通过相对寻址找到全局变量一一对应的.got地址(这里的相对寻址是:在每个函数段中如果使用了全局变量都会存放.got首地址相对运行pc的偏移量以及全局变量在.got中的偏移),所以无论运行地址和链接地址匹不匹配,代码都能正确找到全局变量的.got地址。.got地址中存放了全局变量的链接地址,所以只要在zImage的初始化c语言运行环境部分增加对.got部分全局变量的重定位则代码将正确运行,因此zImage成为了位置无关码
现在开始分析arch/arm/boot/compressed/head.s进行代码分析:
start:
.type start,#function //用于指定标号start为函数
.rept 8 //指定.endr以前的指令循环8次
mov r0, r0
.endr
b 1f
.word 0x016f2818 @魔数用于表示zImage的身份
.word start @ zImage的链接地址
.word _edata @ zImage的链接结束地址
1: mov r7, r1 @ save architecture ID
mov r8, r2 @ save atags pointer
#ifndef __ARM_ARCH_2__
/*用于判断是不是angel启动,我们是u-boot启动进来时已经是svc模式了所以直接跳到
not_angel */
mrs r2, cpsr