0. 링크 스트립트
- 프로그램의 메모리 배치를 정의
- .text, .data, .bss 등의 섹션 위치 및 크기를 지정
- ROM, RAM 주소 지정
- 벡터 테이블, 스택, 힙의 위치를 지정
스타트업 코드
- 시스템이 부팅될 때 초기화 코드 실행
- 벡터 테이블 설정
- .data 섹션을 RAM으로 복사
- .bss 섹션을 0으로 초기화
- 스택과 힙을 설정
- main() 함수 호출
1. .bss 섹션 > 초기화안한 변수에 0 을넣어줌 > 안해주면 쓰레기값이 들어감
> 초기화안한변수는 .bss 안에 넣어야함
2. Vector Table ~= 함수포인터들의 배열
Reset 부터 Main()으로 가는 과정!
/*
STM32 Programmaing manual 참고
+ startup code, linker script, Debug > .map
구조)
RAM : R / W , 저장불가
<> ROM : Read Only , 저장가능
>
_edata, _sdata :: 초기화 O 변수
_sbsss, _ebsss :: 초기화 X 변수
> RAM, 변수이름만 있음
<>
변수의 값 :: ROM 에 저장
>>
RAM 에서 ROM 의 값을 불러옴 or 0 으로 초기화
*/
Reset_Handler:
/* Call the clock system initialization function.*/
bl SystemInit
// 클락을 위한 초기화 한번해주고 돌아옴
/* Copy the data segment initializers from flash to SRAM */
ldr r0, =_sdata // 0x20000000 _sdata
ldr r1, =_edata // 0x200001f0 _edata
ldr r2, =_sidata // 0x0800ab8c _sidata
movs r3, #0 // r3= 0 :: 주소증가용 인자
b LoopCopyDataInit
LoopCopyDataInit:
adds r4, r0, r3 // _sdata 시작주소
cmp r4, r1 // 값비교
bcc CopyDataInit // _sdata 시작주소부터 _edata 를 값비교
// bcc :: r4 >= r1 이면 branch
// :: r4 < r1 을 비교
CopyDataInit: // _sdata가 아직 _edata만큼 못왔다면
ldr r4, [r2, r3] // (ROM에 있는 주소 + 인자)의 값을 r4 에 가져와서
str r4, [r0, r3] // (RAM에 있는 주소 + 인자)의 값에 r4의 값을 넣어줌
adds r3, r3, #4 // 인자를 4byte (word) 씩 늘려줌
// _edata 까지 ROM에 있는 값을 넣어줌
/* Zero fill the bss segment. */ 초기화된 놈들은 값 다 넣어주고 이제 초기화 안된놈들
ldr r2, =_sbss // 0x200001f0 :: 시작주소
ldr r4, =_ebss // 0x20003044 :: 끝주소
movs r3, #0 // 주소 증가용
b LoopFillZerobss
LoopFillZerobss:
cmp r2, r4
bcc FillZerobss // 시작주소~끝주소까지 돌면서 비교
FillZerobss:
str r3, [r2] //
adds r2, r2, #4 // _sbss에있는 값에 4씩(주소) 증가하며 0 을 넣어줌
/* Call static constructors */
bl __libc_init_array
// 라이브러리 초기화 해주고
/* Call the application's entry point.*/
bl main
// 드디어 메인 도착!
>>
Reset > 변수 값들 다 넣고, 초기화 하고 > Main