### 0.0.1 GCC ARM Embedded Toolchain: Cortex-M 아키텍처 타겟팅 및 링킹(Linking)

### 0.0.1 GCC ARM Embedded Toolchain: Cortex-M 아키텍처 타겟팅 및 링킹(Linking)

이 무자비한 툴체인의 중핵(Core), 실질적인 드론의 맥박을 빚어내는 장인은 바로 GCC ARM Embedded Toolchain이다. 앞서 CMake와 Python 스크립트들이 화려한 청사진을 그려 던져주면, 이 크로스 컴파일러는 오직 외길, 드론 칩셋의 물리적 한계와 아키텍처에 코드를 욱여넣는 혈투를 벌인다. 이 컴파일러가 어떻게 기판(Cortex-M)과 타협하고 링크(Link)하는지 그 타겟팅 문법을 분석한다.

아키텍처 스위치(Architecture Switch)와 부동소수점(FPU) 하드웨어 가속

C++ 소스코드 float a = 3.14 * b; 라는 단순한 식을 만났을 때, x86 호스트 컴파일러는 방대한 연산 유닛을 활용한 어셈블리를 내뱉지만, 소형 ARM 칩에 들어갈 타겟 코드를 짤 때 gcc-arm-none-eabi는 치밀한 스위치 지시어(Flag)에 종속된다.

컴파일러는 CFLAGS로 부여된 코어 지정 옵션(예: -mcpu=cortex-m7)을 보고 자신이 타겟팅할 칩의 한계를 파악한다. 하지만 비행 제어기 추정기(EKF)의 방대한 통계 행렬 연산을 실시간으로 소화하기 위한 최중요 스위치는 바로 하드웨어 부동소수점 유닛 제어인 -mfloat-abi=hard-mfpu=fpv5-d16 등의 FPU 옵션이다.
이 옵션이 걸려 있으면, 실수(Float) 연산을 멍청한 정수 덧셈 반복 루틴 소프트웨어 라이브러리로 풀어서 계산(Soft-float)하지 않고, 칩셋에 각인된 정밀 수학 코프로세서(FPU 하드웨어)로 다이렉트 바이패스 시키는 기계어 명령(FPU Instructions)으로 컴파일한다. 이 크로스 컴파일 플래그 하나가 빠지면 EKF 연산 속도가 수십 배 느려지며, CPU 타임라인이 오버플로우되어 추락의 제물이 된다.

메모리 맵핑(Memory Mapping)과 링커 스크립트(Linker Script, .ld) 결합

수천 개의 파일들이 .o (목적 파일) 형태로 완전히 가공되어 산더미처럼 쌓여도 그것은 프로그램이 아니다. 마지막 관문에서 링커(arm-none-eabi-ld) 컴포넌트가 출현한다.
이 링커를 지휘하는 지휘봉이 바로 소스트리(예: boards/px4/fmu-v6c/nuttx/scripts/) 곳곳에 포진한 **링커 스크립트(.ld 파일)**이다.

이 명세서는 링커에게 보드의 실존 지형을 각인시킨다. “이 칩셋의 Flash ROM 주소는 0x08000000 번지부터 시작하고 크기는 2MB이며, RAM 구역은 0x20000000 번지부터 512KB 존재한다.“라는 무식한 지리 정보가 적혀있다.
링커는 이 공간 정보를 기반으로, 절대로 변하지 않는 읽기 전용 상수 코드(C++ .text, .rodata 섹션)를 Flash의 특정 주소 구간에 차곡차곡 쌓아올리고, 비행 중 계속해서 바뀌어야 할 변수 영역(C++ .data, .bss 섹션) 레이블들을 RAM 주소 한계 구역 내로 퍼즐 맞추듯 끼워 넣는다. 이 거대한 공간 할당의 타겟팅 융합 과정(Linking)이 한 점의 에러 없이 통과해야만, 비로소 플래싱(Flashing)이 가능한 궁극의 펌웨어 구슬이 결집 되는 것이다.