(add canon basic loader) |
(Adding categories) |
||
Line 152: | Line 152: | ||
</source> |
</source> |
||
+ | [[Category:CanonBasic]] |
||
+ | [[Category:Development]] |
||
+ | [[Category:Scripts]] |
Revision as of 07:02, 20 September 2010
Canon basic binary loader
This script loads and boots the specified ARM binary. The binary should be unencoded, and loadable at 0x1900
Tested on a540 (vxworks) and D10 (dryos)
' bootbin is the image to load
DIM bootbin = "A/MAIN.BIN"
DIM lcdmsg=0
DIM msgstr=0
PRIVATE SUB RegisterProcs()
' ExecuteEventProcedure does is not registered by default on vx
' Newer cams seem to have this as an alias for System.Create()
SystemEventInit()
if ExecuteEventProcedure("UI_RegistDebugEventProc") = -1 then
ExecuteEventProcedure("UI.CreatePublic")
end if
ExecuteEventProcedure("DispDev_EnableEventProc")
END SUB
PRIVATE SUB InitMsg()
lcdmsg = ExecuteEventProcedure("LCDMsg_Create")
' not default black
if lcdmsg >= 0 then
LCDMsg_ChangeColor(lcdmsg,2)
LCDMsg_SetStr(lcdmsg,"started")
end if
msgstr = AllocateMemory(80)
' truncate log
msgfile = Fopen_Fut("A/CBLOADER.LOG","w")
if msgfile <> 0 then
Fclose_Fut(msgfile)
end if
END SUB
PRIVATE SUB PutMsg(msg)
if lcdmsg >= 0 then
LCDMsg_SetStr(lcdmsg,msg)
end if
msgfile = Fopen_Fut("A/CBLOADER.LOG","a")
if msgfile <> 0 then
Fwrite_Fut(msg,strlen(msg),1,msgfile)
Fwrite_Fut("\n",1,1,msgfile)
Fclose_Fut(msgfile)
end if
END SUB
' put some ARM code in a buffer
' this should be in uncacheable memory, but function is not available on older cams
' in practice, loading the main image should ensure all this is flushed out
' can't use strings with \xHH because older cams don't support
' parameters:
' R0 source address
' R1 size
' never returns, saves nothing on the stack
PRIVATE SUB MakeLoader()
buf = AllocateMemory(76)
p = buf
*p = 0xee113f10 ' MRC p15, 0, R3, c1, c0, 0
p = p + 4
*p = 0xe3c33a01 ' BIC R3, R3, #0x1000 // icache bit
p = p + 4
*p = 0xe3c33004 ' BIC R3, R3, #0x4 // dcache bit
p = p + 4
*p = 0xee013f10 ' MCR p15, 0, R3, c1, c0, 0
p = p + 4
*p = 0xe3a03000 ' MOV R3, #0
p = p + 4
*p = 0xee073f9a ' MCR p15, 0, R3,c7,c10, 4 // drain write buffer
p = p + 4
*p = 0xee073f15 ' MCR p15, 0, R3,c7,c5 // flush icache
p = p + 4
*p = 0xee073f16 ' MCR p15, 0, R3,c7,c6 // flush dcache
p = p + 4
*p = 0xe10f4000 ' MRS R4, CPSR
p = p + 4
*p = 0xe3844080 ' ORR R4, R4, #0x80
p = p + 4
*p = 0xe12ff004 ' MSR CPSR_cxsf, R4 // disable IRQs
p = p + 4
*p = 0xee195f11 ' MRC p15, 0, R5, c9, c1, 0 // read data TCM config
p = p + 4
*p = 0xe1a05625 ' MOV R5, R5, LSR#12 // clear the lower 12 bits
p = p + 4
*p = 0xe7935605 ' LDR R5, [R3, R5, LSL#12] // R3 is still 0
p = p + 4
*p = 0xe1a02001 ' MOV R2, R1
p = p + 4
*p = 0xe1a01000 ' MOV R1, R0
p = p + 4
*p = 0xe3a00c19 ' MOV R0, #0x1900
p = p + 4
*p = 0xe3a03c19 ' MOV R3, #0x1900
p = p + 4
*p = 0xe12fff35 ' BLX R5
MakeLoader = buf
END SUB
PRIVATE SUB LoadNBoot()
loader = MakeLoader()
fd = Open(bootbin,0)
IF fd = -1 THEN
PutMsg("bootbin size fail")
EXIT SUB
END IF
imgsize = Lseek(fd,0,2)
Close(fd)
imgbuf = AllocateMemory(imgsize)
IF imgbuf = 0 THEN
sprintf(msgstr,"alloc %d fail",imgsize)
PutMsg(msgstr)
EXIT SUB
END IF
fd = Fopen_Fut(bootbin,"r")
IF fd = 0 THEN
sprintf(msgstr,"open %s fail",bootbin)
PutMsg(msgstr)
EXIT SUB
END IF
rcnt = Fread_Fut(imgbuf,1,imgsize,fd)
Fclose_Fut(fd)
IF rcnt <> imgsize THEN
sprintf(msgstr,"read %d fail",imgsize)
PutMsg(msgstr)
FreeMemory(imgbuf)
EXIT SUB
END IF
sprintf(msgstr,"%s %d",bootbin,imgsize)
PutMsg(msgstr)
Wait(500)
' register the start of loader as a function
ExportToEventProcedure("loader_func",loader)
DispCon_TurnOffDisplay()
' if starting is very slow, watchdog can hit before loading is complete
' but may stay on indefinitely if we crash
StopWDT()
loader_func(imgbuf,imgsize)
' if loader_func could return, we could try to restore
'StartWDT()
'DispCon_TurnOnDisplay()
END SUB
PRIVATE SUB Initialize()
RegisterProcs()
InitMsg()
LoadNBoot()
END SUB