调试U-Boot笔记(五)

    昨天,我们修改了u-boot中的部分代并成功地用AXD把我们的u-boot跑起来了。这是一个很大的成就!我们不能自满,今天将再接再厉,进一步探索。

    我们今天的目标是:使将u-boot烧录到NandFlash与NorFlash,并使之正常启动。

    接着昨天的试验,我们的程序能够通过AXD运行起来,那么我们把程序用JLink命令加载到Mini2440上也应该可以正常运行。我们来试一下……

    打开J-Link Commander程序。还是老步骤,先下载init.bin文件到0x40000000地址上并运行起来,等其完成了SDRAM的初始化之后,再将我们编译的u-boot.bin下载到0x33f80000地址上。依次键入如下命令:
    > r
    > loadbin e:init.bin 0x40000000
    > setpc 0x40000000
    > g
    看一下开发板上的LED有没有正常闪烁,如有则继续:
    > h
    > loadbin e:u-boot-gdbu-boot.bin 0x33f80000
    > setpc 0x33f80000
    > g

    OK!此时我已听到一声蜂鸣器叫的声音,我们来看一下串口终端的显示:
   

    这已说明我们的u-boot启动起来了。

    然后,我们试一下将我们的u-boot写入到NandFlash去,我在笔记(一)中有写其中的过程。
    (1)用J-Link Commander将u-boot.bin导入到0x30000000的地址上去。
    (2)在串口终端中执行u-boot命令将0x30000000地址上的数据写到NandFlash中去。

    好,我们马上开始。我们在JLink命令行里输入以下命令:
    > h
    > loadbin e:u-boot-gdbu-boot.bin 0x30000000
    > g

    然后我们转向串口调试终端,执行U-boot命令:

    看来并没有想像中的那么顺利,在烧写NorFlash的时候还是遇到以前同样的问题。至于烧写到NandFlash,也失败了。

    烧写NorFlash时出现以下错误:
   

    错误是:General Flash Programming Error
    我把这个错误哪到源码里去搜索了一下,其在:
   

    打开该文件看看,查为flash_perror(int err)函数在执行。而该函数只负责打印错误信息。
    查到cp命令的执行函数,为 common/cmd_mem.c文件中的 do_mem_cp()。
   

    跟踪 do_mem_cp() 函数:

int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
    {
        ulong    addr, dest, count;
        int    size;
        if (argc != 4) {
            printf ("Usage:n%sn", cmdtp->usage);
            return 1;
        }
        /* Check for size specification.
        */
        if ((size = cmd_get_data_size(argv[0], 4)) < 0)
            return 1;
        addr = simple_strtoul(argv[1], NULL, 16);
        addr += base_address;
        dest = simple_strtoul(argv[2], NULL, 16);
        dest += base_address;
        count = simple_strtoul(argv[3], NULL, 16);
        if (count == 0) {
            puts ("Zero length ???n");
            return 1;
        }
    #ifndef CFG_NO_FLASH
        /* check if we are copying to Flash */
        if ( (addr2info(dest) != NULL)
    #ifdef CONFIG_HAS_DATAFLASH
         && (!addr_dataflash(addr))
    #endif
         ) {
            int rc;
            puts ("Copy to Flash... ");
            rc = flash_write ((char *)addr, dest, count*size);
            if (rc != 0) {
                flash_perror (rc);
                return (1);
            }
            puts ("donen");
            return 0;
        }
    #endif
        ……
        while (count-- > 0) {
            if (size == 4)
                *((ulong *)dest) = *((ulong *)addr);
            else if (size == 2)
                *((ushort *)dest) = *((ushort *)addr);
            else
                *((u_char *)dest) = *((u_char *)addr);
            addr += size;
            dest += size;
        }
        return 0;
    }

    重点观察L36~46之间的代码,这段代码的意思就是将数据复制到NorFlash中去。要想知道为什么烧写不成功,还得进: flash_write ( (char * )addr , dest , count *size ) ; 去看看。
    common/flash.c 文件中定义: 

/*-----------------------------------------------------------------------
     * Copy memory to flash.
     * Make sure all target addresses are within Flash bounds,
     * and no protected sectors are hit.
     * Returns:
     * ERR_OK 0 - OK
     * ERR_TIMOUT 1 - write timeout
     * ERR_NOT_ERASED 2 - Flash not erased
     * ERR_PROTECTED 4 - target range includes protected sectors
     * ERR_INVAL 8 - target address not in Flash memory
     * ERR_ALIGN 16 - target address not aligned on boundary
     *            (only some targets require alignment)
     */
    int
    flash_write (char *src, ulong addr, ulong cnt)
    {
    #ifdef CONFIG_SPD823TS
        return (ERR_TIMOUT);    /* any other error codes are possible as well */
    #else
        int i;
        ulong end = addr + cnt - 1;
        flash_info_t *info_first = addr2info (addr);
        flash_info_t *info_last = addr2info (end );
        flash_info_t *info;
        if (cnt == 0) {
            return (ERR_OK);
        }
        if (!info_first || !info_last) {
            return (ERR_INVAL);
        }
        for (info = info_first; info <= info_last; ++info) {
            ulong b_end = info->start[0] + info->size;    /* bank end addr */
            short s_end = info->sector_count - 1;
            for (i=0; i<info->sector_count; ++i) {
                ulong e_addr = (i == s_end) ? b_end : info->start[i + 1];
                if ((end >= info->start[i]) && (addr < e_addr) &&
                 (info->protect[i] != 0) ) {
                    return (ERR_PROTECTED);
                }
            }
        }
        /* finally write data to flash */
        for (info = info_first; info <= info_last && cnt>0; ++info) {
            ulong len;
            len = info->start[0] + info->size - addr;
            if (len > cnt)
                len = cnt;
            if ((i = write_buff(info, (uchar *)src, addr, len)) != 0) {
                return (i);
            }
            cnt -= len;
            addr += len;
            src += len;
        }
        return (ERR_OK);
    #endif /* CONFIG_SPD823TS */
    }

    最终是调用L54的 write_buff() 来实现Flash数据写入操作。我正想跟一下这个write_buff()函数,发现u-boot工程里有很多个write_buff()函数。感觉u- boot根据每一种类型的FLASH芯片都做了一套Flash驱动接口。这时,我在想:“我是不是没有选对Flash芯片哟?”

    好了,夜很深了,明天再继续探究。 

时间: 2024-10-31 09:01:55

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

kvm虚拟化学习笔记(五)之windows虚拟机性能调整

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

C#可扩展编程之MEF学习笔记(五):MEF高级进阶

好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用的基本已经讲完了,相信大家已经能看出MEF所带来的便利了.今天就介绍一些MEF中一些较为不常用的东西,也就是大家口中的所谓的比较高级的用法. 前面讲的导出都是在每个类上面添加Export注解,实现导出的,那么有没有一种比较简便的方法呢?答案是有的,就是在接口上面写注解,这样只要实现了这个接口的类都会

JSP学习笔记(五)-----JSP中使用JavaBean

js|笔记 1. 该实例主要告诉我们怎么样在JSP代码中调用JavaBean构件2. 使用JavaBean的优点是简化了JSP代码,界面代码和逻辑代码互相分离,便于程序员查看和调试3. 该实例需要五个文件:login.jsp,test.jsp, userbean.class4. 首先看一下login.jsp <html><center><form method=post action="http://127.0.0.1:8000/test.jsp">

PHP微信公众开发笔记(五)

PHP微信公众开发笔记系列 日期:2014.9.3 今天做了身份验证的功能,然后完善了下搜索功能.其实主要的是将整个代码结构整理了一番,应该可以说是模块化设计吧. 模块化设计我们的公众号. 因为我们之前提的功能需求中有: 1.菜单--查询功能.我考虑到后期功能的扩展,就想将这些分模块来实现:菜单模块(这样,今后我们需要添加新的菜单功能,可以直接在这个模块里操作,这样修正和维护也简单,在考虑到后期可能会分工协作的时候各开发者之间不会产生冲突): 2.数据库模块(这里就主要是负责数据库相关的工作,如

JVM深入学习笔记五:JVM 监控工具

命令行工具 JDK提供了很多的工具来监控JVM. 这些工具都是支持RMI远程监控的,暂且不记录远程调试的办法 1. JPS Process Status.  列出正在执行的虚拟机进程,可以查看到具体的类和进程ID. public class JPSTest { public static void main(String[] args) { while(true){} } } 执行之. 使用windows命令查看进程: C:\Users\huanggang>tasklist | findstr

VC++/MFC学习笔记(五)

 ADO技术介绍ADO是Microsoft最新和最强大的数据访问接口OLE DB而设计的,是一个便于使用的应用程序层.OLE DB为任何数据源都提供了高性能的访问,这些数据源包括关系和非关系数据库.电子邮件.文件系统.文本和图形以及自定义业务对象等.ADO在关键的Internet方案中使用最少的网络流量,并且在前端和数据源之间使用最少的层数,所有这些都是为了提供轻量.高性能的接口.同时ADO使用与DAO相似的约定和特性,使得它更易于学习.这里先介绍一下ADO技术的历史和ADO访问数据源的特点,然

zfdebug调试zend framework笔记

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

cmake学习笔记(五)

在cmake 学习笔记(三) 中简单学习了 find_package 的 model 模式,在cmake 学习笔记(四)中了解一个CMakeCache相关的东西.但靠这些知识还是不能看懂PySide使用CMakeLists文件,接下来继续学习find_package的 config 模式及package configure文件相关知识 find_package 的 config 模式 当CMakeLists.txt中使用find_package命令时,首先启用的是 module 模式: 按照 C

java笔记五:多线程的使用

以前学习基础的时候学习了一段时间的多线程,上课的时候老师也讲过一遍,那时候感觉学的似懂非懂.因为到现在很长一段时间没有用到多线程的知 识,所以现在基本上忘了差不多了.但是下个星期要面试了,所以今天特意又研究了一下多线程,免得被问到多线程问题时什么都不记得了那就麻烦了.现在对 java比较熟悉了,所以再一次学习多线程知识,感觉没有那么难了(记得刚接触多线程的时候,感觉非常吃力). 首先讲一下进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进

Caliburn.Micro学习笔记(五)----协同IResult

Caliburn.Micro学习笔记目录 今天说一下协同IResult 看一下IResult接口 /// <summary> /// Allows custom code to execute after the return of a action. /// </summary> public interface IResult { /// <summary> /// Executes the result using the specified context. /