지난 글에서 ARM 코어는 전원 인가시 가장 먼저 0x00에 위치한 리셋 익셉션 핸들러를 호출한다고 했던거 같은데
리셋 익셉션 핸들러는 메모리 맵을 우선 설정해줘야 한다고 한다.
동작 모드별 메모리맵 설정이 끝난 후 C 언어 main으로 진입
https://ggamji.tistory.com/113
위 글에서 ARM의 7개의 동작 모드와 메모리 맵을 그렸는데
리셋 익셉션 핸들러에서 각 동작 모드를 돌아가며 스택을 초기화 시키도록 코드를 구현하자
#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_START_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 UND_STACK_TOP (UND_STACK_START + UND_STACK_SIZE - 4)
include/MemoryMap.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
include/ARMv7AR.h 도 구현
각 동작 모드별로 비트가 다른데
프로그램 상태 레지스터 PSR에서 이런 상태를 보관하는데
현재 상태를 저장하는 레지스터로 CPSR(Current PSR)
상태를 저장하는 레지스터로 SPSR(Saved PSR)이 존재한다.
아래 그림은 cortex-a8의 PSR로
여기서 M[4:0]이 모드비트인데
위 ARMv7AR.h 헤더에 구현한데로 저 자리에 다음의 값이 들어갈때 동작모드가 변경되며,
익셉션이 발생 시 하드웨어가 알아서 바꾼다.
10000 : USR
10001 :FIQ
....
11011 : UND
11111 : SYS
ARM 동작 모드
- 익셉션과 관련된 동작모드와 관련되지 않은 동작모드가 있음
- User 모드 USR : ARM 상태나 Thumb 상태로 동작하며 일반적으로 이 모드로 동작
- Fast Interrupt 모드 FIQ : FIQ 익셉션 발생시 전환. 이 모드는 ARM 상태서만 동작. 뱅크드 레지스터가짐
- 인터럽트 모드 IRQ : IRQ 익셉션 발생시 전환. ARM 상태와 Thumb 상태 둘다 동작
- Supervisor 모드 SVC : 운영체제가 시스템 콜 호출하기 위한 보호모드. 호출시 SVC 모드로 변경후 수행.
- Abort 모드 ABT : 어보트가 발생시 동작
- System 모드 SYS : 사용자 프로세스가 커널 모드가 필요할때 사용. 소프트웨어로 전환 가능
- Undefined 모드 und : 정의되지 않은 명령어 발생시 진입
* 뱅크드 레지스터 : 빠른 처리를 위한 별도 레지스터
ARM 레지스터
- 각 동작마다 고유의 뱅크드 레지스터와 공유되는 레지스터가 존재
- 공유되는 레지스터 = 범용 레지스터(R0 ~ R12) + R15(PC) + CPSR
- 모드 별 뱅크드 레지스터는 아래 그림 참조
- R13 : 스택 포인터
- R14 : 링크 레지스터로 서브 루틴 호출시 리턴어드레스 보관
- R15 : 프로그램 카운터
'컴퓨터과학 > os' 카테고리의 다른 글
navilos - 7. UART 1 (0) | 2022.08.18 |
---|---|
navilos - 6. 익셉션 핸들러 구현2, 메인함수 진입 (0) | 2022.08.18 |
navilos - 4. 어셈블리어 공부하며 본 초기코드 (0) | 2022.08.17 |
navilos - 3. 메모리맵 (0) | 2022.08.17 |
navilos - 2. 펌웨어 만들고, 빌드 자동화 (0) | 2022.07.17 |