Как прыгнуть в загрузчик в Аде? - PullRequest
2 голосов
/ 26 января 2012

Я пишу встроенный код в 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; 

Ответы [ 2 ]

2 голосов
/ 26 января 2012

Я провел небольшой эксперимент на этом 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 не является кодом-генерирует правильно?

2 голосов
/ 26 января 2012

Так как обычно загрузчик запускается при перезагрузке, самый простой способ - принудительно перезагрузить процессор.Загрузчик может разумно предположить, что он работает в неинициализированной системе в состоянии сброса и может выполнить инициализацию, которая недопустима в уже инициализированной системе, поэтому принудительный сброс является самым безопасным методом.

Ваш процессор можетиметь команду сброса или контроллер сброса, который может выполнить это напрямую.В противном случае он может иметь сторожевой таймер, который может генерировать сброс.Запустите сторожевой таймер с достаточно коротким тайм-аутом и дайте ему поработать без обслуживания.

...