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; } }