4장 부팅과정 작성.
부팅을 하기 위해서는 우선 메모리 설계를 먼저 해야한다.
실행 파일은 메모리를 다섯 가지로 나누어 사용한다.
text 영역: 코드가 있는 공간.
data 영역: 전역변수가 있는 공간.
Stack 영역: 지역변수, 함수 복귀 주소가 들어있는 공간.
heap 영역: 코드 실행 중 동적으로 할당하여 사용하는 공간.
이때 stack 영역은 동작 모드별 스택, 테스크 스택 별로 나누며 그림으로 나타내면 다음과 같다.
위 메모리를 실제 정의하는 코드는 다음과 같다.
/*
* MemoryMap.h
*/
#define INST_ADDR_START 0
#define USRSYS_STACK_START 0x00100000
#define SVC_STACK_START 0x00300000
#define IRQ_STACK_START 0x00400000
#define FIQ_STACK_START 0x00500000
#define ABT_STACK_START 0x00600000
#define UND_STACK_START 0x00700000
#define TASK_STACK_START 0x00800000
#define GLOBAL_ADDR_START 0x04800000
#define DALLOC_ADDR_START 0x04900000
#define INST_MEM_SIZE (USRSYS_STACK_START - INST_ADDR_START)
#define USRSYS_STACK_SIZE (SVC_STACK_START - USRSYS_STACK_START)
#define SVC_STACK_SIZE (IRQ_STACK_START - SVC_STACK_START)
#define IRQ_STACK_SIZE (FIQ_STACK_START - IRQ_STACK_START)
#define FIQ_STACK_SIZE (ABT_STACK_START - FIQ_STACK_START)
#define ABT_STACK_SIZE (UND_STACK_START - ABT_STACK_START)
#define UND_STACK_SIZE (TASK_STACK_START - UND_STACK_START)
#define TASK_STACK_SIZE (GLOBAL_ADDR_START - TASK_STACK_START)
#define DALLOC_MEM_SIZE (55 * 1024 * 1024)
#define USRSYS_STACK_TOP (USRSYS_STACK_START + USRSYS_STACK_SIZE - 4)
#define SVC_STACK_TOP (SVC_STACK_START + SVC_STACK_SIZE - 4)
#define IRQ_STACK_TOP (IRQ_STACK_START + IRQ_STACK_SIZE - 4)
#define FIQ_STACK_TOP (FIQ_STACK_START + FIQ_STACK_SIZE - 4)
#define ABT_STACK_TOP (ABT_STACK_START + ABT_STACK_SIZE - 4)
#define IRQ_STACK_TOP (IRQ_STACK_START + IRQ_STACK_SIZE - 4)
#define UND_STACK_TOP (UND_STACK_START + UND_STACK_SIZE - 4)
Stack은 Top에서 Bottom으로 자라는 구조이며 마지막 4Byte를 뺀 이유는 저자가 Stack이 다닥다닥(?) 붙어있는 게 싫다고 하여 분리 하였다. (실제 window 메모리 구조 면 각 메모리 경계에 침범 하였을 시 메모리가 깨지는걸 우려해 Guard page가 있었던거 같다.)
Stack은 동작모드에 맞게 입력 해줘야 하므로 동작 모드 전환 하는 header file을 작성한다.
/*
* ARMv7AR.h
*/
#define ARM_MODE_BIT_USR 0x10
#define ARM_MODE_BIT_FIQ 0x11
#define ARM_MODE_BIT_IRQ 0x12
#define ARM_MODE_BIT_SVC 0x13
#define ARM_MODE_BIT_ABT 0x17
#define ARM_MODE_BIT_UND 0x1b
#define ARM_MODE_BIT_SYS 0x1f
#define ARM_MODE_BIT_MON 0x16
위 모드를 적용하기 위한 코드는 Assembly로 작성되며 다음과 같다.
MRS r0, cpsr
BIC r1, r0, #0x1F
ORR r1, r1, #동작 모드
MSR cpsr, r1
LDR sp, =스택 꼭대기 메모리 주소
CPSR 이란 특수 레지스터를 통해 각각 모드로 전환 할 수 있다.
R1레지스터로 동작 모드를 바꾼다음
Stack 메모리 주소(TOP)를 설정한다. STACK은 TOP에서 Bottom으로 자라기 때문에 Top주소를 넣는다.
'Firmware > RTOS' 카테고리의 다른 글
임베디드 OS 개발 프로젝트 5 (0) | 2020.01.26 |
---|---|
임베디드 OS 개발 프로젝트 A-1 (2) | 2020.01.25 |
임베디드 OS 개발 프로젝트 3 (0) | 2020.01.18 |
임베디드 OS 개발 프로젝트 2 (0) | 2020.01.18 |
임베디드 OS 개발 프로젝트 1 (1) | 2020.01.18 |