1、设置kernel/arch/arm/Makefile文件中的
TEXTADDR = 0xC0008000
内核启动的虚拟地址
2、设置kernel/arch/arm/boot/Makefile文件中的
ZRELADDR = 0xa0008000
内核启动的物理地址
如果需要从flash中启动还需要设置
ZTEXTADDR地址。
linux启动分析(3)---内核解压缩过程
内核压缩和解压缩代码都在目录kernel/arch/arm/boot/compressed,
编译完成后将产生vmlinux、head.o、misc.o、head-xscale.o、piggy.o这几个文件,
head.o是内核的头部文件,负责初始设置;
misc.o将主要负责内核的解压工作,它在head.o之后;
head-xscale.o文件主要针对Xscale的初始化,将在链接时与head.o合并;
piggy.o是一个中间文件,其实是一个压缩的内核(kernel/vmlinux),只不过没有和初始化文件及解压文件链接而已;
vmlinux是(没有--lw:zImage是压缩过的内核)压缩过的内核,就是由piggy.o、head.o、misc.o、head-xscale.o组成的。
在BootLoader完成系统的引导以后并将Linux内核调入内存之后,调用bootLinux(),
这个函数将跳转到kernel的起始位置。如果kernel没有压缩,就可以启动了。
如果kernel压缩过,则要进行解压,在压缩过的kernel头部有解压程序。
压缩过得kernel入口第一个文件源码位置在arch/arm/boot/compressed/head.S。
它将调用函数decompress_kernel(),这个函数在文件arch/arm/boot/compressed/misc.c中,
decompress_kernel()又调用proc_decomp_setup(),arch_decomp_setup()进行设置,
然后使用在打印出信息“Uncompressing Linux...”后,调用gunzip()。将内核放于指定的位置。
以下分析head.S文件:
(1)对于各种ArmCPU的DEBUG输出设定,通过定义宏来统一操作。
(2)设置kernel开始和结束地址,保存architecture ID。
(3)如果在ARM2以上的CPU中,用的是普通用户模式,则升到超级用户模式,然后关中断。
(4)分析LC0结构delta offset,判断是否需要重载内核地址(r0存入偏移量,判断r0是否为零)。
这里是否需要重载内核地址,我以为主要分析arch/arm/boot/Makefile、arch/arm/boot/compressed/Makefile
和arch/arm/boot/compressed/vmlinux.lds.in三个文件,主要看vmlinux.lds.in链接文件的主要段的位置,
LOAD_ADDR(_load_addr)=0xA0008000,而对于TEXT_START(_text、_start)的位置只设为0,BSS_START(__bss_start)
=ALIGN(4)。
对于这样的结果依赖于,对内核解压的运行方式,也就是说,内核解压前是在内存(RAM)中还是在FLASH上,
因为这里,我们的BOOTLOADER将压缩内核(zImage)移到了RAM的0xA0008000位置,我们的压缩内核是在内存(RAM)从
0xA0008000地址开始顺序排列,
因此我们的r0获得的偏移量是载入地址(0xA0008000)。接下来的工作是要把内核镜像的相对地址转化为内存的物理地址,即
重载内核地址。
(5)需要重载内核地址,将r0的偏移量加到BSS region和GOT table中。
(6)清空bss堆栈空间r2-r3。