JINTBEAT Design Life

Linker - (2) 본문

🖥️ - ARM

Linker - (2)

jintbeat_design 2026. 4. 9. 00:36
반응형

개요 : 현재 Zynq zybo z7-20을 가지고 짬이 날 때, 이런 저런 Test를 하는 중이다. 분명 처음 이 보드를 사용할 때는 아무것도 몰라도 프로그램이 정상적으로 실행되었었다. 한 5년만에 다시 실행해봤더니 실행이 안된다. 그 이유를 디버깅하다 Linker Script 공부를 시작하게 되었다. 그 중 rodata를 DDR로 할당하면 printf가 깨졌던 적이 있다.

 

.rodata 자체는 읽기만 하면 되니까 DDR에 있어도 원리상 문제는 없다. 

 

> 그런데, DDR이 아직 초기화되지 않은 시점에 .rodata를 읽는 코드가 실행되면 바로 깨질 수 있다. 

> printf가 대표적인 희생자이다.

const char *msg = "Hello World";
const int table[4] = {1,2,3,4};

> 이런 건 실행 중에 바뀌지 않기 때문에 굳이 RAM으로 복사할 필요 없이 그냥 Flash / ROM / DDR 어디 읽기 가능한 곳에 있어도 됨.

 

그런데 왜 printf가 죽을 수 있나 ?

> printf("hello\n")에서 "hello\n" 문자열 자체가 .rodata에 있기 때문

 

printf("Hello World\n");

컴파일러는 보통 이 문자열을 이렇게 둔다.

.rodata:
  "Hello World\n"
  
  그리고 실제 코드는 대략 이런 느낌
  
  printf(0x00123456);   // "Hello World\n" 문자열 주소 전달

 

> 즉, CPU에서는 

> 1. .text에서 printf() 호출

> 2. 인자로 넘길 문자열 주소를 읽음

> 3. 그 문자열 내용을 읽어서 UART로 보냄.

 

그런데, .rodata가 DDR에 있고, DDR init이 안되어 있으면 ?

> CPU가 이 문자열을 읽으려는 순간, read DDR Address가 실패할 것이다.

> 그 결과는 여러 형태로 나올 수 있다.

> 그냥 멈춤 (bus hang)

> data abort / exception

> 이상한 문자 출력

> printf() 안 나온 것처럼 보임

 

printf가 자주 읽는 것들
printf("count = %d\n", x);

> count = %d\n → .rodata

 

Startup code는 뭐지 ?
Reset
 ↓
Startup Code
 ↓
C Runtime Init
 ↓
main()
 ↓
네가 작성한 FW Code

 

> FW code(main.c, driver.c, app logic)은 startup 이후에 실행된다.

> 보통 reset 직후 CPU가 제일 먼저 실행하는 코드이다.

> 이 코드는 대개 startup.s, crt0.S, vectors.s로 되어 있다. 

 

CPU가 reset되면, 바로 main()으로 jump하지 않기 때문에 따로 필요하다.

> 초기 상태는

> SP(스택 포인터) 설정 안됨.

> RW(.data) 복사 안됨

> ZI(.bss) 초기화 안됨

> 인터럽트 벡터 설정 필요

> 즉, C 코드가 돌 준비가 아직 안된 상태

> 그래서 startup code가 먼저 와서 환경을 만들어줘야한다.

 

Startup code가 하는 일

1. Stack Pointer 설정

ldr sp, =_estack

> 의미 : 스택 최상단 주소를 SP에 넣음

> 이거 안하면 함수 호출/지역변수/리턴 자체가 불안정함.

 

2. .data 초기화 (RW 복사)

> Flash의 초기값 → RAM으로 복사

int x = 10;

> 이런건 startup에서 복사해줘야함.

 

3. .bss 초기화(ZI zero)

> 초기값 없는 전역/정적 변수를 0으로 채운다.

 

 

 

*************************************************************

이 글은 ChatGPT 질의 응답을 바탕으로 작성되었습니다.

*************************************************************

 

반응형

'🖥️ - ARM' 카테고리의 다른 글

Barrel Shifter란?  (0) 2026.04.15
ELF(Executable and Linkable Format) 이란?  (2) 2026.04.12
Linker - (1)  (0) 2026.04.09
ARM I2C 응용 - EEPROM(ATmel) 동작 분석  (1) 2025.08.13
ARM I2C(Inter-Integrated Circuit) 동작 원리  (7) 2025.08.10