포스트

임베디드 스터디 - ELF 포맷

임베디드 스터디 - ELF 포맷

.ELF 파일

  • 메모리 메타데이터가 추가된 바이너리 파일
    • 섹션 : .text, .bss, .rodata 같이 데이터 형태로 구분하는 구역 단위
    • 세그먼트 : Flash, RAM 메모리에 섹션 데이터를 실제로 올릴 때 묶는 단위
1
2
3
4
5
6
7
┌─────────────────────┐
│   ELF Header        │  ← "나는 ELF다, 32/64bit, ARM, 진입점 주소는 여기"
├─────────────────────┤
│   Sections          │  ← .text / .data / .bss / .rodata 실제 내용
├─────────────────────┤
│   Program Headers   │  ← "이 섹션들을 메모리 어디에 올려라" (세그먼트)
└─────────────────────┘
  • 펌웨어를 구울 때 .elf.bin이나 .hex로 변환하여 굽는다.
    • 메모리는 .elf 파일의 메타데이터를 읽지 못한다.
1
2
3
4
5
.elf → .bin   : 메타데이터 전부 제거, 순수 바이트만
                주소 정보가 없으므로 굽는 시작주소를 별도 지정 필요

.elf → .hex   : 메타데이터 제거 + 주소 정보는 인코딩해서 포함
                (Intel HEX 포맷 — 주소+데이터 한 파일에)

binutils

  • .elf파일 분석용으로 사용됨
1
2
3
4
5
objdump -d firmware.elf   # 역어셈블
nm firmware.elf           # 심볼 목록
readelf -a firmware.elf   # ELF 전체 정보
size firmware.elf         # 섹션별 크기
objcopy -O binary firmware.elf firmware.bin  # 변환

objdump

  • .elf 파일을 기계어에서 다시 어셈블리어로 변환함
    • 코드가 의도대로 컴파일됐는지 확인하는 용도
      1
      2
      3
      4
      5
      6
      7
      8
      
      00000000 <main>:
       0:   push    {r7, lr}
       2:   sub     sp, #8
       4:   movs    r3, #5
       6:   str     r3, [sp, #4]    ; sensor_count = 5
       8:   bl      0x1c <read_sensor>
       c:   movs    r0, #0
       e:   pop     {r7, pc}
      

nm

  • 심볼(함수, 변수) 목록과 주소
    • 메모리 최적화를 위한 데이터 분석용
      1
      2
      3
      4
      5
      
      20000000 B error_count       ← B = .bss (RAM)
      20000004 D sensor_count      ← D = .data (RAM)
      08000100 T main              ← T = .text (Flash)
      08000200 T read_sensor
      08000050 R FIRMWARE_VERSION  ← R = .rodata (Flash)
      

readelf -a

  • .elf 파일 헤더, 섹션, 세그먼트 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
ELF Header:
  Machine: ARM
  Entry point: 0x08000000
  
Section Headers:
  [Nr] Name    Type    Addr        Size
  [ 1] .text   PROGBITS 08000000  0x8000
  [ 2] .data   PROGBITS 20000000  0x0400
  [ 3] .bss    NOBITS   20000400  0x1000

Program Headers (Segments):
  LOAD: 0x08000000  FileSiz: 0x8400  MemSiz: 0x8400  Flags: R E
  LOAD: 0x20000000  FileSiz: 0x0400  MemSiz: 0x1400  Flags: RW

size

  • 섹션별 크기
    • Flash/RAM 사용량 체크용
    • Flash = .text + .data
    • RAM = .data + .bss
1
2
text    data     bss     dec     hex filename
  32768    1024    4096   37888    9400 firmware.elf

objcopy

  • 파일 변환
1
2
3
$ objcopy -O binary firmware.elf firmware.bin
$ ls -la firmware.bin
-rw-r--r-- 1 user 33792 firmware.bin   # .text + .data 크기
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.