Bare‐metal‐C‐Ch03‐빌드과정과‐GNU툴체인 - Hongjayeong-02/Basic_SoC_implementation GitHub Wiki
(Bare-metal-C-00-필수개념) 00번 페이지 6절에서 요약한 빌드 파이프라인(전처리→컴파일→어셈블→링킹)을 이 챕터에서
arm-none-eabi-*도구를 직접 손으로 호출해서 눈으로 확인한다. IDE가 "Build" 버튼 뒤에서 숨기는 과정을 직접 지휘해보는 것.
IDE에서 "Build" 한 번으로 끝나는 작업이 사실은 다섯 단계로 나뉘어진다는 걸 알면, 링커/링커스크립트 관련 에러(예: "undefined reference", "region overflowed")를 만났을 때 어느 단계에서 문제가 생기는지 바로 감이 온다.
| 단계 | 입력 | 출력 | 도구 | 하는 일 |
|---|---|---|---|---|
| 전처리 | main.c | main.i | gcc -E | #include, #define 치환 |
| 컴파일 | main.i | main.s | gcc -S | C → ARM 어셈블리 |
| 어셈블 | main.s | main.o | gcc -c (내부적으로 as) | 어셈블리 → 목적코드(ELF, 미링크) |
| 링킹 | *.o | *.elf | gcc + 링커스크립트 | 여러 .o를 하나로 합치고 주소 배치 |
| 로케이팅 | *.elf | .hex/.bin | objcopy | 플래시에 그대로 구울 이미지 추출 |
-
전처리기는 C 문법을 모른다. 단순 문자열 치환기라서
#define REG (*(volatile ...)0x40020400)같은 매크로도 그대로 복사-붙여넣기만 한다. -
.elf와.hex/.bin은 용도가 다르다..elf는 디버깅 심볼(함수명, 줄번호 대응 등)까지 포함한 "풀" 파일이고,.hex/.bin은 그 중 순수 메모리 내용만 뽑은, 플래시에 그대로 구울 수 있는 이미지다.
Ch02의 main.c를 그대로 쓰면서, 이번엔 Makefile 대신 스크립트(build.sh)로 단계를 하나씩 직접 호출한다:
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=soft -E main.c -o main.i
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=soft -S main.i -o main.s
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=soft -c main.s -o main.o
arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=soft -T linker.ld main.o startup.o -o ch03_build.elf
arm-none-eabi-objcopy -O ihex ch03_build.elf ch03_build.hex
-mcpu=cortex-m4는 F411/F439 공통(둘 다 Cortex-M4F 코어). 다만 F439ZI는 하드웨어 FPU(FPv4-SP)를 갖고 있으므로, 부동소수점을 쓰는 챕터(Ch06 이후)부터는 -mfloat-abi=hard -mfpu=fpv4-sp-d16로 전환한다. 지금은 정수 레지스터 조작만 하므로 -mfloat-abi=soft로 충분하다.
arm-none-eabi-objdump -d main.o
이 명령으로 main.o 안의 기계어를 다시 어셈블로 "역"변환해서 볼 수 있다. 예를 들어 delay()의 while(count--) 루프가 subs(빼기) / cmp(비교) / bne.n(같지 않으면 분기) 수준의 어셈블로 컴파일되는 것을 직접 확인할 수 있다 — C의 "제어문"이 실제로는 어떤 저수준 명령어로 바뀌는지 보는 가장 직관적인 방법.
-
ch03_build.elf크기:text 252 / data 0 / bss 0— Ch02의 Makefile 빌드 결과와 정확히 동일 (같은 소스, 같은 링커스크립트이므로 당연한 결과). - 이 "동일함" 자체가 검증의 핵심 — Make로 하든 손으로 명령을 치든, 같은 소스/옵션이면 같은 바이너리가 나온다는 걸 직접 확인한 것.
- Q. 빌드 단계 순서는? → 전처리 → 컴파일 → 어셈블 → 링킹 → 로케이팅
-
Q.
.i,.s,.o,.elf는 각각 어느 단계의 산출물? → 전처리(.i) → 컴파일(.s) → 어셈블(.o) → 링킹(.elf) -
Q.
.elf와.hex의 차이는? →.elf는 디버깅 심볼 포함한 "풀" 파일,.hex/.bin은 플래시용 순수 메모리 이미지 -
Q. F439ZI에서
-mfloat-abi=hard를 쓸 수 있는 이유는? → F439ZI는 하드웨어 FPU(FPv4-SP)를 내장
네비게이션: 이전: Bare-metal-C-Ch02-레지스터-직접정의 · Bare‐metal-C-Programming · 다음: Bare-metal-C-Ch04-링커스크립트와-스타트업