分类: LINUX
2014-12-05 14:36:43
supervivi和uboot支持的内核格式是不相同的。用supervivi烧写内核时,烧写的是zImage文件,而用uboot烧写时经过处理后的image文件:zImage.img,这个文件与zImage相比是多了一个文件头部,是zImage文件经过uboot的mkimage工具而生成的。所以,supervivi和uboot不能加载相同的内核文件
由于uboot 只能用来启动uImage,不能启动zImage,因此当内核编译结束生成zImage 镜像文件后,还需要进一步制作uImage 镜像.
制作uboot 时,在uboot 的tools 目录下会生成mkimage 工具,约52kB.
将tools 目录下生成的mkimage 文件拷贝到/bin 目录中.
# cp u-boot/tools/mkimage /bin
然后到了编译linux内核的地方
make uImage
[root@localhost linux-2.6.32.2]# make uImage
CHK include/linux/version.h
make[1]: “include/asm-arm/mach-types.h”是最新的。
CHK include/linux/utsrelease.h
SYMLINK include/asm -> include/asm-arm
CALL scripts/checksyscalls.sh
CHK include/linux/compile.h
Kernel: arch/arm/boot/Image is ready
Kernel: arch/arm/boot/zImage is ready
UIMAGE arch/arm/boot/uImage
Image Name: Linux-2.6.32.2-FriendlyARM
Created: Fri Dec 5 14:47:10 2014
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2266644 Bytes = 2213.52 kB = 2.16 MB
Load Address: 30008000
Entry Point: 30008000
Image arch/arm/boot/uImage is ready
这样uImage就编译好了
这样编译出来的 内核,由于 Load Address Entry Point 都是同样的地址,在加载的时候有可能出现问题,因为 uImage 是加了一个64 byte的信息头,供建立tag 之用。所以Entry Point 要设为30008040 。用如下命令
mkimage -n 'linux-2.6.34.7' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage uImage
也可以在linux 源代码里修改 uImage 的生成方式 用 make uImage 来制作
使用mkimage 生成的内核镜像文件,bootm 命令 首先会判断bootm xxxx 这个指令地址xxxx是否与-a 指定的load address地址是否相同
如果相同,就原封不动的放在那个地址,但在-e 的entry address 会推后64 byte ,来跳过这64 byte 的头部。
如果不同,会从这个地址开始提取64 byte 的头部,对其进行分析,然后把去掉头部的内核复制到-a 指定的load address 去运行
具体细节可参看uboot代码common/cmd_bootm.c中bootm_load_os函数的实现:
switch (comp) {
case IH_COMP_NONE:
if (load == blob_start || load == image_start) {
printf(" XIP %s ... ", type_name);
no_overlap = 1;
} else {
printf(" Loading %s ... ", type_name);
memmove_wd((void *)load, (void *)image_start,
image_len, CHUNKSZ);
}
*load_end = load + image_len;
puts("OK\n");
break;
以上方法都源于网络上说的,我自己在使用时的实际情况如下,开发板用的友善之臂mini2440 uboot 用的友善之臂提供的tekk 的。具体分为两种情况
一、制作uImage的时候,
Load Address: 30008000
Entry Point: 30008000
load addres 和 entry point 相同,如上。
load addres 和 entry point 不相同,相差0x40,如下
Load Address: 30008000
Entry Point: 30008040
在uboot 的环境参数设置为(bootcmd=nand read.i xxxx 60000 500000;bootm yyyy)
bootcmd=nand read.i 0x30007fc0 60000 500000;bootm 0x30008000 或者 bootcmd=nand read.i 0x30008000 60000 500000;bootm 0x30008040
其中 nand read 地址 xxxx 和 yyyy 要相差0x40 。即 xxxx + 0x40 = yyyy .xxxx可以为任意可用的地址,比如 0x31000000
就可以启动,换成其他的都会有问题。
可能是uboot 的这部分源码改了