调试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芯片哟?”

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


目录
相关文章
|
存储 运维 Kubernetes
Kubernetes密钥管理安全方案和最佳实践
众所周知,Kubernetes作为编排引擎为应用开发者提供了Secrets模型用于在应用Pod中加载和使用敏感信息(如数据库密码、应用证书、认证token等)。Secrets的使用对于K8s开发者来说应该已经比较熟悉了,下面是一些Secrets相关的基本概念:Secrets是一个namespace维度的模型,结合K8s RBAC访问控制可以实现集群内namespace维度的读写隔离Secrets可
1404 0
Kubernetes密钥管理安全方案和最佳实践
|
4月前
|
机器学习/深度学习 分布式计算 Java
Java 大视界 -- Java 大数据机器学习模型在遥感图像土地利用分类中的优化与应用(199)
本文探讨了Java大数据与机器学习模型在遥感图像土地利用分类中的优化与应用。面对传统方法效率低、精度差的问题,结合Hadoop、Spark与深度学习框架,实现了高效、精准的分类。通过实际案例展示了Java在数据处理、模型融合与参数调优中的强大能力,推动遥感图像分类迈向新高度。
|
5月前
|
安全 物联网 API
核验身份证的一致性API的实战指南
随着网络空间安全问题日益突出,实名制成为保障安全与秩序的重要手段。探数API的身份证实名认证工具通过姓名和身份证号核验用户身份真实性,并返回扩展信息,广泛应用于各行业。本文介绍了其实现功能、调用流程及代码示例,同时解答了关于个人信息安全等常见疑问。接入该API不仅满足合规要求,更能提升用户信任,降低运营风险,共同构建安全高效的数字未来。
429 1
|
XML Java Android开发
34. 【Android教程】菜单:Menu
34. 【Android教程】菜单:Menu
567 2
|
人工智能 运维 安全
世界级大模型群,进化阿里云服务器操作系统新范式
世界级大模型群,进化阿里云服务器操作系统新范式
348 13
|
监控 关系型数据库 MySQL
深入了解MySQL主从复制:构建高效稳定的数据同步架构
深入了解MySQL主从复制:构建高效稳定的数据同步架构
345 1
|
8月前
|
存储 自然语言处理 运维
多语言环境全支持的面板有哪些?
在全球化背景下,服务器管理工具需实现多语言多环境全支持,涵盖技术、服务和合规三个层面。Websoft9作为典型代表,支持12种语言的动态界面切换、自动时区与编码适配,并提供多语言技术文档及区域合规配置,适合全球化中小企业部署。相比之下,cPanel、宝塔面板和Plesk各有侧重,用户应根据需求理性选择。
246 2
|
SQL 存储 缓存
高基数 GroupBy 在 SLS SQL 中的查询加速
本文详细介绍了SLS中的高基数GroupBy查询加速技术。
315 111
|
供应链 监控 安全
系统安全性的重要性体现在多个方面
【10月更文挑战第9天】系统安全性的重要性体现在多个方面
508 1
|
10月前
|
SQL PyTorch 算法框架/工具
Intel技术专家:oneAPI 开放式加速计算|龙蜥大讲堂第114期
这次分享的主题是《oneAPI 开放式加速计算 龙蜥大讲堂第 114 期》的主要内容。主要分为四个部分: 1. 发展背景 2. 什么是 oneAPI 3. 产品应用 4. 总结展望
487 6