10.17.2007

LoadAndRun - Overwrite the running program

要作一個LoadAndRun功能..所以會遇到 Load 到目前program的區域,把自己蓋掉的情況。
所以要先Load到其他地方,copy回來,再run。 這樣,就可以把 "copy" 的動作。 放到其他地方,

要處理的部份,就剩下 "Copy" 的code。

漂亮的話是要用 RAM Function,修改loading script,讓init code把 "Copy" function 放到"其他區域"。

但是 這有點麻煩。--- 因為不確定 memory usage map,不知道要擺在哪好。
所以,想利用 SRAM的區域來放。
目前SRAM放 bootloader code,一旦boot 完,就沒用了。

但是要小心,因為前面的區域,有Exception Hanlder要用,所以要避開。

開啟 make option 的 map output,看一下,就從 main.c 所佔用的區域開使用好了。

main.o 從 0x00000368 開始。 那就從 0x00000400 開使用好了。

SRAM有4k,所以還有3k的space可以用。

原來想把 "CopyAndRun" function 實做在 bootloader中,然後用get function pointer 取得。讓 test code run,但是這樣太不flexible,bootloader改版時,testcode也會受到影響。
所以還是拿來當scratch memory來用好了。

test code把需要的code 填入 這塊區域,然後跳過去run。



CopyAndRun( )要寫到assembly code 中。因為 Run 的Launch 動作本來就是寫在assembly 中。


先寫一個code看一下argument order..

EXPORT CopyAndRun
CopyAndRun
mov pc,lr
然後在 source (*.cpp)中..
extern "C" void CopyAndRun(int a,int b, int c);
..
CopyAndRun(1,2,3);
build , set breakpoint on CopyAndRun 看一下r0,r1,r2的值...
依次是1,2,3,所以argument 的順序是 r0, r1, r2.. 其實這個看ABI 應該可以知道....




實做 copy function...
; void CopyAndRun(DWORD dest, DWORD src,DWORD length)
EXPORT CopyAndRun_Start
EXPORT CopyAndRun_End
CopyAndRun_Start
add r2,r2,r1 ; src+len = end
10 ldr r3,[r1]
str r3,[r0]
add r0,r0,#4
add r1,r1,#4
cmp r1,r2
bne %B10
mov pc,lr
CopyAndRun_End
開頭和最後的label是給copy用的。先作copy的部份,run 只要改最後 的instruction就可以。

這一段code,要被copy到 0x400 的位置,再呼叫。
C function 中,要宣告出 function 的 Start, Stop position ,然後在程式中使用前,用memcpy copy到0x400:
extern void *CopyAndRun_Start;
extern void *CopyAndRun_End;
....
memcpy((int*)0x400,(int*)&CopyAndRun_Start,(int)&CopyAndRun_End - (int)&CopyAndRun_Start);
....
((void(*)(int,int,int))0x0400)(0x500,(int)testdata,20*4);
上面的sample 把 testdata的內容copy到0x500的地方
這樣就可以 check 0x500 的memory內容是否真的和testdata一樣。

確認OK後,就可以改 CopyAndRun 的assembly code。作 Run 的動作..
; void CopyAndRun(DWORD dest, DWORD src,DWORD length)
EXPORT CopyAndRun_Start
EXPORT CopyAndRun_End
CopyAndRun_Start
mov r4,r0 ; save dest address
add r2,r2,r1 ; src+len = end
10 ldr r3,[r1]
str r3,[r0]
add r0,r0,#4
add r1,r1,#4
cmp r1,r2
bne %B10
; mov pc,lr
mov pc,r4 ; jump to dest addr

CopyAndRun_End

沒有留言: