- 论坛徽章:
- 0
|
原来的relocat的bug:
当g-bios-bh代码在内存中的物理地址和链接地址不重叠或者物理地址和虚拟地址完全一致时,
整个g-bios运行正常,但当程序有部分重叠时,程序就会运行不正常。
原因:
relocation的程序放在代码段,因而在移动过程中,如果程序的物理地址和链接地址有部分重叠,
就会将relocation本身覆盖。导致程序出错。
调试过程:
为了防止程序在移动过程中被覆盖,开始想先将代码先移动到和链接地址、物理地址都不重叠的地方,
然后在执行relocation,这样当前程序就不会被覆盖。
后来发现其实不需要将整个代码都移动,只要将relocation部分代码移动到一个安全的地方,然后调过去
执行,再执行完成后返回到移动后的程序中。但是如果将relocation部分代码移动到sdram中的一个安全
的地方需要对原代码的物理地址和链接地址进行计算,功能上实现是行,但相对较复杂。
后来想到了将relocation代码移到sram,这样不管原程序位于sdram的任何位置,relocation的代码都不会
被覆盖,而且实现起来也相对简单。
代码调试过程中的问题:
程序开始运行,将relocation代码拷贝至sram,将pc指向sram中的程序,但是在执行完这部分程序后,
pc无法返回至sdram中的代码。
后来查看了程序的反汇编代码,发现编译器将 ldr pc, =skip_move 翻译成 ldr pc, [pc, #xxx] (xxx为常数,当前pc的偏移)
如果程序不移动,代码执行时会调至skip_move,但relocation的代码会拷贝至sram,而相对于此时的pc偏
移xxx就不在是skip_move的地址了。
解决方法:
在跳至sram之前将skip_move的链接地址保存在Rn(n为寄存器编号,一般选取通用寄存器)中,然后返回时执行 mov pc,Rn。
经过调试,对物理地址、虚拟地址、链接地址、总线地址有了很深刻的了解,但是帖子写起来感觉在写绕口令,
不合理的地方或者不清楚的地方,大家一起讨论。 |
|