对于上篇介绍的飞凌OK6410开发板之u-boot-2011.06-rc2移植方法,通过自己的OK6410开发板实践验证,是可行的,但是在最后面启动的时候,串口输出UBOOT启动画面会定格在FLASH:......FAILED.....这个位置,然后要求RESTART BOARD,所以UBOOT虽然是启动了,但是还没启动完全,卡在FLASH这一块了,所以昨天又花了半天时间整这个问题,通过不断地代码追踪,最终找到了问题的所在。
对于UBOOT的移植这一块,我的方法就是尽量自己去寻求问题的解决方案,不要一出问题就去BAIDU ,GOOLE,运气好,可能搜到与你问题相近或是一样的答案,运气不好的话,可能搜了半天,也找不到,这个都是有可能的,即使搜到问题的解决方案了,你也只是明白该怎么做,但是却不明白为什么要去这么做,这样自己的印象也不深刻。所以我在这也主要是谈谈我移植 u-boot-2011.06-rc2到OK6410开发板上的一个大体思路与方法,希望对你们有帮助,不会去直接将如何修改如何做直接就贴出来,感觉这样意义也不大。下面就来说说今天的重点吧——how to solve the problem about failure of flash
如果手头有RAM程序调试工具的话,估计就更好办,但一般的UBOOT调试基本都是用串口输出打印信息辅助调试,CPU信息,DRAM信息全都打印出来了,到达FLASH这一块,就打印FAILED,然后UBOOT便挂起,一开始我也是不得其解,以为是 u-boot-2011.06-rc2内自带的CFI_FLASH(commom flash interface)driver对OK6410不起作用,后来便直接丢弃之,然后将UB00T1.16内的SMDK6410内的flash驱动移植了过来,这个花了一点时间,毕竟驱动代码是现成的,只是需要做些稍微的修改就可以加入u-boot-2011.06-rc2,但是通过单板实践验证,一到DRAM信息输出后开发板就立刻重启,连FLASH信息也没输出,但是在UBOOT1.16上却顺利通过,我想肯定还是有哪些位置需要修改,毕竟uboot1.16与u-boot-2011.06-rc2在代码结构以及文件结构上安排还是很不同的,可我没有一点头绪,所以舍弃了这个思路,后来仔细想想,原来采用自带的CFI_FLASH DRIVER时可以看到FLASH信息输出,只不过是FAILED,要不先从这块入手,于是开始跟踪代码的运行,呵呵,说是跟踪其实也是费了一番心血的,毕竟,你都不知道如何去下手,从哪去跟踪,其实,跟踪代码还是要有一定的技巧的,如果对UBOOT内部代码结构熟悉的话,应该会很容易,既然是FLASH这一块自检失败,就需要找到相关的位置,而FLASH是属于板载资源的,所以代码应该与BOARD文件相关,于是我锁定了OK6410.C,LOWLEVEL_INIT.S以及ARCH/ARM/LIB/BOARD.C这3个文件,毕竟这几个文件与板载资源初始化关系很密切,最后通过代码分析,在ARCH/ARM/LIB/BOARD.C这个文件里发现了问题。
仔细的看了一遍这个文件,发现原来串口打印信息以及打印的顺序全都是由这个文件来决定的,通过一步一步的代码分析,我找到了这么一段代码:
#if !defined(CONFIG_SYS_NO_FLASH)
puts ("Flash: ");
if ((flash_size = flash_init ()) > 0) {
# ifdef CONFIG_SYS_FLASH_CHECKSUM
print_size (flash_size, "");
/*
* Compute and print flash CRC if flashchecksum is set to 'y'
*
* NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
*/
s = getenv ("flashchecksum");
if (s && (*s == 'y')) {
printf (" CRC: %08X",
crc32 (0, (const unsigned char *) CONFIG_SYS_FLASH_BASE, flash_size)
);
}
putc ('/n');
# else /* !CONFIG_SYS_FLASH_CHECKSUM */
print_size (flash_size, "/n");
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
} else {
puts (failed);
hang ();
}
#endif
看到标红色的没,那就是串口输出信息 FLASH:.....FAILED....
而这个failed 只是一个指针变量,在这段代码的前面有一小段代码说明:
#if !defined(CONFIG_SYS_NO_FLASH)
static char *failed = "*** FAILED***/n";
#endif
看到那个puts (failed);函数下一条的函数没,hang ();其实就是一个系统挂起函数,来粗略分析一下这段代码吧。
if ((flash_size = flash_init ()) > 0), flash_init ();这个函数是在/driver/mtd/cfi_flash.c中定义的一个flash初始化函数,而它会返回一个值,也就是flash_size ,而OK6410单板上没有带flash芯片,只有2个64M(共128M)的DRAM内存芯片,还有一个FLC的1G NAND FLASH芯片,所以导致flash_size = flash_init ()) <=0,进而去执行ELSE后面的 puts (failed);hang ();两个函数,所以导致最终UBOOT启动卡在FLASH:FAILED 然后挂起。
由于OK6410没有自带flash,因此在这里最简单的一个解决办法就是将hang ();函数屏蔽掉,不让系统挂起,代码继续往下执行就可以了,也就是://hang ();。
如果,你觉得flash:.....failed.....这个输出信息看起来很别扭的话,可以直接屏蔽掉,或是将failed这个指针变量换一下,这里我换的的NULL。好了。最后再保存编译,下载到OK6410的DRAM内运行:
CPU: S3C6400@533MHz
Fclk = 533MHz, Hclk = 133MHz, Pclk = 66MHz (ASYNC Mode)
Board: OK6410
DRAM: 128 MiB
Flash: *** NULL ***
NAND: raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
raise: Signal # 8 caught
1024 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: CS8900-0
Hit any key to stop autoboot: 0
OK6410 #
这个就是最后的输出结果,看到没,OK6410自带的NAND也识别出来了,只不过可能是自带的驱动不完善的缘故,导致对NAND的一切操作都无效,这个工作后面再进行,还有NET网卡驱动上面现实的是SMDK6400默认的CS8900,也是需要更改的,后面会继续移植相关驱动部分的。
其实本来是想等驱动移植的差不多再贴出来的,但是感觉还是一步实践,一步记录下来最好,免得到时一起写的话,工作量太大了,到这里,可以说OK6410的u-boot-2011.06-rc2移植才算真正启动启动起来了,后面的工作主要就是相关驱动的移植,以及可能需要增加的功能的实现代码的ADD了。