* ARM processor
- word : CPU가 한번에 처리할 수 있는 크기
- Thumb mode : 32 bit ARM에서 돌아가는 16bit 기계어, ARM 명령어들을 16bit로 압축한 명령어 set
- ARM Mode
Mode | 약자 | 설명 | |
Normal mode | User | USR | Normal Program execution mode |
Privileged mode |
System | SYS | Run privileged operating system tasks |
Fast Interrupt Request | FIQ | When a high priority fast interuppt is raised | |
Interrupt Request | IRQ | When a low priority normal interrupt is raised | |
Supervisor | SVC | A protected mode for the operaing system, entered when a SWI(소프트웨어인터럽트) instruction is executed | |
Abort | ABT | Used to handle memory access violations | |
Undefined Instruction | UND | Used to handle undefined instructions |
- Privileged Mode는 IRQ나 FIQ 등의 Interrupt의 사용 가능 유무를 직접 설정할 수 있다.
- Privileged Mode는 자기들끼리, 자기네들 스스로 서로 Mode 변경이 가능하다. Normal Mode는 자기 스스로 Privileged Mode로 Mode 변경이 불가능하다.
- ARM의 default mode는 SCV mode이다. 여기서 출발해야 boot up시에 ARM에 대한 모든 권한을 행사할 수 있으니!
* Compile
*.c arm-elf-gcc C compiler |
*.o |
linker.ld arm-elf-gcc or arm-elf-ld Linker |
*.elf |
arm-elf-objcopy Object copy |
*.bin |
*.s arm-elf-as Assembly compiler |
- elf : 헤더, 바이너리, 심볼 3개의 파트로 나뉘어짐
. 헤더 : 파일의 구성을 나타내는 로더맵 역할
. 바이너리 : 실제 타켓 플래시 메모리에 올라가는 실행할 수 있는 코드로 구성
. 심볼 : 디버깅을 위한 정보로 개발자가 정의한 함수나 변수들이 실제 메모리 주소와 일치가 되도록 매핑
* Startup.S
- 부팅 과정 중 가장 첫번째 단계를 맏고 있는 파일로 *.s 어셈블리언어로 만든 소스
. 왜 어셈블리 언어로?
1. 인터럽트 처리는 개발자 몫인데, 인터럽트는 자주 발생되니까 최대한 빨리 적게 개발하는 방법으로 실행 코드 수를 줄이는 방법으로 선택
2. 메모리 컨트롤러 레지스터 설정과 스택 주소 할당을 위해서. main 함수도 C언어로 만들었기에 스택 영역이 필요하고, 스택 할당 전 SDRAM이 읽고 쓰기가 가능해야하기 때문에 스택 영역 할당 전 메모리 컨트롤러 레지스터에 데이터 값을 넣어 초기화.
- 익셉션 벡터, 인터럽트 disable, PPL(Phase Looked Loop), SDRAM 초기화, 스택 영역 할당, 변수 초기화, C언어의 main 함수 진입 등을 어셈블리 언어로 만든다.
- 익셉션 벡터 : 임베디드 시스템이 리셋되거나 인터럽트 발생시 ARM core는 고정된 주소로 점프한 후 개발자가 지정한 주소로 다시 점프해서 프로그램이 흘러가도록 함
- 인터럽트 disable : 임베디드 시스템 부팅 초기가 매우 중요하기 때문에 그 순간 만큼은 인터럽트를 받지 않기 위함
- PLL 설정 : CPU와 각종 디바이스에 클럽 설정하기 위함
- 메모리 클러스터 설정 : CPU가 SDRAM 메모를 읽기, 쓰기할 수 있도록
- main 함수 진입 : CPU가 SDRAM에 읽기 쓰기가 가능해지면 C 프로그램이 동작하기 위한 스택 영역 지정 후 C언어의 main으로 점프한다.
- startup.s와 main.c 파일을 컴파일하면 누가 먼저 실행되어야할지를 linker.ld라는 링크 스크립트에서 결정할 수 있다. : ENTRY(_start) -> startup.s에 있는 레이블
* Makefile
- 빌드 과정을 한번 만에 할 수있도록 제공
- 프리웨어인 ARM-GCC, 상용 컴파일러 ADS
- startup.o와 main.o를 가지고 링크 시켜야함, 이 과정 후 *.elf 파일 생성, 링크시켜주는 파일은 arm-elf-ld인데, 컴파일러 버전에 따라 arm-elf-gcc에서도 링크 역할해줌
- 구성 : source file name / compiler name / assembler compiler option / c compiler option / compile command
## File Definition ## PRJ = general INIT1 = Startup CM1 = main ## Destination path Definition ## PRE = arm-elf SOURCE=./sources/ ## ARM tool Definition ## ARMASM = $(PRE)-as ARMCC = $(PRE)-gcc ... ## Option Definition ## AFLAGS = -marm9tdmi -EL -M --gdwarf2 CFLAGS = -B$(GCC_EXEC_PREFIX) -g -gdwarf-2 -Oo -c -mcpu=arm9tdmi -mlittle-endian -mapcs-frame -mno-apcs-stack-check LFLAGS = -Bstatic -nostartfiles -Xlinker --script=linker.ld -lc OBJS = $(INIT1).o $(CM1).o $(PRJ).elf: $(OBJS) $(ARMLINK) $(LFALGS) -o $(PRJ).elf $(OBJS) $(ARMOBJCOPY) $(PRJ).elf --output-target=binary $(PRJ).bin .. all: clean $(PRJ).elf clean: rm -f *.o ...... |
* 링커 스크립트(Linker Script) 파일
- 컴파일을 하고 나면 오브젝트 파일이 만들어 질 때 4개의 독립된 영역으로 나누어 진다 : 코드 / 데이터 / 힙/ 스택
- 링크 스크립트는 섹션 영역의 start와 end 영역을 지정, 개발자가 링크 스크립트를 만들 때 임베디드 제품의 메모리 맵을 확인한 다음 각 섹션 영역을 어떻게 나눌 것인지 결정한 후 만든다.
- 일반적으로 .text_start와 .data_start 그리고 .bss_start 주소를 지정해주면 된다.
- arm-elf-size general.elf : 해당 섹션 영역의 사이즈를 알 수 있다.
- 어떤 컴파일을 사용하느냐에 따라 스케트(Scatter) 파일 또는 링크 스크립트 파일이라고 부른다.
- 만드는 방법
1. MCU 데이터 시트를 열어서 메모리 맵 확인 : 플래시 메모리 시작 주소와 사이즈, SDRAM 시작 주소와 사이즈 확인
2. 메모리 영역을 어떻게 나눌 것인지 결정 : 플래시 메모리에는 코드영역과 데이터영역 지정, SDRAM 영역은 주로 BSS(Block Started Segment)의 시작 주소 지정
- 힙 영역은 링크 스크립트에서 따로 지정하지 않아도 됨. malloc 함수 자체가 자동으로 .bss_end+4 주소 이후로 잡아준다.
-ARM 프로세서에서 스택은 상위주소에서 하위주소로 증가, Heap은 하위 주소에서 상위 주소로 증가.
- 스택 영역 시작 주소 지정은 linker.ld에서 하지 않고 startup.s에서 지정
* RTOS, Embedded OS
- Kernel : Context Switing, Scheduling, Memory Management, ISR Management 등을 담당하는 부분을 따로 떼어서 Kernel이라고 부른다. Task, Process 등이 Kernel에게 Service를 받기 위해 Kernel API를 부르던가, Interrupt가 걸려서 Interrupt 처리할 때 Interrupt 처리 routine의 끝에 Kernel API가 불리던가 하는 등으로 Kernel 활성화
'개발 > System' 카테고리의 다른 글
특정 파일 UTF8 ↔ ANSI 변환 (0) | 2013.08.24 |
---|---|
UNIX의 디렉토리 (0) | 2012.10.29 |
파일 정보의 획득 (0) | 2012.10.29 |
다수의 이름을 갖는 파일 (0) | 2012.10.29 |
access, chmod, chown 시스템 호출 (0) | 2012.10.29 |