上文链接中解释了编译生成镜像过程,本文主要分析内核zImage自解压过程。
zImage包含了自解压程序和内核镜像程序。
自解压程序的链接文件位于 arch/arm/boot/compressed/vmlinux.lds.S
。链接脚本指定了程序入口ENTRY(_start)
。
程序入口位于arch/arm/boot/compressed/head.S
。自解压程序head.S需要确认解压后的内核映像绝对地址。
* (1)定义了CONFIG_AUTO_ZRELADDR
* ZRELADDR是已解压内核最终存放的物理地址
* 如果AUTO_ZRELADDR被选择了, 这个地址将会在运行是确定:
* 将当pc值和0xf8000000做与操作,
* 并加上TEXT_OFFSET(内核最终存放的物理地址与内存起始的偏移)
* 这里假定zImage被放在内存开始的128MB内
* (2)没有定义CONFIG_AUTO_ZRELADDR
* 直接使用zreladdr(此值位于arch/arm/mach-xxx/Makefile.boot文件确定)
也可以在内核编译时指定loadaddr,设置内核的物理地址。例如:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- LOADADDR=0x40008000 uImage -j24
首先检查是否会发生自我覆盖。会发生自我覆盖的情况,会先进行镜像的搬运。