크로스 컴파일러
보통의 컴파일러는 실행하는 컴퓨터와 컴파일하는 컴퓨터가 동일하다 하지만 임베디드 환경에서는 컴파일하는 곳과 실행하는 컴퓨터가 상이하다. 때문에 특별한 컴파일러가 필요하고 이를 크로스 컴파일러라고 푸른다.
이러한 차이는 pc 에서 쓰는 cpu 와 임베디드에서 사용하는 cpu 가 달라서 똑같은 기능을하는 실행파일( 바이너리파일) 이라도 cpu 에 따라서 다르게 생성되기 때문이다.
크로스 컴파일러가 실행되는 과정
결국 .c 파일과 .S 파일로 만들어진 오브젝트 라일을 통해서 링킹 작업을 통해 ,elf(실행파일) 을만든다.
( 어셈블 언어로는 C 언어에서는 처리하지 못하는 부분을 해준다. 스택 만들기 메모리 segment 등등 )
elf 파일은 -> 디버깅을 위한 파일이다.
디버깅을 위한 타겟의 메모리 주소와 개발자의 프로그램 소스와의 연관 정보를 갖는 주소 Format이랍니다. 헤더, 바이너리, 심볼 3개의 파트로 나누어져 있으며, 헤더에는 파일의 구성을 나타내는 로더맵(Load Map)과 같은 역할을 하지요. 바이너리는 순수하게 실행할 수 있는 코드만으로 구성되어 있으며 실제 타겟 플래시 메모리에 올라가게 되죠. 마지막으로 심볼 정보는 디버깅을 위한 정보랍니다.
여기 elf 파일에서 실제로 arm 에 올라가 바이너리 파일만 뽑아내는 것이 오브젝트 카피 컴파일러 유틸리티를 통해서 .bin 파일이 만들어진다.
스타트업(Startup.S) 파일 -> 어셈블리 컴파일러에서 컴파일 되는 파일
아까 이파일은 c 언어에서 못하는걸 하는 친구라고 했다. 하지만 어셈블리언어를 쓰는 또하나의 이유가 있는데 인터럽트 처리 때문이다.
인터럽트는 굉장히 빈번히 발생하기 때문에 1byte 라도 코드수가 줄어들면 엄청난 이득이다. 때문에 이러한 인터럽트 처리에 대한 부분을 어셈블리 언어에서 담당한다.
- arm 의 경우 IRQ , FIQ 인터럽트가 존재하는데 이에 대해서 어떻게 처리할지 어셈블리 언어로 짜여진다.
처음으로 돌아가서 c 언어에서 못하는 부분은 메모리 컨트롤러 레지스터 설정과 , 스택 어드레스 할당이다. c 언어가 돌아가기 위해서는 스택이 필요하다. 이러한 스택을 만들어 주는 녀석이 어셈블어로 작성된 Startup.S 파일이다.
또한 스택은 sdram 안에 만들어져야 하는데 cpu 가 sdram 에 접근못한다면 어불성성이다. 대문에 메모리 컨트롤러 레지스터 설정을 통해서 cpu 가 sdram 에 접근하게 해주는 등의 일은 먼저 해야한다.
Startup.S 파일에서 하는 자세한 일
(익셉션벡터, 인터럽트 디세이블(Disable), 피엘엘(PLL), 에스디램 초기화, 스택 영역 할당, 변수 초기화,
씨 언어의 메인 함수 진입 )
1. 익셉션벡터 : 여러가지 인터럽트가 발생했을대 암코에서 지정된 고정 어드레스로 점프하도록 해주는 주소
2. 모든 인터럽트 디스에이블: 부팅 초기는 굉장히 중요한 순간이기 때문에 인터럽트가 발생하지 않도록 해주어야한다.
3. pll(피엘엘) 설정 : 각종 클럭 설정
4. 메모리 컨트롤러 설정 : cpu 가 sdram 에 읽고, 쓰기가 가능하도록 해준다.
5. 스택 영역 할당 : c 언어가 동작하기 위한 스택 영역 생성
6. 씨언어 메인함수 콜 :
cf) Startup.S 파일의 위치
앞에서 다뤘듯이 낸드 플레시 메모리는 메모리 주소가 없어서 실행코드를 바로 실행할수 없다 때문에 부트로더가 존재한다. 이 부트로더 안에 Startup.S 파일이 존재해야한다.
MakeFile
구조
##### File Definition #### 마지막에 만들어지는 파일이름 gerneral.elf,Sartup.o,main.o
PRJ = general
INIT1 = Startup
CM1 = main
#### Destination path Definition ####
PRE=arm-elf
SOURCES=./sources/
#### ARM tool Definition #### 컴파일러 정의
ARMASM = $(PRE)-as
ARMCC = $(PRE)-gcc
ARMLINK = $(PRE)-gcc
ARMSIZE = $(PRE)-size
ARMOBJCOPY = $(PRE)-objcopy
#### Option Definition #### 각각의 컴파일러에 대한 옵션
AFLAGS = -marm9tdmi -EL -M --gdwarf2
CFLAGS = -B$(GCC_EXEC_PREFIX) -g -gdwarf-2 -O0 -c -mcpu=arm9tdmi -mlittle-endian -mapcs-frame -mno-apcs-stack-check
LFLAGS = -Bstatic -nostartfiles -Xlinker --script=linker.ld -lc
OBJS = $(INIT1).o $(CM1).o # 마지막에 생설될 오브젝트파일 , elf 파일 bin 파일
$(PRJ).elf: $(OBJS)
$(ARMLINK) $(LFLAGS) -o $(PRJ).elf $(OBJS)
$(ARMOBJCOPY) $(PRJ).elf --output-target=binary $(PRJ).bin
$(ARMSIZE) $(PRJ).elf
all: clean $(PRJ).elf # bin 파일 뺴고 필요없는 오브젝트파일 elf 파일 삭제
clean:
rm -f *.o
rm -f $(PRJ).src
rm -f $(PRJ).elf
$(INIT1).o: $(SOURCES)$(INIT1).s
$(ARMASM) $(SOURCES)$(INIT1).s $(AFLAGS) -o $(INIT1).o
$(CM1).o: $(SOURCES)$(CM1).c
$(ARMCC) $(CFLAGS) $(SOURCES)$(CM1).c -o $(CM1).o
'공부,일 > 임베디드 스케치' 카테고리의 다른 글
임베디드 스케치 3장 -2 (0) | 2021.09.03 |
---|---|
인베디드 레시피 -2 , 시스템 hardware 구성요서 (0) | 2021.09.02 |
인베디드 관련 공부 사이트 (0) | 2021.09.01 |
댓글