关于RTEMS MINI2440的QEMU仿真从UBOOT加载问题的研究

恩,首先要感谢 Rickleaf, 介绍 QEMU 仿真 MINI2440 的方案给我,并且将MINI2440移植好的bsp分享给我。使我工作速度大大增加。

以下是他的一篇移植 rtems4.9.5 到 qemu 上的文章。

http://blog.csdn.net/rickleaf/archive/2011/03/16/6254361.aspx

 

当时虽然能运行,但是使用gdb加载的方式。而不是使用uboot的加载方式。uboot的加载方式一直有问题。

Rickleaf研究了一下,发现加载和启动地址都是 0x30000100。详见博文:

 

http://blog.csdn.net/rickleaf/archive/2011/03/18/6260292.aspx

 

但对于这篇文章所说的原因:

 

/------------------------------以下文字摘自rickleaf的博客---------------------------------------/

2.探究原因

原来转换成bin文件以后,entry前面的伪指令是没有的,

想想也对,不烧到那里不就预留了吗?:-)

/------------------------------以上文字摘自rickleaf的博客---------------------------------------/

 

个人对这个原因持不同意见。我做了如下的工作:

首先,使用编译好的mini2440的bsp编译hello_world_c示例。官方带的。编译成功后,在hello_world_c下的o-optimize下有一个hello.num文件。这个是hello.exe(实际上是elf格式)中的符号位置。其中前22行是:

 

         w _Jv_RegisterClasses
         w __deregister_frame_info
         w __register_frame_info
00000100 A _abt_stack_size
00000400 A _fiq_stack_size
00001000 A _irq_stack_size
00001000 A _svc_stack_size
04000000 A _sdram_size
30000000 A _sdram_base
30000000 B arm_exception_table
30000000 B arm_reset_vect
30000004 B arm_undef_vect
30000008 B arm_swi_vect
3000000c B arm_iabrt_vect
30000010 B arm_dabrt_vect
30000018 B arm_irq_vect
3000001c B arm_fiq_vect
30000020 B rtems_vector_table
30000040 B bsp_vector_table

30000100 T _axf_text_start
30000100 T _start
3000026c T Reset_Handler

 

从0x3000 0000 地址到 0x3000 0040 地址我们看到都是有东西的。并且符号是B。B是什么,查阅官方文档是:

该符号的值出现在非初始化数据段(bss)中。例如,在一个文件中定义全局static int test。则该符号test的类型为b,位于bss section中。其值表示该符号在bss段中的偏移。一般而言,bss段分配于RAM中。

 

原来 arm_exception_table、arm_reset_vect 就是一个静态的全局变量,但没有初始化。恩,那我使用arm_reset_vect搜索整个bsp的代码,并没有发现代码中对这个变量进行初始化或声明。 《using ld》 文档对这个问题的描述是,在连接脚本里可以使用赋值语句申明一些全局变量。以下是我翻译的关于表达式这段的原文:

 

 

 

 

既然是在连接脚本中定义的,那我们就去看看mini2440的rtems连接脚本。我把rickleaf写的脚本前90行贴出来了。

 

从连接脚本上看,sdram的地址从0x3000 0000 开始,首先放置的是.base段,.base段占用 0x100 个字节。实际上没那么多,因为. = ALIGN(0x100)这句话使得地址计数器按0x100对齐。使得.text地址从0x3000 0100开始。我们看到脚本第15行ENTRY(_start) 实际上是第一条指令,也是.text的第一条指令。毫无疑问rtems的第一条指令在0x3000 0100的位置。

 

那么就糊涂了,整个镜像从linkcmd中看到的是从0x3000 0000开始,0x3000 0100是第一条指令。为什么在uboot中输入一下命令:

tftp 30000000 image.bin

go 30000100

没有任何反应?

(((

注意,编译好的hello.exe使用命令:

        arm-rtems4.9-objcopy -O binary hello.exe /tftpboot/image.bin

(我的tftp服务器文件夹在/tftpboot下,因人而异)

)))

只有一句话:##Starting application at 0x30000100 ...

 

根据上面的hello.nm,猜想:全局未初始化数据段如果在镜像的末尾或在镜像的开始,实际上是不会包含在镜像里的。

 

那么,我要证明一下这个猜想。修改一下脚本:

 

SECTIONS
{
  .base :
  {
    arm_exception_table = .;   

    arm_reset_vect    = .;     /* 0x00 */
    LONG(200)          /*. += 4;*//*Modified by Bacon*/

    arm_undef_vect    = .;     /* 0x04 */

 

LONG表示在地址计数器位置存储一个4字节的整数。这里是存储个200 ,纯粹为了试验。

恩,重新编译mini2440的rtems bsp和hello world的示例。

再次查看hello.nm,前22行是:

 

         w _Jv_RegisterClasses
         w __deregister_frame_info
         w __register_frame_info
00000100 A _abt_stack_size
00000400 A _fiq_stack_size
00001000 A _irq_stack_size
00001000 A _svc_stack_size
04000000 A _sdram_size
30000000 A _sdram_base
30000000 D arm_exception_table
30000000 D arm_reset_vect
30000004 D arm_undef_vect
30000008 D arm_swi_vect
3000000c D arm_iabrt_vect
30000010 D arm_dabrt_vect
30000018 D arm_irq_vect
3000001c D arm_fiq_vect
30000020 D rtems_vector_table
30000040 D bsp_vector_table

30000100 T _axf_text_start
30000100 T _start
3000026c T Reset_Handler

 

 

注意:原来由符号B改成符号D了。

D表示符号位于初始化数据段中。一般来说,分配到data section中。例如定义全局int baud_table[5] = {9600, 19200, 38400, 57600, 115200},则会分配于初始化数据段中。

 

然后进入~/qemu文件夹下,运行:

./mini2440/mini2440_start.sh

启动qemu

(这部详细请参考:http://blog.csdn.net/coolbacon/archive/2011/03/16/6252938.aspx)

输入命令:

tftp 30000000 image.bin

go 30000100

 

哈哈,顺利的看到了hello world!!

 

下面是有图有真相时间:

 

 

 

 

 

这印证了我的猜测。说明,最终的镜像不包含全局未初始化的数据段。

对于这个问题,还有深究的空间,以下是全局未初始化数据段空间位置的三种情况:

 

对于第一种和第三种,我觉得都是可以缺失的,即最终的内存镜像里可以不包含"全局未初始化数据段"。对于第二种情况,就有些值得研究了。根据我的经验,我认为如果“其他段”需要体现在最终镜像里,那么”全局未初始化数据段“也必须体现在镜像里,则需要包含。如果其他段不需要体现,那么全局未初始化数据段也不会体现在最终镜像里。(得空做个实验验证一下我的想法。)

 

关于这个问题,不想证明谁对谁错,探求真理,是做技术人员的天性。感谢Rickleaf的贡献,没有他我也不会想到这一层。

 

 

 

 

 

  
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值