kernel 默认uImage生成:
如果在kernel根目录下执行make uImage会用默认参数执行mkimage
arch/arm/boot/Makefile  62行开始有命令和规则:

quiet_cmd_uimage = UIMAGE  $@ 
      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \ 
           -C none -a $(ZRELADDR) -e $(ZRELADDR) \ 
           -n 'Linux-$(KERNELRELEASE)' -d $< $@
$(obj)/uImage:  $(obj)/zImage FORCE 
    $(call if_changed,uimage) 
    @echo '  Image $@ is ready'
  
上面文件中在24行定义
ZRELADDR    := $(zreladdr-y)

在第17行有
include $(srctree)/$(MACHINE)/Makefile.boot
  
而这个Makefile.boot的中有 
    zreladdr-y  := 0x30008000 
  
所以 ZRELADDR    := 0x30008000

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

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

       关键
a.如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,提供传递参数的tag,然后把去掉头部的内核复制到-a指定的load地址中(没有解压,内核会   自解压)去运行之,
b.如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部(会分析提供传递参数的tag),然后内核自解压启动。

       理解:

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

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


    所以-a 和-e的区别在于,-a用于指定uboot将zImage拷贝到哪里,-e指定拷贝之后从哪里开始运行。

mkimage制作uImage的各个参数意义

-A ==> set architecture to 'arch'

-O ==> set operating system to 'os'

-T ==> set image type to 'type'

-C ==> set compression type 'comp'

-a ==> set load address to 'addr' (hex)

-e ==> set entry point to 'ep' (hex)

-n ==> set image name to 'name'

-d ==> use image data from 'datafile'

-x ==> set XIP (execute in place)

#mkimage -n 'linux-2.6.14' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage zImage.img
Logo

更多推荐