我正在用Ada编写嵌入式代码。我想跳转到位于地址0x0E00的引导加载程序代码。我尝试使用以下代码:
with Interfaces; use Interfaces;
with System;
package AVR.bootloader is
procedure Call;
pragma No_Return(Call);
pragma Import (Assembler,Call);
for Call'Address use System'To_Address (16#0E00#);
end AVR.bootloader;问题是这是行不通的。
编辑:我想做一个与C语言等价的操作:
void (*boot)(void)=0x0E00; 发布于 2012-01-26 18:07:45
我在这台Macbook Pro上做了一个小实验,你的代码似乎做了你想做的事情;我修改了代码
with System;
procedure Bootloader is
procedure Call;
pragma No_Return (Call);
pragma Import (Assembler, Call);
for Call'Address use System'To_Address (16#0E00#);
begin
Call;
end Bootloader;当我用gnatmake -c -u -f -S bootloader.adb编译时,保存的汇编程序是
.text
.globl __ada_bootloader
__ada_bootloader:
LFB1:
pushq %rbp
LCFI0:
movq %rsp, %rbp
LCFI1:
subq $16, %rsp
LCFI2:
movq $3584, -8(%rbp)
movq -8(%rbp), %rax
call *%rax
leave
LCFI3:
ret
[...]这看起来很有希望,尽管我对asm还不够熟悉,还不知道。
在gdb下运行它我得到(在很多讨论之后)
(gdb) run
Starting program: /Users/simon/tmp/bootloader
Reading symbols for shared libraries ++........................ done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000e00
0x0000000000000e00 in ?? ()
(gdb) bt
#0 0x0000000000000e00 in ?? ()
Cannot access memory at address 0xe00
#1 0x0000000100000d93 in main (argc=1, argv=140734799805048, envp=140734799805064) at /Users/simon/tmp/b~bootloader.adb:121
#2 0x0000000100000bf4 in start ()这看起来更有希望。
也许你的AVR编译器没有正确地生成代码?
发布于 2012-01-26 09:56:39
由于通常引导加载程序在重置时运行,因此最简单的方法是强制处理器重置。引导加载程序可以合理地假设它在处于重置状态的未初始化系统上运行,并且可以执行在已经初始化的系统上无效的初始化,因此强制重置是最安全的方法。
您的处理器可能有一个重置指令或一个重置控制器,可以直接执行此操作。否则,它可能有一个看门狗定时器,可以产生一个重置。以适当的短超时启动看门狗定时器,并让其运行而不对其进行维护。
https://stackoverflow.com/questions/9012414
复制相似问题