Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1255523
  • 博文数量: 261
  • 博客积分: 4196
  • 博客等级: 上校
  • 技术积分: 3410
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-17 17:05
文章分类

全部博文(261)

文章存档

2018年(1)

2017年(22)

2016年(2)

2015年(8)

2014年(27)

2013年(40)

2012年(161)

分类: 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 的这部分源码改了

阅读(997) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~