Chinaunix首页 | 论坛 | 博客
  • 博客访问: 718197
  • 博文数量: 124
  • 博客积分: 3156
  • 博客等级: 中校
  • 技术积分: 1584
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-02 10:29
文章分类

全部博文(124)

文章存档

2012年(3)

2011年(2)

2010年(61)

2009年(34)

2008年(24)

我的朋友

分类: LINUX

2010-02-01 18:07:14

U-Boot-2008.10移植后引导内核(二)
 
    前一篇文章已经叙述完了引导内核的整个过程,但是对其中几个关键的地方我们还没有进行分析,例如 mkimge 命令中的地址等问题。这些对我们进一步学习很重要,所以我想在这篇文章里和大家一起探讨一下。

(一)mkimage 命令
    对于mkimage命令来说,-a参数后是内核的运行地址(假设为addrA),-e参数后是入口地址(假设为addrB),这两个地址的关系可以是相同,也可以是B=A+0x40 ,我们分开讨论这两种情况。

提示:使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用(tag是用于bootloader和内核之间传递参数的)。bootm命令会首先判断bootm xxxx 这个指定的地址xxxx是否与-a指定的加载地址相同:
   (1)如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之。
   (2)如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部。

 


1. A 等于 B (搬运代码方式)

 

    mkimage -a addrA -e addrA
    这种情况下,我们第一篇文章中介绍的“引导系统实验”的tftp 下载kernel 就一定不能下载到 addrA(addrB)处 。因为由上面的提示可知,那两个地址相同的情况下u-boot并不搬运kernel 代码,也就是没有把header去掉,所以内核无法启动,会直接 RESET。  
    当然也不能下到与 addrA 的地址相距小于 0x40 的地方, 否则搬运的时候会有一些覆盖, 导致搬运后的kernel不完整, bootm的时候,也会 RESET 的。
    由于内核固化到Nand Flash后,在启动的过程中也要读到内存中,所以我们的“引导系统实验”和固化后的启动其实在某阶段上是一致的,因而得出一个结论。

结论:在编译内核的时候,如果 mkimage 命令的 -a 和 -e 后面的地址相同,那表示用搬运代码的方式启动内核,所以我们设置的环境变量 bootcmd 的地址必须与那两个相同的地址有一段距离(应该是大于0x40),这样才能正常启动系统。
如:    mkimage ... -a 0x30008000 -e 0x30008000 ...
   另外 nand read 0x31000000 0x50000 0x00200000;bootm 0x31000000

 


2. B=A+0x40 (不搬运代码方式)

 

    mkimage -a addrA -e addrA+0x40 或者 mkimage -a addrA -x 两个是一回事。-x 的意思是在kernel所在地执行。表示不必搬运代码。
    依上面的提示我们可知,不搬运代码的条件是 bootm 的地址和 mkimage 的 -a 指定的地址相同。所以,在我们的“引导系统实验”中 tftp 下kernel的地址应该是 addrA 处,然后直接 bootm addrA 就可以成功引导了。

结论:在编译内核的时候,如果 mkimage 命令的 -e 后面的地址是 -a 后面的地址加 0x40 ,那表示用不搬运代码的方式启动内核,所以我们设置的环境变量 bootcmd 的地址必须与 -a 后面的地址相同,这样才能正常启动系统。
如:    mkimage ... -a 0x30008000 -e 0x30008040 ...
   另外 nand read 0x30008000 0x50000 0x00200000;bootm 0x30008000

(二)env 参数的修改
    本来以为修改U-Boot代码可以达到修改环境变量的目的,其实不然。依据U-Boot代码中的宏定义(在mini2440.h中)
#define CONFIG_ENV_OFFSET      0x30000 或者(#define CFG_ENV_OFFSET      0x30000)
可知环境变量在NAND FLASH的0x30000处,也就是处于我们的param分区。所以我们在U-Boot中修改环境变量并不起作用,不过第一次启动的时候可能例外,因为此时 Nand Flash 中的数据无效,U-Boot可能会把在U-Boot中设置的环境变量固化到Nand Flash 中。 
 
    env 在 u-boot 中通常有两种存在方式,即在永久性存储介质中( Flash NVRAM等)和在SDRAM中,也可以配置不使用 env 的永久存储方式,但这不常用。u-boot 在启动的时候会将存储在永久性存储介质中的 env 重新定位到 RAM 中,这样可以快速访问。所以如果要修改环境变量的话,只能通过 setenv 设置和通过 saveenv 将 RAM 中的 env 保存到永久性存储介质中。

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