mkimage command not found

问题1:编译内核时候提示 mkimage" command not found - U-Boot images will not be built "

解决:

1)将经过编译后的uboot目录中tools目录下的mkimage的路径导入到系统环境变量;

2)将uboot目录中tools目录下的mkimage拷贝到系统usr/bin目录;

分析:

mkimage随着uboot的编译而得到,uboot的tools目录下有mkimage的代码,查看tools下的Makefile文件,看到编译时候使用的CC=$(HOSTCC),又结合ubuntu下通过apt-get install u-boot-tools得到的mkimage,分别用file查看mkimage看到都是x64的,而且uboot的tools目录下的mkimage也可以在ubuntu下运行,所以推测两者是一致的,采用任何一种方法都可以得到,都可以用于后面转化得到uImage。



问题2:make uImage得到的uImage,看到Load Address和Entry Point都是0

联想:在uboot的顶层Makefile中,可以看到$(obj) u-boot.img : $(obj) u-boot.bin

./tools/mkimage -A ... -T... -C ... -a... -e... -n... -d...

这样入口地址将会被传入;


在编译内核时候,make uImage的过程如下:

生成uImage的工具mkimage由arch/arm/boot/Makefile中的MKIMAGE定义:

MKIMAGE := $(srctree)/scripts/mkuboot.sh

mkuboot.sh的作用是去找到是否存在"mkimage",此工具是用来生成最后的uImage。

mkuboot.sh 首先检查toolchain是否拥有mkimage (使用-z来判空),如果没有,再检查系统中是否拥有mkimage;如果没有则报错。

然后调用:$mkimage "$@"


在老版本的内核中,通过mkimage来生成uImage的位置为arch/arm/boot/Makefile中:

  1. quiet_cmd_uimage = UIMAGE  $@  
  2.       cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel /  
  3.            -C none -a $(LOADADDR) -e $(STARTADDR) /  
  4.            -n 'Linux-$(KERNELRELEASE)' -d $< $@  


其中-a 参数的传入通过该Makefile下面语句:

  1. ZERLADDR := $(zreladdr -y)

  2. ifeq ($(CONFIG_ZBOOT_ROM),y)  
  3. $(obj)/uImage: LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT)  
  4. else  
  5. $(obj)/uImage: LOADADDR=$(ZRELADDR)  
  6. endif  


-e参数的传入通过该Makefile的下面语句:

$(obj)/uImage: STARTADDR=$(LOADADDR)


从makefile.boot中传入生成uImage的相关参数(e.g: arm/arm/mach-omap2/Makefile.boot)

  1. ifneq ($(MACHINE),)  
  2. include $(srctree)/$(MACHINE)/Makefile.boot  
  3. endif  


在Makefile.boot中定义了zreladdr -y += 0x80008000


由zImage生成uImage通过该Makefile的下面语句:

  1. $(obj)/uImage:  $(obj)/zImage FORCE  
  2.     $(call if_changed,uimage)  
  3.     @echo '  Image $@ is ready' 

注:zImage的生成过程:http://blog.csdn.net/voice_shen/article/details/17713441

当然,也可以手动的通过 mkimage -A arm -O linux -T kernel -C none -a -e -n -d zImage uImage生成uImage。


关于uImage的启动,注意下面几种情况: 

1> mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 
30008040 -n linux-2.6.18.8 -d zImage uImage2.6.18.8-8040 

使用mkimage生成内核镜像文件,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootm xxxx 这个指定的地址xxxx(download addr)是否与-a指定的加载地址(load adrr)是否相同。
(1)如果不同的话,会从地址xxxx(download addr)开始提取出uImage的64byte的头部,对其进行分析,分析出load addr,然后把去掉头部的内核复制到load addr中,此时因为入口地址(
enter addr)不等于load addr,所以内核启动不起来。

(2)如果相同的话,uImage原封不动的放在那,此时因为-e指定的入口地址为推后64byte,跳过了这64byte的头部。

所以把 uImage download到 30008000的位置上可以启动,否则从 30008040 是启动不了的。

2> mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 
30008000 -n linux-2.6.18.8 -d zImage uImage2.6.18.8-8000 

(1)这种情况download地址随便,因为将加载地址和入口地址设置成同样的地址,在下载到任意地址时,将去掉头部的内核镜像拷贝到指定加载地址后,其实就是从加载地址开始启动。

(2)下载地址和指定加载地址相同,如果 tftp 下载地址==0x30008000 , 此时因为下载地址和指定加载地址相同,所以就不会搬动,内核直接从指定加载地址自解压啦,但是因为指定的入口地址也是0x30008000,还是在镜像头处,可以看到上面的代码,如果相同没有做任何事,只是打印了提示信息,所以还得将入口地址往后推后64个字节还是从 0x30008040 启动就肯定OK 。

 

所以在制作镜像头以及下载地址就有两种情况:

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

加载地址和入口地址相同

tftp 0x31000000 zImage.img

bootm 0x31000000

下载地址可以任意放。

 

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

入口地址在加载地址后面64个字节

tftp 0x30008000 zImage.img

bootm 0x30008000

下载地址一定要在指定的加载地址上



你可能感兴趣的:(编译)