본문 바로가기
Scatter Loading과 Bootup - __user_initial_stackheap

Scatter Loading에 관련해서 이젠 좀 익숙해 졌겠지요. - 과연 - Scatter Loading을 사용하게 되면 몇 가지 주의해야 할 점이 있어요. 쫌 알면 쉬운 거지만, 쫌 모르면 헤맬 만한 이야기에요. 유후~

첫 번째로 ScatterLoading을 사용하게 되면 우리는 우리 나름대로의 Stack과 Heap을 사용하게 되지요. 자동으로 Compiler가 만들어주는 Stack과 Heap은 안 쓴다 구요. "ScatterLoading"편에서 그런 말을 한적이 있지요.

"그런데, 우리가 만들어낸 image의 ZI에 포함되지 않는 여기서의 Stack과 Heap은 도대체 뭐냐! 지금 말하고 있는 메모리 Model이 Default Memory 모델임을 잊지 마시고, 현재 RO, RW, ZI는 Embedded OS (또는 Kernel)같은 복잡한 것이 porting되지 않은, Application 하나 올린 거라고 생각하시면 됩니다. 그러니까, 그 Application이 사용하는 Stack과 Standard Library가 사용하는 (malloc같은) Heap인겝니다. Compiler가 알아서 Stack과 Heap영역을 만들어 준다고나 할까요. "

ScatterLoading을 사용하게 되면, 무시되는 Symbol이 몇 개 있어요. Compiler 지가 알아서 만들어 내는 Symbol중에,

Image$$RW$$Base
Image$$RW$$Limit
Image$$RO$$Base
Image$$RO$$Limit
Image$$ZI$$Base
Image$$ZI$$Limit

요것들을 Generation하지 않아요. 왜냐하면 Scatter Loading에 명시한 Region의 이름에 대한 RW, RO, ZI의 Base, Limit을 만들어 내니까 글쵸.

예를 들어서, Scatterloading을 사용하지 않는 경우에는 stack과 heap이 자동으로 정해지는 데, 이 자동으로 정해지는 부분은 아래와 같이 다시 구현되어 있다고 보시면 되어요.

원래 Compiler 지가 알아서 Stack과 Heap을 자동으로 만들어 낼 때는 지가 만들어낸 Symbol을 참조하는데요, 여기에 이용 되는 것이, 예를 든 Image$$ZI$$Base, Image$$ZI$$Limit 요거 두 개를 이용해서 Stack과 Heap을 만들어 내는 거죠. ZI영역 더 위쪽에 Stack과 Heap을 임의로 만들어 내는데 요 일을 하는 게, rt_entry에 진입하고 나서 C Library안에 __user_initial_stackheap()이라는 함수에서 하게 되어요. Image$$ZI$$Base(Limit) Symbol이 없으니까, 당연히 Linker가 마지막에 Link Error를 내겠죠. 이런 경우에는 우리가 __user_initial_stackheap()라는 함수를 재정의 해줘야 하는 거에요.

__userInitial_stackheap()함수의 원형은

#include
__value_in_regs struct __initial_stackheap

__user_initial_stackheap (unsigned R0, unsigned SP, unsigned R2, unsigned SL)

으로 생겼구요.

보통 Scatter loading을 사용하고, RTOS를 사용하는 경우에는 (RTOS를 사용하는 경우에는각 Software Module이 자기 자신의 전용 Stack을 따로 쓰는데요, 다음에 나오는 RTOS쪽을 보시면, 이해 되실꺼에요 음)

__value_in_regs struct __initial_stackheap

__user_initial_stackheap(unsigned R0, unsigned SP, unsigned R2, unsigned SL)
{
     return;
}

요렇게 구현하죠. 그런데, 굳이! 이런 initial stack과 heap을 만들어 주고 싶으면,

char _initial_heap[0x2000];
char _initial_stack[0x2000];

__value_in_regs struct __initial_stackheap

__user_initial_stackheap(unsigned r0, unsigned sp, unsigned r2, unsigned sl)
{
    struct __initial_stackheap config;

    config.heap_base = (unsigned)_initial_heap;
    config.stack_base = (unsigned)_initial_stack + sizeof(_initial_stack) - 1;
    config.heap_limit = (unsigned)_initial_heap + sizeof(_initial_heap) - 1;
    config.stack_limit = (unsigned)_initial_stack;
    return config;
}

요런 특별한 방법으로 config라는 구조체에 값을 넣어주면 lib이 알아서 init을 해준답니다요. 요건 lib과의 통신을 위해서 정해져 있는 형식이니까 왜 이렇게 짜나요? 하고 질문하면 곤란해요.
뭐 이렇게 만들어줘도 되고요. __user_initial_stackheap()이라는 함수는 Bootup중에 꼭 들리는 함수이니까, RTOS Kernel이 자기가 쓸 heap과 stack을 init하는 트릭을 쓰기도 하고
뭐 그런거죠.

 
Linked at 임베디드 시스템 개발자 되기 .. at 2009/07/16 20:26

... ; ⓚ Reset Handelr에서 main (Entry point)까지 ⓛ Scatter Loading과 Bootup - __user_initial_staqckheap 5) Software 비네팅 (Vinetting) ⓐ Context ... more

Linked at 황씨의 정신줄 보관함 : Sc.. at 2009/08/24 20:17

... itial_stackheap()은 뭐지?이 궁금증은 "친절한 임베디드 시스템 개발자 되기 강좌"라는 블로그를 운영하시는 히언님 덕분에 완벽하게 해결되었다. http://recipes.egloos.com/5045581 히언님께 펌에 대한 허락을 받고 퍼오고 싶었으나, 댓글마저 블락이 되어 있어서.. 이렇게 링크만 건다. 절대..절대.. 블로그 문닫지 마세 ... more

친절한 임베디드 시스템 개발자 되기 강좌 글 전체 리스트 (링크) -



댓글





친절한 임베디드 개발자 되기 강좌 글 전체 리스트 (링크) -