linux启动之前那些事

1. ZRELADDR指的是解压后内核的位置,这个位置其实就是内核编译时链接的地址(和内核所在的物理地址相差一个偏移)。ZTEXTADDR指的是压缩镜像和head.s及misc.o等链接后生成的可执行文件地址。这个地址如果是在nor flash中执行则需要设置相应的地址,如果在ram中执行,则设置成0即可,因为其.got中的符号会做重定位。这个工作是在linux自解压代码中实现的(head.s)

 

2.原始内核镜像(去除调试等额外信息)压缩后piggy.gz被包含在一个piggy.s中-->piggy.o&head.o&misc.o&vmlinux.ld-->zImage-->uImage

 

3.mkimage -a addr1 -e addr2    addr1指的是uImage的加载地址,addr2指的是zImage的入口,这两个地址的设置和uboot的bootm地址有关系,uboot是这样处理的,启动时会检查0x40大小的头信息中addr1,如果和启动地址相同则不会搬移zImage,然后在addr2地址直接启动。如果不同则把启动地址去掉0x40字节后的镜像复制到addr1指定的地方然后启动(也是addr2)。


1)如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag建议是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。


2)如果使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootm xxxx 这个指定的地址xxxx是否与-a指定的加载地址相同。


(1)如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之
(2)如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部。


#1当bootm xxx中的xxx地址与内核的入口地址不相同时,会从xxx地址提取64byte的头部,对其分析,然后去掉头部64byte,然后将内核复制到-a指定的地址处,这种情况下,-a加载地址和-e的入口地址应该相同。


 #2当bootm xxx中xxx地址与内核加载地址相同时,此时会在内核入口地址处读,-e的入口地址比-a的加载地址多64byte

 

4.uboot完成自己的使命后进入zImage的head.s开始执行,简单的说就是判断以ZRELADDR地址解压后会不会和当前的代码空间冲突,如果是则需要搬移自身代码,重定位自身的符号,然后解压(解压在搬移自身代码之前,解压到一个合适的位置)并搬移到ZRELADDR地址,然后进入真正的内核执行,在此之后linux启动的大幕开始了。


你可能感兴趣的:(工作,linux,Flash)