第六章:基于九鼎X210开发板移植2014.10版U-boot之重定位

2019-07-12 17:37发布

 那么内存初始化完成后,要做的就是将bl2的代码拷贝到内存中去了,原版的uboot在arhc/arm/libcrt0.Srelocate_code来对代码进行拷贝,但我们不使用这个(原因是我们的uboot放在nand和sd卡中,需要使用另一种方法来对代码进行拷贝),一如既往使用开发板的程序,移植过来。  重定位的地方就定在了lowlevel_init之后main之前。
 代码过长,就不贴了,后期会整一个帖子专门放改过代码的地方。  注意,这里用到了movi_bl2_copy这个函数,而这个函数也是需要移植的,当然,这个函数也需要放在前8k。
 需要拷贝开发板的代码:  1、samsung-ubootinclude目录下的movi.h拷贝到u-boot-2014.10include目录下。
 2、samsung-ubootcpus5pc11x目录下的movi.c拷贝到u-boot-2014.10oardsamsungX210目录中。  同样的,为了防止代码过于臃肿,删除movi.c中不必要的代码。只保留我们需要用到的movi_bl2_copy即可(当然不裁剪也可以,理论上应该是够用的)然后按照之前的方式,将movi.o链接进前8k,编译的过程中会报错,原因基本上是因为缺少宏之类的,将缺少的宏补齐即可。然后我在复制代码完成后,打印了一个'K'字符,来表示成功。然后跳转到crt0里面的main去执行board_f函数。
      
 之后编译,发现并不能使用(接下来就是开始排查问题的时候)  理论上,应该能够打印出'K'这个字符,但实际上什么都没打印。于是我进行排查后,发现只要进入了movi_bl2_copy后,就再也出不来了,直观的看就是串口只打印出'B'不打印'C'
        进入movi_bl2_copy后,发现里面这个函数其实是调用irom里面固化了的程序来copy代码到内存。问题应该就是出在这里面。
 假设1:时钟初始化未完全,导致拷贝失败。  起因是我发现lowlevel中时钟的初始化并没有执行,但是立马就否定了,因为bl0中有对cpu做了初步的初始化,且咱们用sd卡烧录程序的时候,也应该是调用irom里面的固化程序来让将bl1拷贝到内部sram中的,所以否定。
 假设2:DDR初始化未完成,所以拷贝到内存中失败了。  copy_bl2这个函数需要传入五个参数,分别是sd卡通道号,拷贝的起始block、拷贝的block数目、拷贝到内存的地址、固定为0。一看就知道是将bl2拷贝到内存中,那么如果内存初始化出错,应该也是拷贝不了的,况且这个函数是写死在irom里面,我们也无从得知里面是怎么样的,所以只能开始验证。
     
 我将整个movi_bl2_copy函数屏蔽掉,然后写下了以下的测试代码,主要作用就是往内存中写入数据,然后读出,看一不一致,如果一致的话打印'Y',不一致的话打印'N',结果是打印出'Y',而且还能打印出'C'这个字符。说明内存是能够正常使用的,去执行movi_bl2_copy的时候出问题了。
 假设3:C语言环境的栈设置有误。 栈里面保存了执行该函数前的任务信息,如果栈出问题了,就会导致信息丢失,就不能退回执行前的工作状态了。 于是我写了一个测试函数,在movi_bl2_copy调用它,果然执行的时候,无法跳出。这样就说明栈设置有问题了。
 最终问题定位:
 Review代码之后,发现在start.S中设置了栈指针,_TEXT_BASE地址为我们最开始设置的0x30000000,由于我们ARM的栈是满减栈,栈是向下生长,即:下一个地址为0x2fff_fffx,我们内存起始地址为0x30000000,所以就会导致栈数据丢失。
      最后,将之前设置的CONFIG_SYS_TEXT_BASE的值改大一点就可以解决上述问题了。这里我将CONFIG_SYS_TEXT_BASE设置成一开始默认的0x3480_00000.