本文总结了在将最新发布的uboot移植到S3C6410时碰到的问题,并对问题进行了的详细分析,最后给出了解决方案。后续将不断增加碰到的新问题,供大家学习讨论,不足之处请指正,谢谢!
当前下载的uboot版本为:U-Boot 2013.04,以smdk6400为基础进行移植。
在终端输入:git clone git://命令就可获得当前最新的uboot源代码包。
uboot编译过程如下:
make O=build smdk6400_config
make O=build all
问题1. 第一次编译时出现错误提示如下:
u-boot/build/u-boot.lds:13: syntax error
打开u-boot.lds检查发现,原来u-boot.lds文件中align有大小写的区别。可能是有的交叉编译器不能识别小写的align,解决办法是打开board/samsung/smdk6400/u-boot-nand.lds文件,将里面小写的align改成大写的ALIGN。重新编译:
make O=build distclean
make O=build smdk6400_config
make O=build all
问题2. 编译时出现错误提示如下:
undefined reference _main
通过对旧版本的uboot代码进行比较发现,新版本的uboot将Start.S中的部分汇编代码移到了文件u-boot/arch/arm/lib
/crt0.S中,而crt0.S文件并没有添加到Makefile文件,导致链接时提示找不到_main函数的错误。解决办法是修改nand_spl/board/samsung/smdk6400/Makefile文件,修改内容如下:
SOBJS = start.o cpu_init.o lowlevel_init.o crt0.o
# from SoC directory
(新增加内容)
$(obj)crt0.S:
@rm -f $@
@ln -s $(TOPDIR)/arch/arm/lib/crt0.S $@
问题3. 编译时出现错误提示如下:
undefined reference coloured_LED_init
undefined reference red_led_on
该问题是由于coloured_LED_init和red_led_on两函数没有被定义。也没有什么用处,直接找到u-boot/arch/arm/lib
/crt0.S文件,将调用这两个函数的语句屏蔽掉就行了:
/* bl coloured_LED_init*/
/* bl red_led_on*/
问题4. uboot第一阶段启动问题
uboot启动的第一阶段调用了board/samsung/smdk6400/smdk6400_nand_spl.c中的board_init_f函数,该函数又调用了relocate_code(CONFIG_SYS_TEXT_BASE - TOTAL_MALLOC_LEN, NULL, CONFIG_SYS_TEXT_BASE)函数。虽然不太明白调用relocate_code函数有什么意义,但是这时CONFIG_SYS_TEXT_BASE=0,而TOTAL_MALLOC_LEN=1024*1024,导致SP地址指向一个无效地址,导致第一阶段根本无法加载第二阶段启动代码。
在调用board_init_f函数前已经通过ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)完成了SP地址初始化,因此在这里直接调用nand_boot函数就可以了。对board/samsung/smdk6400/smdk6400_nand_spl.c文件修改如下:
void board_init_f(unsigned long bootflag)
{
nand_boot();
}
问题5. uboot第二阶段启动问题
当软件代码长度发生变化时,可能会导致uboot第二阶段启动代码无法执行,概率很大,这时,在汇编代码中增加一条NOP指令,uboot又能正常运行,因为这个问题困扰了很长一段时间,本人觉得可能跟relocate_code这段代码有关,但又看不出什么毛病,希望有高人能够指点一二。
该问题的解决办法就是打开board/samsung/smdk6400/u-boot-nand.lds文件,找到.rel.dyn所在位置,将它上面一行的. = ALIGN(4)改为. = ALIGN(8)。
问题6. uboot启动后出现大量的raise: Signal # 8 caught
出现该信息表示做除法运算时,除数为0,进最终定位发现uboot延时程序里面调用了do_div (res, (timer_load_val / (100 * CONFIG_SYS_HZ)))函数,打印输出timer_load_val的值发现timer_load_val=0。
进一步查看源代码发现,uboot第二阶段启动代码的加载地址是0x57e00000,调用relocate_code函数后,代码挪到了SDRAM存储器比较靠后的位置:0x57fa4000(mini6410开发板挪到了这个位置)。由于timer_load_val定义为未初始化的静态全局变量,因此timer_load_val存在于uboot的bss段所在空间,而timer_load_val是由timer_init函数在代码挪动前初始化的,代码挪动时并没有将bss段内容挪到新的位置,而是简单的全部初始化为0,导致该问题的发生。
解决办法就是打开arch/arm/lib/timer.c文件,在timer_load_val的定义后面增加:__attribute__((section(".data")))。修改后代码如下:
static ulong timer_load_val __attribute__((section(".data")));
阅读(1431) | 评论(0) | 转发(0) |