[英]SPARC assembly jmp \boot
我將簡要說明問題。 我有一個Leon3開發板(gr-ut-g99)。 使用GRMON2,我可以在板上的所需地址加載可執行文件。
我有兩個程序。 我們稱它們為A和B。我試圖將它們加載到內存中,並且它們分別工作。
我現在想做的是使A程序稱為B程序。
這兩個程序都是使用gcc編譯器(Gaisler Sparc GCC)的變體用C編寫的。
為了進行跳轉,我在程序A中編寫了一個微小的內聯匯編函數,該函數跳轉到我加載程序B的內存地址。
在程序A的摘要下方
unsigned int return_address;
unsigned int * const RAM_pointer = (unsigned int *) RAM_ADDRESS;
printf("RAM pointer set to: 0x%08x \n",(unsigned int)RAM_pointer);
printf("jumping...\n");
__asm__(" nop;" //clean the pipeline
"jmp %1;" // jmp to programB
:"=r" (return_address)
:"r" (RAM_pointer)
);
RAM_ADDRESS是#define
#define RAM_ADDRESS 0x60000000
程序B是一個簡單的hello世界。 程序B加載在0x60000000地址。 如果我嘗試運行它,它將起作用!
int main()
{
printf ("HELLO! I'M BOOTED! \n");
fflush(stdout);
return 0;
}
運行ProgramA時,我期望的是在控制台上看到“正在跳躍...”消息,然后看到“ HELLO!I BOOTED!”。 從程序B
會發生什么,而不是IU異常。 我在下面發布了grmon2 Monitor顯示的消息。 我還報告了“ inst”報告,該報告應顯示異常之前執行的最后操作。
grmon2> run
IU exception (tt = 0x07, mem address not aligned)
0x60004824: 9fc04000 call %g1
grmon2> inst
TIME ADDRESS INSTRUCTION RESULT SYMBOL
407085 600047FC mov %i3, %o2 [600063B8] -
407086 60004800 cmp %i4 [00000013] -
407089 60004804 be 0x60004970 [00000000] -
407090 60004808 mov %i0, %o0 [6000646C] -
407091 6000480C mov %i4, %o3 [00000013] -
407092 60004810 cmp %i4, %l0 [80000413] -
407108 60004814 bleu 0x60004820 [00000000] -
407144 60004818 ld [%i1 + 0x20], %o1 [FFFFFFFF] -
407179 60004820 ld [%i1 + 0x28], %g1 [FFFFFFFF] -
407186 60004824 call %g1 [ TRAP ] -
我還嘗試用“ jmpl”或“ call”代替“ jmp”,但是它不起作用。 我很困惑 我不知道如何很好地解決這個問題,因此我不知道還需要提供什么其他信息。
我可以說,programB在0x60000000處加載,而entry_point當然是0x60000000。 從該入口點直接運行程序B效果很好!
在此先感謝您的幫助!
在我看來,您確實執行了跳轉,並且跳轉到了程序B,這由跟蹤緩沖區中的指令地址證明。 但是您崩潰的地方是在stdio中嘗試打印內容。 Stdio大量使用了函數指針,該序列清楚地顯示了一個調用指令,其中目標地址位於寄存器中,指示了函數指針的使用。
我建議將fflush(stdout)放在跳轉之前的程序A中,這將允許您在執行跳轉之前查看消息。 然后,在程序B中,不使用printf,而是將一些已知值放入內存中,然后可以通過監視器檢查該值,以確認它是否在那里。
我的猜測是stdio庫包含一些需要在程序開始時設置的數據或參數,而這些數據或參數尚未完成或未正確完成。 不確定正在運行的平台,但是您是否具有某種調試功能或單步執行功能,例如在調試器中? 如果是這樣,只需單步執行跳轉,然后跟蹤程序的運行位置即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.