调试VIVI: 一系列莫名错误及其解决过程

在将VIVI移植到三星2440板上时,遇到一系列错误,包括内存校验错误、堆初始化错误和指令异常。通过深入分析,发现错误源于Nand Flash内容错误、编译器生成不兼容的指令以及链接库问题。解决方案包括修正烧录软件、手动填充00、调整编译器选项和修改链接库目录,最终成功运行VIVI。
摘要由CSDN通过智能技术生成
  • 问题出现

近期一个项目需要将VIVI移植到我们的三星2440板上,在head.S中设置好晶振频率时钟频率之后,VIVI能跑起来了,但进入main后,初始化mtd设备时,程序挂了。

 

接上JTAG,使用ADS的AXD Debugger进行汇编调试,发现程序正运行着死循环,根据vivi.map中提供的地址信息,得知当前指令属于UndefEntryPoint异常中断处理程序,也就是说,程序发生了Undefined instruction exception异常。

 

  • 内存校验错误

由于无法知道哪里的指令发生异常,只能通过调试器单步汇编代码进行检查。在这个过程中,由于我对AXD Debugger不太熟悉,浪费了不少时间。

 

首先讲下Nand Flash Boot的机制。和Nor Flash不同,Nand Flash只提供数据访问接口,因此Nand Flash上存储的指令必须复制SDRAM中才能执行。考虑到大容量的Nor Flash成本远高于Nand Flash,普遍的做法是在板上置一片小容量的Nor Flash和一片大容量的Nand Flash,在Nor Flash写入引导代码,引导代码再将Nand Flash中的内容复制到SDRAM中执行,比起全部使用Nor Flash来说,成本可以成本不少。

 

三星的S3C2440则采用了另外一种办法,可以将Nor Flash也省掉。它的原理是CPU内置了4K的RAM,当CPU设置为Nand Boot模式时,这4K的RAM地址将被映射到0x00000000,CPU初始化时,第一件事是将Nand Flash的前4K内容读入内置的4K RAM中,之后才是执行此RAM中的指令。这就要求Boot Loader的内容必须控制在4K内,这有求太高了,现代的Boot Loader通常都带有大量的调试功能,基本上不可能做到那么小,因此Boot Loader也就分化成两部分,功能极简单的Nand Boot Loader和一般意义上的Boot Loader,比如WinCE就分为Nboot和Eboot。Nand Boot Loader只负责把Boot Loader搬运到内存中,再一个跳转就算了事。

 

可是两个Boot Loader还是太麻烦了,VIVI使用了另一种方法,启动后,首先将自己从Nand Flash中搬运到SDRAM中,再精确的跳转到下一条指令处,这样就可以省掉Nand Boot Loader。

 

就是这个搬运的过程,给我制造了不少麻烦。因为搬运后,VIVI会进行校验以确定代码是否正确复制,也就是将0x00000000开头的4K内容和目标地址的前4K内容进行比较,如果内容一致,则认为已正确搬运。这么大一个循环我当然在调试时设置了断点直接跳过,结果居然发现数据校验失败....真是太奇怪了,因为我亲自察看过两块内存,确实是完全一致的。

 

无法从代码上找到原因,只能单步执行慢慢观察,结果让我很意想不到:断点位置的内存被保护起来了,导致读出的数据是错误的。

 

  • 堆初始化错误

校验通过以后,VIVI跳转到SDRAM区域地址0x33f00000之后继续执行,进入了main函数,之后在heap_init中挂掉了。增加调试代码后,得知原因是gHeapBase初始值不对导致heap_init失败,但明明代码中的定义是"static blockhead *gHeapBase = NULL;"

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值