调试U-Boot笔记(四)

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

    打开 Options->Configure Target.. 在弹出的对话框中添加 JLinkRDI.Dll 文件。

   

    点击[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

    > 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中全为汇编代码,不方便描述。这里我用伪代码说一下我的思路。

    之前的程序逻辑是:

cpu_init_crit();
if ( start != TEXT_BASE )
{
    relocate();
}
stack_setup();
if ( bootFrom NandFlash )
{
    nand_read_ll();
}

    现在将其更改为: 

if ( start != TEXT_BASE )
{
    cpu_init_crit();
    if (bootFrom NandFlase){
        nand_read_ll();
    }else{
        relocate();
    }
}
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中……

时间: 2024-08-19 22:29:27

调试U-Boot笔记(四)的相关文章

kvm虚拟化学习笔记(四)之kvm虚拟机日常管理与配置

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://koumm.blog.51cto.com/703525/1290269 KVM虚拟化学习笔记系列文章列表 ---------------------------------------- kvm虚拟化学习笔记(一)之kvm虚拟化环境安装http://koumm.blog.51cto.com/703525/1288795 kvm虚拟化学习笔记(二)之linux kvm虚拟机安装 h

《编程之美》读书笔记(四): 卖书折扣问题的贪心解法

  <编程之美>读书笔记(四):卖书折扣问题的贪心解法        每次看完<编程之美>中的问题,想要亲自演算一下或深入思考的时候,都觉得时间过得很快,动辄一两个小时,如果再把代码敲一遍的话,需要的时间可能更长,真是搞不懂通过微软面试的那些家伙的脑袋到底什么构造,书的序言中提到他们每次面试45分钟,还要写出程序?!在我看来,如果是控制CPU曲线或是中国象棋问题或许还有可能,如果是买书折扣问题,我觉得真的是不太容易,尤其是如果当面试者钻进本题的贪心解法而不是动态规划算法的思路之后,

MongoDB快速入门笔记(四)之MongoDB查询文档操作实例代码_MongoDB

MongoDB简介 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 下面给大家介绍MongoDB查询文档操作的实例 先把student删除,再重新插入数据 > db.student.drop() true > db.student.insert([{ "_id" : 1, "

.Net Winform开发笔记(四)透过现象看本质_C#教程

写在前面: 从一个窗体的创建显示,再到与用户的交互,最后窗体关闭,这中间经历过了一系列复杂的过程,本文将从Winform应用程序中的Program.cs文件的第一行代码开始,逐步分析一个Winform应用程序到底是怎样从出生走向死亡,这其中包括Form.Show()和Form.ShowDialog()的区别.模式对话框形成的本质原因.消息循环.Windows事件与.net中事件(Event)的区别.System.Windows.Form.Application类的作用.以及我之前一篇博客中(.N

JSP学习笔记(四)-----JSP动作的使用

js|笔记 1. 该实例主要告诉我们怎么样在JSP代码中使用JSP动作,例如<jsp:forward >2. 该实例需要四个文件:login.jsp,test.jsp,ok.htm,no.htm3. 首先看一下login.jsp<html><center><form method=get action="http://127.0.0.1:8000/test.jsp">username<input type=text name=use

zfdebug调试zend framework笔记

一.zfdbug简介:   zend framework项目开发过程中,测试是无处不在的,但zend framework测试非常麻烦.因此就有老外写了一个zf的debug插件,功能非常全面(文件,内存,数据,缓存,变量,运行时间,异常),它能展示我们平时看不到的系统信息对我们快速定位问题,提高系统的性能,安全性等都有很大的帮助. 有了zfdebug,以后使用zend framework开发项目,调试再无烦恼. 二.zfdebug的官方地址: http://code.google.com/p/zf

Programming Ruby读书笔记(四)

Ruby正则表达式 三种表示方法: Regexp.new('^s*[a-z]') /^s*[a-z]/ %r...{^s*[a-z]} 测试代码: def show_reqexp(a, re) if a =~ re "#{$`} << #{$&} >> #{$'}" else "no match" end end puts show_reqexp("Fats Waller", /ll/) 结果:Fats Wa &l

《淘宝技术这十年》读书笔记 (四). 分布式时代和中间件

        前面两篇文章介绍了淘宝的发展历程.Java时代的变迁和淘宝开始创新技术:            <淘宝技术这十年>读书笔记 (一).淘宝网技术简介及来源            <淘宝技术这十年>读书笔记 (二).Java时代的脱胎换骨和坚若磐石            <淘宝技术这十年>读书笔记 (三).创造技术TFS和Tair        这篇文章主要讲述分布式时代和中间件相关知识,包括服务化.HSF.Notify和TDDL.同时里面有我们经常遇见的编

Sqlite学习笔记(四)&amp;&amp;SQLite-WAL原理(转)

Sqlite学习笔记(三)&&WAL性能测试中列出了几种典型场景下WAL的性能数据,了解到WAL确实有性能优势,这篇文章将会详细分析WAL的原理,做到知其然,更要知其所以然. WAL是什么       WAL(Write ahead logging)是一种日志模式,它是一种思想,普遍应用于关系型数据库.每个事务执行变更时,修改数据页,同时会产生日志,这样在事务提交后,不需要将修改的脏页刷盘,只需要将事务产生的日志落盘即可返回.WAL保证日志一定先于对应的脏页落盘,就是所谓的WAL.SQLI

PL/SQL学习笔记(四)

这部分主要讲述在PL/SQL中如何访问oracle (一)检索单行数据 在PL/SQL嵌入select语句,使用方法: SELECT select_list INTO variable_name1,variable_name2,variable_name3... FROM TABLE WHRE condition 例:   DECLARE   v_sal  NUMBER ( 6 , 2 );  v_id  NUMBER ; BEGIN   v_id: = ' &id ' ;   SELECT