IAP 부트로더의 핵심은 Flash 프로그래밍. Unlock, Erase, Write 함수를 찾자.


Flash 레지스터

레지스터주소용도
FLASH_KEYR0x40022004Unlock Key
FLASH_SR0x4002200CStatus
FLASH_CR0x40022010Control
FLASH_AR0x40022014Erase Address

Flash Key

Unlock에 필요한 매직 넘버:

#define FLASH_KEY1  0x45670123
#define FLASH_KEY2  0xCDEF89AB

Ghidra에서 찾기

Search → For Scalars → 0x45670123

void Flash_Unlock(void) {
    *(uint32_t *)0x40022004 = 0x45670123;
    *(uint32_t *)0x40022004 = 0xCDEF89AB;
}

매직 넘버 순서대로 쓰면 잠금 해제.


Erase 함수

Flash_Unlock 근처에 있다:

void Flash_ErasePage(uint32_t addr) {
    *(uint32_t *)0x40022010 |= 0x02;    // PER (Page Erase)
    *(uint32_t *)0x40022014 = addr;     // 페이지 주소
    *(uint32_t *)0x40022010 |= 0x40;    // STRT
    while (*(uint32_t *)0x4002200C & 0x01);  // BSY 대기
    *(uint32_t *)0x40022010 &= ~0x02;
}

Write 함수

void Flash_WriteHalfWord(uint32_t addr, uint16_t data) {
    *(uint32_t *)0x40022010 |= 0x01;    // PG (Program)
    *(uint16_t *)addr = data;           // 16비트 쓰기
    while (*(uint32_t *)0x4002200C & 0x01);
    *(uint32_t *)0x40022010 &= ~0x01;
}

STM32 Flash는 Half-word(16비트) 단위로 쓴다.


다음 글에서 IAP 프로토콜 분석.

#13 - IAP 프로토콜 분석