CallProg 분석
Testapp7 에 있는 CallProg 라는 함수에 대한 분석이다. 이 함수는 흔히 다른 함수와는 달리 어셈블리어로 만들어져 있다. 그 만큼 중요하고, 또 마지막에 jump 코드가 포함되어 있다.
아마도 이 코드를 분석한다면, 내가 원하는 듀얼부팅에 뭔가 실마리를 얻을 수 있을 것 같다.
void callprog(void* addr) // 테스트 프로그램에서 callprog((void *)0x7ffffffe) 로 호출했다
{
int i;
int priority = 0;
int regs[4]; /*lint -e550*/
#ifdef APK
long int res;
char buf[100];
#endif
/* check the hardware priority */
__asm {
ldpri; // 우선순위를 load 한다
st priority; // st 에 우선 순위값을 저장한다
}
if (1 == priority) {
/* change to high priority */
__asm {
ldlabeldiff here - there; // here 와 there 사이의 차이를 load 한다
ldpi; // 포인터를 load 한다
here:;
stl -1; // -1 을 local 에 저장한다
ldlp 0; // 0 의 local pointer 를 load 한다.
runp; // 프로세스를 실행한다
there:;
}
}
/* disable inturrupts */
interrupt_disable_global (); // 인터럽트를 중지시킨다
/* restore the interrupt controller */ // 인터럽트 복구
for (i=0; i<INTERRUPT_LEVELS; i++) {
(void) interrupt_disable (i);
}
#if 0
/* reset hard channels.
* this is a very rarely needed operation that causes known problems.
* if you do not use hard channels in the bootstrap do not enable this
* code.
*/
__asm {
ld MININT;
resetch;
ld MININT + 0x10;
resetch;
}
#endif
/* remove debugger protection (which can leave cross rom references) */
debugsetmutexfn(NULL, NULL);
#ifdef APK
/* return to bare machine debug */
debugcommand("runtime c2rtl", &res);
/* stop symbolic lookup for the original rom image */
sprintf(buf, "program -disable -uid 0x%x", _ST_ProgramIdentifier);
debugcommand(buf, &res);
#endif
/* destroy the scheduler and timer queues */
__asm {
ldabc 0, MININT, MININT; // 3개의 변수, 0, 0x80000000, 0x80000000 을 load 한다
swapqueue; // swap scheduler 큐
ldabc 1, MININT, MININT; // 3개의 변수, 1, 0x80000000, 0x80000000 을 load 한다
swapqueue; // swap scheduler 큐
ldab 0, MININT; // 0 과 0x80000000 을 load 한다
swaptimer; // swap timer queue
ldab 1, MININT; // 1 과 0x80000000 을 load 한다
swaptimer; // swap timer queue
}
/* clear the shadow registers */
regs[1] = 0;
__asm {
ldabc 2, 1, regs;
ldshadow; // shadow registers 를 load 한다
}
/* disable all traps (except the debug trap if is it installed) */
if (! debugconnected()) { // debugger 에 연결됨을 결정한다
__asm {
ldab 0xffff, 0; // 0xffff 와 0 을 load 한다
trapdis; // trap disable
ldab 0xffff, 1; // 0xffff 와 1 을 load 한다
trapdis; // trap disable
}
} else { // debugger 에 연결되지 않으면,
__asm {
ldab 0xfffe, 0; // 0xfffe 와 0 을 load 한다
trapdis; // trap disable
ldab 0xfffe, 1; // 0xfffe 와 1 을 load 한다
trapdis; // trap disable
}
}
/* disabling the cache is not pretty, this operation may not be
* supportable on future ST20 architectures so the STLite/OS20
* cache_disable_ operations are currently undocumented features
*/
(void) cache_disable_data(); // EnableDCache 레지스터를 쓰기전에, data cache 를 비활성화 시킴
(void) cache_disable_instruction(); // EnableDCache 레지스터를 쓰기전에, 명령 cache 를 비활성화 시킴
/* jump to the other rom image */
__asm {
ld addr; // addr 의 값을 load 한다 [0x7ffffffe]
ldmemstartval; // Mem Start 주소를 load 한다
gajw; // Workspace 영역
pop; // processor stack 의 POP
gcall;
}
}