임베디드 면접 용어 사전
펌웨어 빌드.bss

.bss 섹션

초기값이 0이거나 없는 전역·정적 변수 섹션. 이미지에 자리를 차지하지 않고 startup에서 0으로 채운다.

초기값이 없거나 0인 전역·static 변수가 들어가는 섹션. 파일에는 크기 정보만 있고 실제 데이터는 없다.

int counter;                    // .bss
static uint8_t buffer[4096];    // .bss
int flags = 0;                  // .bss (0 초기화도 여기로)

왜 파일에 데이터가 없나

4KB 배열을 0으로 초기화한다면
→ .data 라면 플래시에 0을 4096개 저장해야 한다  ← 낭비
→ .bss 는 "4096바이트가 필요하고 전부 0" 이라는 정보만 저장
→ startup 코드가 런타임에 0으로 채운다

플래시 공간을 아끼는 최적화다. 이름은 옛 어셈블러의 "Block Started by Symbol" 의사 명령에서 유래했다.

startup 코드의 초기화

extern uint32_t _sbss, _ebss;

void Reset_Handler(void) {
    …
    uint32_t *p = &_sbss;
    while (p < &_ebss) *p++ = 0;
    …
}

C 표준이 "초기화하지 않은 정적 저장 기간 객체는 0" 이라고 규정하므로 이 초기화는 선택이 아니라 필수다.

지역 변수와의 차이 — 중요

void f(void) {
    int a;            // 스택. 쓰레기 값!
    static int b;     // .bss. 0 보장
}

int c;                // .bss. 0 보장

전역·static은 0이 보장되지만 지역 변수는 아니다. 초심자가 자주 혼동하며, 실제로 "가끔 이상한 값이 나온다"의 원인이 된다.

RAM만 소모한다

플래시: 0 바이트

  • RAM — : 선언한 크기 전부

큰 버퍼를 두기에 적합하다.

void process(void) {
    uint8_t buf[4096];          // ✗ 스택 4KB — 오버플로 위험
}

void process(void) {
    static uint8_t buf[4096];   // ✓ .bss — 링커가 크기를 계산해 준다
}

링커가 컴파일 시점에 RAM 사용량을 계산하므로, 빌드가 성공하면 그 부분에서 메모리 부족이 일어나지 않는다. 스택은 런타임에 결정되므로 이런 보장이 없다.

초기화를 건너뛰고 싶을 때 — .noinit

__attribute__((section(".noinit"))) uint32_t reset_count;

리셋되어도 값을 유지하고 싶은 경우에 쓴다.

워치독 리셋 횟수 마지막 오류 코드 부트로더와 앱 사이의 통신용 매직 값

소프트 리셋에서는 RAM 내용이 보존되므로 이 값이 살아남는다. 전원이 완전히 끊기면 사라지므로, 매직 값으로 유효성을 검사해야 한다.

if (magic == 0xDEADBEEF) { /* 값이 유효 */ }
else { magic = 0xDEADBEEF; reset_count = 0; }

크기 확인과 진단

arm-none-eabi-size firmware.elf
   text    data     bss
  45231     412    8192      ← bss 8KB

# 무엇이 큰지 찾기
arm-none-eabi-nm --print-size --size-sort -r firmware.elf | grep ' [bB] '

b(소문자)는 static, B(대문자)는 전역 심볼이다.

초기화 시간

.bss 가 크면 부팅이 느려진다 64KB를 0으로 채우려면 32비트 쓰기 16384번 ≈ 수백 μs

빠른 부팅이 필요하면 DMA로 채우거나, 정말 필요한 부분만 초기화하도록 .noinit을 활용하기도 한다. 다만 C 표준 위반이 되므로 신중해야 한다.

힙과의 관계

[.data][.bss][힙 ↓ ][빈 공간][ ↑ 스택]

.bss가 커지면 힙과 스택이 쓸 공간이 줄어든다. 링커 스크립트에서 최소 스택·힙 크기를 ASSERT로 검사하면 빌드 시점에 부족을 감지할 수 있다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 펌웨어 빌드·부팅 — 빌드 과정·메모리 섹션(.data/.bss)·링커·startup·OTA