도와주세요!!
글 수 15,339
2005.12.19 14:25:58 (*.4.218.18)
6670
>안녕하세요..부트로더를 분석하다가 이해가 안되는 부분이 있어서 이렇게 질문을 올립니다.
>ez_m01부트로더 start.s에서
>bl MemClear
>bl LoaderRamCopy
>이부분에서 부트코드를 램에 다운로드 시킵니다.그런데
>ldr r0, =EZ_M01_RAM_BOOT
>add r0, r0, #0x400
>mov pc, r0
>이부분에서 0x400을 더해주는데 start.o파일은 용량이 1킬로바이트가 넘는데,
>0x400이상을 더해주는게 맞는거 같은데..그런데 코드나 스크립트 파일을 보면은
>0x400을 더해주어서 main으로 가게 되있습니다.
>그러면 start코드 영역하고 main하고 겹쳐지지 않나 생각이 듭니다.
>왜 여기서 0x400을 더해주는지 알고 싶습니다.
0x400 = 1024 = 1k
0x800 = 2048 = 2k
부트로더에서 start.s -> start.o -> start.org
마지막 start.org 의 크기에 따라서 1k보다 작으면 0x400, 2k보다 작으면 0x800 아닐까요
start.org 가 1k보다 큰데도 0x400 오프셋을 적용햇다면 에러가 날것같고요
예전에 작은 start.org를 가지고 작업할때 썻던 오프셋이 아닐까 추측해봅니다.
인용 < 부트로더의 기본구현 1 - 유영창 > 중에서 발췌
어셈블러 구현 루틴과 C 함수 구현 루틴의 차이
부트로더를 어떤 언어로 구현하는가는 프로그래머가 어떤 언어를 더 자유롭게 구현하는가에 달린 문제이다. 꼭 C 언어로 부트로더를 구현할 이유는 없다. 하지만 부트로더를 C 언어로 구현하면 어느 정도 아키텍처에 의존적인 부분을 줄여서 작성할 수 있다. 필자는 ARM에서 사용한 부트로더인 ‘이지부트’를 i386EX에도 적용한 적이 있다. 이때 ARM에서 사용된 C로 작성된 부분 중 초기화 부분 이외에는 그대로 사용이 가능했다.
초기에 부트로더를 만들기 위해서는 다른 부트로더의 소스에서 루틴을 가져오거나 커널 소스에 있는 루틴을 가져오게 된다. 이렇게 다른 소스를 가져와 사용할 때는 아무래도 어셈블러보다 C 언어가 유리하다. 결국 C 언어로 부트로더를 작성하는 것이 여러모로 유리하기 때문에 대부분의 공개된 부트로더는 C 언어로 사용된다. 그런데 C 언어는 함수 호출 구조상 스택(stack)이라는 것이 필요하다. 그러나 스택은 롬 시스템에서는 원초적으로 사용이 불가능하다. 따라서 C 언어로 작성된 프로그램은 램에서 동작하여야 한다. 부트로더는 이런 언어적인 차이도 롬으로 동작하는 것과 램에서 동작하는 것으로 나누어야 하는 이유가 된다.
이런 이유로 EZ-X5에서 동작하는 이지부트 프로그램은 start 프로그램과 main 프로그램으로 나누어져 있다. start 프로그램은 어셈블러로 작성되어 있고 아주 기초적인 부분을 수행한다. main은 C 언어로 작성되어 있고 start 프로그램에서 구현한 것 외의 나머지 대부분을 구현한다. 각각 만들어진 두 개의 프로그램 소스는 컴파일되고 실행 이미지가 따로 만들어진다. 이후에 하나의 이미지로 합쳐져 플래시 롬에 써넣게 된다. 이렇게 합쳐진 프로그램 중에서 리셋 후에 처음 동작하는 것을 이지부트에서는 start란 프로그램이 담당하고, 스택이 설정되어 C 함수 호출이 가능한 램 공간에서 수행되는 대부분의 작업은 main 프로그램이 담당한다.
이지부트가 어떻게 동작하는지 <그림 1>을 가지고 설명하겠다. 그림에서 보듯이 EZ-X5의 플래시 롬은 0x00000000에 위치한다. start 프로그램은 2KB 이내로 매우 작은 크기를 갖고 있다. main 프로그램은 그 나머지를 차지한다. 플래시 롬에는 이 두 개의 프로그램이 연속되어 있는 하나의 이미지로 만들어져 배치된다. 이 이미지는 리셋 후 start 프로그램에 의해서 <그림 1>의 (1)에서 보듯이 램의 0xA0F00000에 그대로 복사된다. 램은 0xA000000부터 시작하는데 나중에 배치되는 커널을 고려해서 램의 뒤쪽에 부트로더를 둔다.
<그림 1> 이지부트의 동작 방식
main 프로그램은 수행 시작 위치가 0xA0F00800로 고정된다. 이 위치는 램에 같이 복사된 2KB를 차지하는 start 이미지 바로 뒤쪽이다(예전에 어떤 사람이 필자에게 2KB를 제외한 크기를 램에서 복사하지 않는가 물어본 적이 있다. 하지만 이렇게 하는 특별한 이유가 있는 것은 아니다. 단지 필자가 게으르기 때문인데, 2KB를 제외하면 실제 크기를 계산해서 프로그래밍해야 하지만 그대로 하는 것이 정신건강(?)에 유리하기 때문이다). 부트로더는 부팅이 끝나면 그대로 사라지는 프로그램이기 때문에 부득이 램의 크기가 작은 시스템이 아니라면 굳이 메모리를 아낄 필요는 없다.
롬에서 동작하는 start 프로그램은 초기화를 마치고 main으로 이동해야 하는데 두 프로그램은 같은 프로그램이 아니기 때문에 소스상의 심볼릭 참조가 불가능하다. 즉 소스에서 어떤 함수로 이동하라는 식의 기술이 곤란하다. 그래서 절대 위치로 이동하는 명령을 사용하는데 이동 위치가 <그림 1>의 (2)와 같이 0xA0F00800이 된다.