zl程序教程

您现在的位置是:首页 >  后端

当前栏目

调试U-Boot笔记(五)

2023-09-14 08:58:19 时间

    昨天,我们修改了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!此时我已听到一声蜂鸣器叫的声音,我们来看一下串口终端的显示:
    23210549_GqWG.png

    这已说明我们的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时出现以下错误:
    23210550_THPV.png

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

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

    跟踪 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)

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

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



史上最全的 IDEA Debug 调试技巧(超详细案例)(一) Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化。通常我们也可以启用Debug模式来跟踪代码的运行流程去学习三方框架的源码。 所以学习下如何在Intellij IDEA中使用好Debug。
spring-framework最新源码调试(二) 最近打算阅读spring-framework的源码,按照GitHub中在spring-framework项目中给出的编译和导入IntelliJ IDEA的方式进行操作,其中还是遇到了各种各样的问题。主要是环境,最好都用新的,JDK17、Idea 2021、Gradle7.2、Tomcat10等,然后就是多次重试。最终还是成功了,文章末尾也列了几个遇到的问题及最终存在我的GitHub中的地址。
spring-framework最新源码调试(四) 最近打算阅读spring-framework的源码,按照GitHub中在spring-framework项目中给出的编译和导入IntelliJ IDEA的方式进行操作,其中还是遇到了各种各样的问题。主要是环境,最好都用新的,JDK17、Idea 2021、Gradle7.2、Tomcat10等,然后就是多次重试。最终还是成功了,文章末尾也列了几个遇到的问题及最终存在我的GitHub中的地址。
spring-framework最新源码调试 最近打算阅读spring-framework的源码,按照GitHub中在spring-framework项目中给出的编译和导入IntelliJ IDEA的方式进行操作,其中还是遇到了各种各样的问题。主要是环境,最好都用新的,JDK17、Idea 2021、Gradle7.2、Tomcat10等,然后就是多次重试。最终还是成功了,文章末尾也列了几个遇到的问题及最终存在我的GitHub中的地址。
李名赫 博主从事的是物联网行业,目前在某知名智能家居科技公司担任家庭智能中心研发主管。欢迎交流!