天天看点

调试U-Boot笔记(四)

  昨天说了axd的那个 configure target... 菜单项中要选择个什么dll文件。今天在公司里我查了一下,确实如果。昨天我忽略了一点,打开axd进行调试的时候,axd怎么知道我与目标板是通过 jlink进行通信的?发果没有,那么实际上我们昨天调试的程序都是在电脑上仿真的。

    打开 options->configure target.. 在弹出的对话框中添加 jlinkrdi.dll 文件。

调试U-Boot笔记(四)

    点击[add]按钮,在jlink驱动的安路径下找到 jlinkrdi.dll 文件并添加进来。在我的电脑该文件的路径是:c:program files (x86)seggerjlinkarm_v434jlinkrdi.dll

    然后,我们再来调试u-boot程序。

    我们把axd的加载u-boot的命令写成一个脚本文件u-boot.txt,放到 e: 下。

    > loadbinary e:u-boot-gdbu-boot.bin 0x33f80000

    > loadsymbols e:u-boot-gdbu-boot.axf

    > 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

    ok,这下u-boot程序才算是真正地下载到了目标板上去了。单步执行一下,没有问题。

    但我还是遇到了挑战:

调试U-Boot笔记(四)

    为什么执行到start.s文件的165~166行时r0与r1的值不会劲呀!

调试U-Boot笔记(四)

    怎么会是这两个值呢?按程序的执行预期结果。它们应该都为0x33f80000呀!?

    按ctrl+m打开内存监视器,将地址设置为0x33f80000,观查这块内存空间有没有被篡改的迹象

调试U-Boot笔记(四)

    果不其然,发现程序执行了160行的 bl cpu_init_crit之后,0x33f80000空间内存全被篡改了:

调试U-Boot笔记(四)

    那问题肯定出在cpu_init_crit里,那么我们一步一步跟起去,看倒底是执行了什么语句使用内存数据被改的。最终发现是在cpu_init_crint() 调用 lowleve_init()对sdram进行初始化时,内存里的数据被破坏了:

调试U-Boot笔记(四)

    lowlevel_init定义在 u-boot/board/my2440/lowlevel_init.s 文件里,主要的工作是配置sdram的控制寄存器。将l155~167的数据逐一赋给bwscon地址的控制寄存器。正是这个赋值操作,使用内存中存在的 数据被破坏。

    如果这个操作有破坏性,那很明显我们是直接从0x33f80000地址运行的,不需要但初始化sdram了。我们可以会程序做一点小修改,使之跳过执行lowlevel_init。

    由于start.s中全为汇编代码,不方便描述。这里我用伪代码说一下我的思路。

    之前的程序逻辑是:

    现在将其更改为: 

  cpu_init_crit()只有在reboot时才执行,如果是从nandflash启动,则调用nand_read_ll()从nandflash 中导入程序代码,如果是从norflash启动的,那么就直接调用重定位函数relocate()将代码从0x00搬到0x33f80000去。

    修改了start.s文件行,重新编译,再用axd进行调试。

    oh, yeah! u-boot真的跑起来了!!!

调试U-Boot笔记(四)

    好了,今天的学习就暂且到此为止。明天我们一起尝试将u-boot烧录到nandflash与norflash中……