# DB720 펌웨어 적재 키트 (PowerShell) ESP32-P4 기반 DB720 보드에 **secure_release 서명 펌웨어**를 PowerShell로 적재하는 독립 키트입니다. 이 폴더 하나만 있으면 빌드 환경 없이도 적재할 수 있습니다(esptool만 있으면 됨). - 펌웨어: `DIBD720Ue_08B_08R040C` (8단40열 = 640×128, 256색/08B) — db250513 키로 V2 서명한 secure_release 빌드 - 빌드일: 2026-06-22 (버전 3.7.2) > **DB720은 secure_release 단일입니다.** 적재·빌드·OTA에 쓰는 펌웨어는 **db250513 키로 서명한 바이너리뿐**입니다. > 서명이 없는 일반 빌드(예: V3.7.1 같은 공개 릴리즈 바이너리)는 secure_release 부트로더가 **서명 검증에서 거부**해 부팅되지 않습니다. > 이 키트의 `firmware\` 폴더에는 **db250513 서명본만** 두세요(비서명 bin 금지). --- ## 0. 두 경우 — 어느 스크립트를 쓰나 | 보드 상태 | 스크립트 | 무엇을 쓰나 | 위험 | |---|---|---|---| | **일상적 앱 교체** (서명 부트로더가 이미 정상) | `flash_app.ps1` | 부트로더 **제외** 4종(파티션/ota_data/앱/www) | 없음 — 부트로더 안 건드려 **brick 불가** | | **부트로더가 비었을 때** (flash 통째 지워짐 / 0x2000 빔 / 부팅 안 됨) | `flash_full.ps1` | 부트로더+파티션+ota_data+앱+www **5종 전부** | ⚠ 부트로더(0x2000)에 손댐 — 아래 §1 경고 | > **일상 적재는 `flash_app.ps1`(경우 B)만 쓰세요.** 가능하면 `-AppOnly`로 앱만 올립니다. > `flash_full.ps1`(경우 A)은 **부트로더가 실제로 비어 부팅이 안 될 때만** 쓰는 복구 전용입니다. --- ## 1. ★★★ full flash 경고 (경우 A 전용) ★★★ `flash_full.ps1`은 부트로더(0x2000)까지 다시 씁니다. - **이미 secure_release로 구워진 보드** (예: 회사 `.230`) → 부트로더가 이미 영구 고정돼 있으므로 같은 서명 부트로더를 다시 쓸 이유가 없습니다. **일상 적재에 경우 A를 쓰지 마세요** — `flash_app.ps1`이면 충분합니다. - **eFuse가 아직 안 구워진 보드** → secure_release 서명본을 full flash하면 첫 부팅에 secure boot **eFuse가 영구로 구워집니다**(되돌릴 수 없음). - **eFuse는 비가역입니다.** 한 번 구워지면 그 보드는 영원히 이 서명 체계에만 묶입니다(DB400 V1에서 `ABS_DONE_0` 잠김으로 보드가 brick된 실증이 있습니다). - **db250513 키를 분실하면 그 보드는 OTA로 더 이상 펌웨어를 못 올립니다(영구).** 키 백업은 필수입니다. `flash_app.ps1`(경우 B)은 부트로더를 안 건드리므로 이 위험이 **없습니다**. --- ## 2. 사전 준비 1. **USB-JTAG 케이블**로 PC ↔ DB720 연결 (보드의 USB-JTAG 포트). 2. **esptool**이 있는 파이썬. 두 스크립트는 기본으로 ESP-IDF 파이썬을 씁니다: `C:\Users\jyheo\.espressif\python_env\idf5.5_py3.13_env\Scripts\python.exe` - 환경이 다르면 `flash_full.ps1` / `flash_app.ps1` 상단의 `$Python` 한 줄만 고치세요. - 또는 `pip install esptool` 한 파이썬이 PATH에 있으면 자동 폴백됩니다. - esptool은 **v4.11 이상**이어야 합니다(낮으면 적재 중 멈춤). 3. **COM 포트 확인** — 적재 포트(USB-JTAG)는 번호가 바뀔 수 있습니다: ```powershell .\list_ports.ps1 ``` - `USB 직렬 장치(COMx)` 또는 VID `303A:1001` = **적재 포트** (`-Port COMx`) - `Silicon Labs CP210x (COMx)` = **COM2 자리**(디버그·문구 전송, 적재 중 열지 말 것) --- ## 3. 적재 방법 PowerShell을 이 폴더에서 열고: ### 경우 B — 서명 부트로더 있음 (일상 적재, 권장) ```powershell # 앱만 최소로(앱 0x20000 + otadata erase) — 권장 .\flash_app.ps1 -Port COM4 -AppOnly # 표준(파티션+ota_data+앱+www, 부트로더 제외) .\flash_app.ps1 -Port COM4 ``` ### 경우 A — 부트로더 비었음 (전체 복구 전용, §1 경고 확인) ```powershell .\flash_full.ps1 -Port COM4 ``` > 실행 정책 때문에 막히면(이 PC에 처음): `Set-ExecutionPolicy -Scope CurrentUser RemoteSigned` 한 번. > `-Port`를 생략하면 기본 `COM4`로 시도합니다. --- ## 3a. 앱이 여러 개일 때 — 골라서 올리기 `firmware\` 폴더에 앱 `.bin`이 여러 개 있을 수 있습니다. 예를 들어 지금은 두 개가 들어 있습니다. | 앱 파일 | 화면 크기 | 상태 | |---|---|---| | `DIBD720Te_08C_04R020C.bin` | 320×64 (4단20열, 8색) | 부팅 검증됨 — 안전, 일상·복구용 권장 | | `DIBD720Ue_08B_08R040C.bin` | 640×128 (8단40열, 256색) | 부팅 미검증 — 테스트용(SRAM 한도 의심) | > 부트로더·파티션·ota_data·www_fs는 앱이 아니라 보조 파일이라 선택 대상에서 빠집니다. 앱 후보는 그 4개를 뺀 나머지 `.bin`입니다. ### 1단계 — 어떤 앱이 있는지 본다 앱을 지정하지 않고 그냥 실행하면, 스크립트가 **임의로 고르지 않고** 앱 목록을 보여준 뒤 멈춥니다. ```powershell .\flash_app.ps1 -Port COM4 ``` 출력 예: ``` 여러 앱이 있습니다 — -App 으로 하나를 지정하세요: DIBD720Te_08C_04R020C.bin DIBD720Ue_08B_08R040C.bin 예: .\flash_app.ps1 -Port COM4 -App DIBD720Te_08C_04R020C.bin ``` ### 2단계 — 올릴 앱을 `-App`으로 지정한다 ```powershell # 320×64(검증된 것)을 앱만 최소로 올리기 — 권장 .\flash_app.ps1 -Port COM4 -App DIBD720Te_08C_04R020C.bin -AppOnly # 640×128(테스트)을 표준으로 올리기 .\flash_app.ps1 -Port COM4 -App DIBD720Ue_08B_08R040C.bin ``` - `-App` 값은 `firmware\` 안의 **파일명만** 적습니다(경로 없이). - 앱이 **하나뿐이면** `-App`을 생략해도 그것이 자동 선택됩니다(여러 개일 때만 지정 필수). - `flash_full.ps1`(경우 A)도 똑같이 `-App`으로 고릅니다. --- ## 3b. 전체 굽기 (full flash) — 5영역 전부 부트로더(0x2000)까지 포함해 **5개 영역을 전부** 쓰는 절차입니다. flash가 통째로 비었거나 부트로더가 깨져 부팅이 안 될 때 보드를 처음부터 살립니다. > ⚠ **먼저 §1 경고를 읽으세요.** 전체 굽기는 부트로더를 건드리므로, eFuse가 안 구워진 보드에서는 **첫 부팅에 secure boot eFuse가 영구로 구워집니다**(되돌릴 수 없음). 일상 적재에는 쓰지 말고 §3(앱 적재)을 쓰세요. 전체 굽기는 **부트로더가 실제로 비어 부팅이 안 될 때만** 씁니다. ### 무엇을 쓰나 (영역 5개) | offset | 파일 | 크기 | 서명 | |---|---|---|---| | `0x2000` | `firmware\bootloader.bin` | 45KB | db250513 서명 | | `0x10000` | `firmware\partition-table.bin` | 3KB | 비서명(정상) | | `0x11000` | `firmware\ota_data_initial.bin` | 8KB | 비서명(정상) | | `0x20000` | 선택한 앱 (`-App`) | 1.2~1.7MB | db250513 서명 | | `0x420000` | `firmware\www_fs.bin` | 512KB | 비서명(정상) | ### 방법 1 — 스크립트 (권장) ```powershell # 앱이 하나면 그대로 .\flash_full.ps1 -Port COM4 # 앱이 여러 개면 -App 으로 지정 .\flash_full.ps1 -Port COM4 -App DIBD720Te_08C_04R020C.bin ``` 스크립트가 5영역을 **하나씩 개별 호출**로 쓴 뒤(SDM 다중영역 한 번에 쓰면 중간 실패) hard_reset 합니다. ### 방법 2 — 수동 esptool (스크립트가 안 될 때, 한 줄씩) `COM4`는 적재 포트로 바꾸고(`.\list_ports.ps1`), `--flash_size 16MB`는 **반드시** 붙입니다(이게 빠지면 SDM에서 4MB로 오인해 `0x420000`(www_fs)을 못 써 부팅 루프가 납니다 — 2026-06-22 실증). ```powershell $P = "C:\Users\jyheo\.espressif\python_env\idf5.5_py3.13_env\Scripts\python.exe" $C = "--chip","esp32p4","-p","COM4","-b","115200","--before","default_reset","--after","no_reset","--connect-attempts","30","--no-stub" $W = "write_flash","--flash_mode","dio","--flash_size","16MB","--flash_freq","80m" & $P -m esptool @C @W 0x2000 firmware\bootloader.bin & $P -m esptool @C @W 0x10000 firmware\partition-table.bin & $P -m esptool @C @W 0x11000 firmware\ota_data_initial.bin & $P -m esptool @C @W 0x20000 firmware\DIBD720Te_08C_04R020C.bin # 올릴 앱 & $P -m esptool @C @W 0x420000 firmware\www_fs.bin # SDM 탈출(정상 부팅) & $P -c "from esptool.targets.esp32p4 import ESP32P4ROM; r=ESP32P4ROM('COM4'); r.connect('default_reset'); r.hard_reset()" ``` > ★ **secure 보드는 부트로더(0x2000)·전체 erase write를 거부할 수 있습니다** — `0105 format invalid` 같은 거부는 부트로더가 이미 같은 키로 구워져 있다는 뜻(정상)이라, 그 경우 0x2000은 건너뛰고 나머지 4영역만 쓰면 됩니다(= §3 앱 적재로 충분). > ★ esptool/USB 리셋은 이 보드에서 다운로드 모드로 떨어지는 경향이 있어, **최종 부팅은 USB-JTAG 케이블을 뽑고 전원 사이클**해야 확실합니다. --- ## 4. 적재 메커니즘 (왜 이렇게 하나) - **eco2 secure download mode(SDM) 레시피**: `--no-stub` + `115200` baud + `--before default_reset --after no_reset`. secure 보드는 esptool stub를 못 올리므로 `--no-stub`, 다운로드 모드 안정 위해 115200을 씁니다. - **영역은 하나씩 개별 esptool 호출로** 씁니다. SDM에서 여러 영역을 한 번에 쓰면 중간에 "Failed to enter Flash download mode"로 실패합니다(2026-06-22 실증 — www_fs가 빈 채 남아 부팅 루프). - **부트로더(0x2000)는 경우 A에서만** 씁니다. secure 보드는 부트로더/전체 erase를 거부하는 게 정상입니다. - 적재 후 `--after no_reset`로 남은 다운로드 모드를 **hard_reset**(esptool ROM 객체)으로 빠져나와 정상 부팅합니다. - 오프셋 정본: 부트로더 `0x2000` / 파티션 `0x10000` / ota_data `0x11000` / 앱 `0x20000` / www_fs `0x420000`. flash: dio / keep / 80m. --- ## 5. 적재 후 확인 다음 중 하나로 새 펌웨어가 실제로 올라가 부팅됐는지 확인합니다. - **COM2(디버그 콘솔, CP210x)에서 `![0081!]`** 을 115200bps로 보내 버전 배너가 오면 정상(적재 포트 COM4 아님). - **부트로그**에 `RSA-PSS verified`(secure_release 서명 검증 통과)와 정상 부팅 메시지가 보이면 정상. - **LAN으로 받은 빌드 시각**을 키트의 빌드일(이 README 상단)과 대조 — 날짜가 맞으면 새 펌웨어가 적용된 것입니다. > 적재 포트(COM4/USB-JTAG)는 **측정·표출 중 열지 마세요** — DTR/RTS가 보드를 리셋해 화면이 날아갑니다. --- ## 6. 안 될 때 | 증상 | 조치 | |---|---| | 포트 연결 실패 / `could not open port` | `.\list_ports.ps1`로 실제 USB-JTAG COM 번호 확인 후 `-Port COMx`. 다른 프로그램이 그 포트를 잡고 있으면 닫기 | | `~0.72MB`에서 멈춤(hang) | esptool 버전이 낮음(<4.11). `pip install -U esptool` (이 키트는 v4.11+ 전제) | | 적재는 됐는데 부팅 안 됨(검정/무응답) | 먼저 `flash_app.ps1 -AppOnly`로 otadata를 지워 ota_0으로 폴백 시도. 그래도 안 되고 부트로더가 빈 것 같으면 경우 A `flash_full.ps1` | | 부트로그에 서명 검증 실패 | 비서명(서명 없는) bin을 올렸을 때 발생. `firmware\`에 **db250513 서명본만** 있는지 확인(V3.7.1 같은 일반 릴리즈 bin은 secure_release에서 부팅 거부) | | `secure download` / 권한 오류 반복 | USB 케이블 재연결 후 재시도(스크립트가 connect 30회 재시도) | --- ## 7. 포함 파일 ``` DB720_Flash\ ├─ README.md ← 이 문서 ├─ list_ports.ps1 ← COM 포트 확인 ├─ flash_app.ps1 ← 경우 B: 서명 부트로더 있을 때(brick-safe, 권장) ├─ flash_full.ps1 ← 경우 A: 부트로더 비었을 때(full, §1 경고) └─ firmware\ ├─ bootloader.bin (0x2000, 45KB) ← 경우 A에서만 사용 (db250513 서명) ├─ partition-table.bin (0x10000, 3KB) ← 비서명(설계상 정상) ├─ ota_data_initial.bin (0x11000, 8KB) ← 비서명(설계상 정상) ├─ DIBD720Te_08C_04R020C.bin (0x20000, 1.2MB) ← 앱① 320×64, 8색 (db250513 서명, 부팅 검증됨·권장) ├─ DIBD720Ue_08B_08R040C.bin (0x20000, 1.7MB) ← 앱② 640×128, 256색 (db250513 서명, 테스트용·미검증) └─ www_fs.bin (0x420000, 512KB) ← 비서명(설계상 정상) ``` > 앱이 둘 다 `0x20000`(ota_0)에 올라가는 같은 자리라, **한 번에 하나만** 적재됩니다. 어느 것을 올릴지는 §3a의 `-App`으로 고릅니다. > 서명 대상(앱·부트로더)은 모두 db250513 서명본이고, 파티션·ota_data·www_fs는 secure boot v2가 서명하지 않는 정상 파일입니다.