1)
우리 나름대로의 Stack과 Heap을 사용하게됨
> 자동으로 Compiler가 만들어주는 Stack과 Heap은 안씀
"그런데, 우리가 만들어낸 image의 ZI에 포함되지 않는 여기서의 Stack과 Heap은 도대체 뭐냐!
Default Memory model > RO, RW, ZI : Application 하나 올린것
<> Embedded OS (또는 Kernel)같은 복잡한 것이 porting되지 않았음
> Application이 사용하는 Stack과 Standard Library가 사용하는 (malloc같은) Heap인것
> Compiler가 알아서 Stack과 Heap영역을 만들어줌
/*
스택(stack) 영역
함수의 호출과 관계되는 지역 변수와 매개변수가 저장되는 영역
> 함수 종료시 소멸
푸시(push) > 데이터 저장, 팝(pop) 동작 > 데이터 인출
후입선출(LIFO, Last-In First-Out) > 늦게 저장된게 가장 먼저 인출
스택 영역은 메모리의 높은 주소에서 낮은 주소의 방향으로 할당 // 아래에서 위로
힙(heap) 영역
사용자가 직접 관리할 수 있는 ‘그리고 해야만 하는’ 메모리 영역
> 동적 할당되고 해제됩니다.
선입선출(FIFO) 낮은 주소에서 높은 주소의 방향으로 할당됩니다. // 위에서 아래로
*/
ScatterLoading > compiler가 만드는 몇개의 symbol 무시 .
Image$$RW$$Base
Image$$RW$$Limit
Image$$RO$$Base
Image$$RO$$Limit
Image$$ZI$$Base
Image$$ZI$$Limit
> Generation X
> because ) Scatter Loading에서 이미 명시한 Region에 대한 RW, RO, ZI의 Base, Limit을 만들어 내므로
ex)
Scatterloading 사용 X > stack과 heap이 자동으로 정해짐
Compiler 가 자동으로 Stack, Heap 만들어 낼 때 > 자기가 만든 Symbol 참조
> Image$$ZI$$Base, Image$$ZI$$Limit > Stack, Heap만들어냄
// Base : 낮은주소 > 높은주소 :: HEAP
// Limit : 높은주소 > 낮은주소 :: STACK
ZI영역 더 위쪽에 Stack과 Heap을 임의로 만들어냄
> rt_entry에 진입 > C Library안에 __user_initial_stackheap()이라는 함수에서 처리
Image$$ZI$$Base(Limit) Symbol이 없음 > Linker : 마지막에 Link Error
이럴땐 > 우리가 __user_initial_stackheap()라는 함수를 재정의 해줘야함
// Bootup중에 꼭 들리는 함수
__userInitial_stackheap() 함수의 원형
------------------------------------------------------------------------------------------------------------
#include
__value_in_regs struct __initial_stackheap
__user_initial_stackheap (unsigned R0, unsigned SP, unsigned R2, unsigned SL)
------------------------------------------------------------------------------------------------------------
보통 Scatter loading을 사용하고, 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; // 0x1000
config.stack_base = (unsigned)_initial_stack + sizeof(_initial_stack) - 1; 0x1400
config.heap_limit = (unsigned)_initial_heap + sizeof(_initial_heap) - 1; 0x1399
config.stack_limit = (unsigned)_initial_stack; 0x 1400
return config;
}
// heap : 낮 > 높
: 낮은 주소 일수록 더 먼저 저장됨 > 흔히 알던 방식
// stack : 높 > 낮
: 높은 주소 일수록 더 먼저 저장됨
> limit 가 기준으로 stack 공간만큼 더한것 = base
-----------------------------------------------------------------------------------------------------------
config라는 구조체에 값을 넣어주면 lib이 알아서 init을 해줌
> lib과의 통신을 위해서 정해져 있는 형식임
'임베디드 > 임베디드 레시피' 카테고리의 다른 글
Pointer (0) | 2024.12.04 |
---|---|
Context와 AAPCS (0) | 2024.12.03 |
Reset Handler에서 main까지 (Entry Point) (0) | 2024.12.01 |
Coprocessor Assembly (0) | 2024.11.27 |
SWI 의 진실 (0) | 2024.11.26 |