Chinaunix首页 | 论坛 | 博客
  • 博客访问: 160163
  • 博文数量: 23
  • 博客积分: 348
  • 博客等级: 一等列兵
  • 技术积分: 235
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-02 16:34
个人简介

System Software Engineer

文章分类

全部博文(23)

文章存档

2013年(9)

2012年(14)

分类:

2012-12-14 12:50:29

原文地址:调试U-Boot笔记(四) 作者:hevake_lcj

    昨天说了AXD的那个 Configure Target... 菜单项中要选择个什么dll文件。今天在公司里我查了一下,确实如果。昨天我忽略了一点,打开AXD进行调试的时候,AXD怎么知道我与目标板是通过JLink进行通信的?发果没有,那么实际上我们昨天调试的程序都是在电脑上仿真的。
    打开 Options->Configure Target.. 在弹出的对话框中添加 JLinkRDI.Dll 文件。
   
    点击[Add]按钮,在JLink驱动的安路径下找到 JLinkRDI.dll 文件并添加进来。在我的电脑该文件的路径是:C:\Program Files (x86)\SEGGER\JLinkARM_V434\JLinkRDI.dll
 
    然后,我们再来调试u-boot程序。
    我们把AXD的加载u-boot的命令写成一个脚本文件u-boot.txt,放到 E:\ 下。

点击(此处)折叠或打开

  1. loadbinary e:\u-boot-gdb\u-boot.bin 0x33f80000
  2. loadsymbols e:\u-boot-gdb\u-boot.axf
  3. setpc 0x33f80000
    然后我们在AXD的命令行里执行命令:
    > ob e:\u-boot.txt
    AXD就从u-boot.txt里读取命令,并执行。这样可以减少我们反复敲命令带来的麻烦。
 
    好,我们执行一下。代码已导进来了,可以我们一执行就出错了。
    这时我才想起,SDRAM没有配置,下载到0x33f80000地址上的代码肯定无法保存。所以,我们得先下载并执行init.bin程序来初始化SDRAM,使之可用。
    OK,执行以下命令,下载init.bin文件并执行:
    > loadbinary e:\init.bin 0x40000000
    > setpc 0x40000000
    > run
    这下,看到开发板上的LED在闪烁,说明init.bin程序完成了SDRAM的初始化。
    暂停程序,然再导入u-boot程序到0x33f80000
    > ob e:\u-boot.txt
 
    OK,这下u-boot程序才算是真正地下载到了目标板上去了。单步执行一下,没有问题。
 
    但我还是遇到了挑战:
   
    为什么执行到start.S文件的165~166行时r0与r1的值不会劲呀!
   
    怎么会是这两个值呢?按程序的执行预期结果。它们应该都为0x33f80000呀!?
    按Ctrl+M打开内存监视器,将地址设置为0x33f80000,观查这块内存空间有没有被篡改的迹象
   
 
    果不其然,发现程序执行了160行的 bl cpu_init_crit之后,0x33f80000空间内存全被篡改了:
   
 
    那问题肯定出在cpu_init_crit里,那么我们一步一步跟起去,看倒底是执行了什么语句使用内存数据被改的。最终发现是在cpu_init_crint() 调用 lowleve_init()对SDRAM进行初始化时,内存里的数据被破坏了:
   
    lowlevel_init定义在 u-boot/board/my2440/lowlevel_init.S 文件里,主要的工作是配置SDRAM的控制寄存器。将L155~167的数据逐一赋给BWSCON地址的控制寄存器。正是这个赋值操作,使用内存中存在的数据被破坏。
    如果这个操作有破坏性,那很明显我们是直接从0x33f80000地址运行的,不需要但初始化SDRAM了。我们可以会程序做一点小修改,使之跳过执行lowlevel_init。
   
    由于start.S中全为汇编代码,不方便描述。这里我用伪代码说一下我的思路。
    之前的程序逻辑是:

点击(此处)折叠或打开

  1. cpu_init_crit();
  2. if ( start != TEXT_BASE )
  3. {
  4.     relocate();
  5. }
  6. stack_setup();
  7. if ( bootFrom NandFlash )
  8. {
  9.     nand_read_ll();
  10. }
    现在将其更改为:

点击(此处)折叠或打开

  1. if ( start != TEXT_BASE )
  2. {
  3.     cpu_init_crit();
  4.     if (bootFrom NandFlase){
  5.         nand_read_ll();
  6.     }else{
  7.         relocate();
  8.     }
  9. }
  10. stack_setup();
    cpu_init_crit()只有在reboot时才执行,如果是从NandFlash启动,则调用nand_read_ll()从NandFlash中导入程序代码,如果是从NorFlash启动的,那么就直接调用重定位函数relocate()将代码从0x00搬到0x33f80000去。
 
    修改了start.S文件行,重新编译,再用AXD进行调试。
    OH, Yeah! u-boot真的跑起来了!!!
    如下是我修改好的start.S文件,供大家参考: start.zip  ,用里面的start.S文件替换原来的u-boot/cpu/arm920t/start.S ,然后再重新编译就可以了。
 
    好了,今天的学习就暂且到此为止。明天我们一起尝试将u-boot烧录到NandFlash与NorFlash中……
阅读(881) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~