← 포트폴리오로 돌아가기

BOOTLOADER EVIDENCE

UDS를 통한 Flash Backup & Restore 근거 자료

AURIX TC234LP에서 요구사항을 메모리 구획과 UDS 처리 흐름으로 구체화하고, MCAL·RTE를 활용해 Application 백업·복원과 SHA-256 비교 분기를 구현했습니다. CAN 응답 중단을 Trace32로 추적해 비정렬 word 접근을 특정한 과정부터 수정 코드·당시 재검증 기록까지 소개합니다.

유형
개인 교육 프로젝트
기간
2026.03.03–2026.03.24
팀 규모
1명
기반
AUTOSAR MCAL·RTE
환경
AURIX TC234LP · Embedded C · CANoe · Trace32

01 / 프로젝트 역할

요구사항 기반 구현·디버깅

개인 프로젝트 · 요구사항 분석, Flash 메모리 구성, 백업·복원 기능 구현과 Trace32 디버깅을 담당했습니다.

02 / 트러블슈팅

CAN 응답 중단에서 Alignment Trap까지

TRACE32 · RESTORE

SID 0x31 RoutineControl 처리 중 발생한 CAN 응답 중단을 Trace32의 함수 Breakpoint, Register·Variable View와 DMI Trap 정보로 추적했습니다. copyBuf, A5, DEADD가 동일한 비정렬 주소 0x7000240D를 가리키는 것을 확인해 FlsLoader_Write() source buffer의 홀수 주소 접근을 원인으로 특정했습니다.

아래 수정·재검증은 교육 당시 기록입니다. 현재 ECU 재시험 결과와 구분하며, 이후 정적 리뷰에서 발견한 미해결 문제는 CODE REVIEW에서 확인할 수 있습니다.

Trace32 디버깅 흐름

  1. 1. 증상SID 0x31 RoutineControl의 RCOR_EraseMemory_App 처리에서 EA_AppToBackup() 호출 이후 ECU의 CAN 응답이 중단됐습니다.
  2. 2. 함수 BreakpointBreak.Set EA_AppToBackup 후 함수 진입과 FlsLoader_Write() 인수를 추적했습니다.
  3. 3. Source address 확인Variable View의 copyBuf와 Register A5가 모두 0x7000240D를 가리키는 것을 확인했습니다.
  4. 4. Alignment Trap 확인DMI에서 ALN Error와 DEADD = 0x7000240D를 확인해 오류 주소를 교차 검증했습니다.
  5. 5. Trap Vector 포착Break.Set 0x80027800++0xFF /Program /Onchip 적용 후 BTV = 0x80027800, PC = 0x80027840 상태를 확인했습니다.
  6. 6. 원인static uint8 copyBuf[]가 홀수 주소에 배치되어 word load에 필요한 정렬을 충족하지 못했습니다. Flash Loader 고유의 4바이트 계약은 별도 문서 확인이 필요합니다.
  7. 7. 수정·재검증uint32 backing array와 uint8* view로 정렬을 확보한 뒤 Application→Backup→Application 양방향 Write·Read와 SHA-256 판정을 다시 수행했습니다.

캡처의 명령·벡터·원인 연결

P:0x701006CA ld16.w d15,[a5]는 source 주소를 읽는 word load입니다. A5 = 0x7000240D는 홀수 주소입니다. Trap 진입 시 PC = 0x80027840은 BTV = 0x80027800에서 0x40 떨어져 Class 2에 해당하고, D15 = 4는 TIN 4(ALN)입니다. DMI의 DEADD = 0x7000240D도 같은 주소를 가리킵니다.

TriCore의 비주변장치 메모리에서 데이터 레지스터 word load는 2바이트 정렬을 허용합니다. 이 사례는 그 조건부터 위반했습니다. uint32 저장 공간으로 4바이트 정렬을 확보한 수정과 CPU의 최소 접근 조건을 구분합니다. Infineon TC1.6 아키텍처 · Alignment / Trap

실제 디버깅 근거

아래 화면은 실제 프로젝트 수행 중 CANoe와 Trace32에서 수집했습니다. UDS 요청·응답, 함수 인수, Register, Variable View와 DMI 상태를 함께 비교해 Memory Alignment Error의 발생 주소와 원인을 확인했습니다.

CANoe UDS RoutineControl 요청 응답 Trace
UDS 응답 흐름

DiagnosticSessionControl(0x10), SecurityAccess(0x27), RoutineControl(0x31)의 요청·응답과 중단 구간을 확인했습니다.

copyBuf A5 alignment error address Trace32 화면
Source address 추적

copyBuf 시작 주소와 A5, Trace32 오류 표시가 0x7000240D로 일치했습니다.

DMI ALN Error DEADD 0x7000240D 화면
DMI Trap 분석

ALN Error와 DEADD = 0x7000240D를 확인해 정렬 위반 주소를 교차 검증했습니다.

BTV 0x80027800 PC 0x80027840 Trap Vector Breakpoint 화면
Trap Vector Breakpoint

BTV = 0x80027800, PC = 0x80027840을 확인해 Trap Vector 범위 진입을 직접 포착했습니다.

정렬 수정 전후 코드

수정 전

static uint8 copyBuf[MEMORY_COPY_CHUNK_SIZE];

memcpy(copyBuf,
       (const void *)(MEMORY_ADDRESS_APPLICATION + offset),
       copySize);

*errorResult = (uint8)FlsLoader_Write(
    MEMORY_ADDRESS_BACKUP + offset,
    copySize,
    copyBuf);

수정 후 핵심

uint32 i;
static uint32 copyBuf[8];
uint8* copyBufByte = (uint8*)copyBuf;
for (i = 0u; i < copySize; i++)
{
    copyBufByte[i] = *((const uint8*)(MEMORY_ADDRESS_APPLICATION + offset + i));
}

보관된 수정 후 소스의 발췌입니다. 32바이트 backing buffer를 두고 바이트 단위로 복사합니다. uint8이 unsigned char인 타입 정의에서는 MISRA C:2012 Rule 11.3의 문자형 포인터 예외와 연결할 수 있습니다. 전체 MISRA 준수 판정은 아닙니다.

Backup·Restore 재검증

양방향 Flash 복구 절차
방향EraseSourceDestination검증
Application Primary → BackupPFLASH_AREA_APPICATION_SECONDARYMEMORY_ADDRESS_APPLICATION + offsetMEMORY_ADDRESS_BACKUP + offsetWrite return, read-back, SHA-256
Backup → Application PrimaryPFLASH_AREA_APPICATION_PRIMARYMEMORY_ADDRESS_BACKUP + offsetMEMORY_ADDRESS_APPLICATION + offsetWrite return, read-back, SHA-256

정렬 수정 후 Application Primary→Backup(EA_AppToBackup())과 Backup→Application Primary(EA_AppRestore()) 양방향 Flash Write·Read, UDS 응답 흐름과 SHA-256 판정을 다시 확인했습니다.

OVERVIEW

시스템 구조와 리프로그래밍 흐름

교육용 프레임워크: Tester → CAN·ISO-TP → BswCom → BswDcm → RTE 호출 → EcuAbsFls → FlsLoader → Flash

Programming Session · DiagnosticSessionControl(0x10) → SecurityAccess(0x27) → Backup·Erase · RoutineControl(0x31) → RequestDownload(0x34) → TransferData(0x36) → RequestTransferExit(0x37) → RoutineControl(0x31)에서 SHA-256 확인 → ECUReset(0x11)

위 경로는 교육 프로젝트의 모듈명입니다. AUTOSAR Classic의 표준 진단 경로(CanTp → PduR → Dcm)와 구분합니다.

구현 범위

아래는 교육 당시 구현과 기록의 정리입니다. 이후 발견한 길이 상한·권한 검사 누락과 valid pattern 기록 순서 문제는 CODE REVIEW에 구분했습니다. 개선안은 적용·빌드·ECU 검증하지 않았으며, 정상 경로의 동작 기록이 모든 실패 조건에서의 안전성을 뜻하지 않습니다.

요구사항과 구현 연결

요구사항 PDF, Notion 수행 기록, 보관 소스를 대조해 프로젝트 1–4의 구현 범위를 정리했습니다. 아래 내용은 소스와 당시 기록의 비교이며 새 ECU 시험 결과가 아닙니다.

요구사항별 구현과 확인 근거
요구사항구현 내용확인 근거
UDS 리프로그래밍세션 진입·보안 접근·삭제·다운로드·무결성 검사·리셋 연결BswDcm의 대표 경로에 사용하는 고유 SID 7개. RoutineControl의 Erase·Check는 같은 서비스의 두 루틴
Flash App 영역 백업·복원Primary → Backup 보존, 실패 시 Backup → Primary 복원EA_AppToBackup()·EA_AppRestore(), Notion 프로젝트 1의 중단 후 복원 수행 기록
메모리 구획링커 스크립트로 Primary·Backup·해시·valid pattern 영역 지정PDF 117쪽 링크 설정과 소스 주소 정의 대조. Primary 0x80100000, Backup 0x80180000
AUTOSAR 기반 MCAL·RTE 활용BswDcm → RTE → EcuAbsFls → Flash Loader 호출 연결진단 처리·ECU 추상화·드라이버 인터페이스 활용 범위. 전체 AUTOSAR 표준 스택 자체 구현이나 적합성 검증을 뜻하지 않음
SW Binary 변경 검출SHA-256 계산·저장 해시 비교, 불일치 시 NRC 0x72와 Restore 요청프로젝트 2·3 소스와 Notion의 정상·변조 Binary 수행 기록. 고정 키 접두어 해시는 HMAC·전자서명이 아님
SW Binary 바이트 변환TransferData에서 데이터에 -0x05 적용 후 기록, 해시 바이트 제외프로젝트 4 소스와 +0x05/-0x05 변환 관계. 암호학적 기밀성을 보장하는 방식은 아님

메모리 운용 차이: PDF의 구현 예시는 신규 Binary를 Secondary에서 검사한 뒤 Primary로 복사합니다. 본 프로젝트의 Notion 기록과 보관 소스는 기존 Primary를 Backup에 보존하고 신규 Binary를 Primary에 기록한 뒤, 검사 실패 시 복원하는 흐름입니다.

최종 소스에 포함되지 않은 항목: Notion 프로젝트 5의 다운로드 중 SHA-256 누적 계산 예시는 최종 소스에 반영되어 있지 않습니다. 프로젝트 6의 시도·성공 횟수 제한도 구현 성과에 포함하지 않았습니다. 최종 소스의 해시 계산은 RoutineControl에서 Primary를 다시 읽는 방식입니다.

MEMORY MAP

AURIX TC234LP Bootloader의 PFlash·DFlash 구획과 Backup·Restore 방향을 실제 링커 주소로 정리했습니다.

Bootloader, Application Primary, Valid Pattern, Backup, DFlash 영역의 실제 주소와 Backup Restore 방향을 표시한 Memory Map
Bootloader용 링크 스크립트의 주소와 크기를 기준으로 시각화했습니다. 클릭하면 확대할 수 있습니다.

영역 정의

링커 정의 기반 Flash 구획
영역주소 범위크기용도관련 함수·심볼
Bootloader User0x80000000–0x80025FFF152 KiBBootloader 코드와 BMHD 인접 영역, 실행 시작점 0x80000020RESET
Bootloader INTTAB·Trap0x80026000–0x80027FFF8 KiB인터럽트 벡터 및 Trap TableINTTAB 0x80026000, BTV 0x80027800
Application Primary0x80100000–0x8017DFFF504 KiB현재 실행 대상 Application BinaryMEMORY_ADDRESS_APPLICATION, EA_AppToBackup()
Application INTTAB0x8017E000–0x8017FFBF8 KiB - 64 BApplication 벡터 영역pflash_app_inttab
SHA-256 저장 영역0x8017FFC0–0x8017FFDF32 B계산값과 비교하는 저장 해시 (전자서명 아님)MEMORY_ADDRESS_SIGNATURE
Valid Pattern0x8017FFE0–0x8017FFFF32 B리프로그래밍 완료·실행 가능 상태 표시pflash_app_valid
Application Backup0x80180000–0x801FFFFF512 KiB업데이트 전 Application 보존 및 실패 복구EA_AppToBackup(), EA_AppRestore()
DFlash Bank 00xAF000000–0xAF01FFFF128 KiB비휘발성 상태·로그 저장 후보 영역dflash0
DFlash Bank 10xAF100000–0xAF103FFF16 KiB비휘발성 보조 영역Bank 1 (심볼 원본 재확인 필요)

근거

#define INTTAB     0x80026000
#define RESET      0x80000020
#define IFXTRAPTAB (INTTAB + 0x1800)

memory pflash_app_valid {
    size = 32;
    map cached(dest_offset=0x8017FFE0, size=32);
}

memory pflash_app_backup {
    size = 512k;
    map cached(dest_offset=0x80180000, size=512k);
}

Bootloader 링크 설정에서 Application과 Backup은 reserved rom으로 선언되어 Bootloader 코드가 해당 영역에 배치되지 않습니다. SHA-256은 이 프로젝트에서 Binary 변경 여부를 판단하는 무결성 검사로 사용했습니다.

UDS SEQUENCE

UDS 7개 서비스의 대표 호출 흐름과 Backup·Restore 분기를 요약했습니다. 전체 오류 처리의 완전성이나 안전성을 입증하는 시퀀스는 아닙니다.

UDS 대표 호출 흐름과 SHA-256 불일치 Restore 분기, valid pattern 선기록 결함을 표시한 도식
교육 당시 서비스 분기와 RTE·Flash 호출 관계의 개요입니다. 해시 비교와 valid pattern 기록의 세부 순서는 아래 구현 한계 설명을 함께 확인해야 합니다. 클릭하면 확대할 수 있습니다.

서비스 순서

UDS 리프로그래밍 서비스와 책임
순서서비스당시 구현 흐름확인 범위·미해결 문제
10x10 DiagnosticSessionControlProgramming Session 진입정상 절차의 진입 흐름. 모든 서비스의 세션 검사를 보장하지 않음
20x27 SecurityAccessSeed/Key 교환 분기고정 Seed/Key 사용. EraseMemory 권한 검사 누락은 별도 미해결
30x31 RoutineControlEA_AppToBackup() 후 RID_EraseMemory 실행요청 길이·세션·권한·physical request 검사 누락. Backup 실패 시 Erase 차단은 공개 근거로 입증하지 못함
40x34 RequestDownload주소·길이와 전송 상태 초기화광고한 블록 길이와 실제 TransferData 길이 상한 검사는 별개이며, 후자는 누락
50x36 TransferDataBlock Sequence 처리, 바이트 변환 후 Primary에 Binary 기록길이 상한·ISO-TP 재조립 경계 검사 누락. 순서 오류 시험은 근거 부족
60x37 RequestTransferExit전송 길이 확인 후 valid pattern 기록이 단계에서는 해시를 비교하지 않음. SHA-256 검증 전에 valid pattern을 기록하는 순서 결함. 수정안 미적용
70x31 RID_CheckProgrammingDependenciesPrimary를 읽어 키 접두어 SHA-256 계산·비교, 불일치 시 Backup 복구교재의 Secondary 검증 후 Primary 복사 방식과 다름. 완전한 의존성·안전 조건 검사를 입증한 것은 아님
80x11 ECUResetReset 및 Application 실행 경로Restore 후 Application 정상 진입은 별도 실행 근거 부족

진단 타이밍과 워치독

SessionControl 응답 50 02 00 32 01 F4는 P2=50ms, P2*=5000ms를 광고합니다. P2*는 ResponsePending 이후의 대기시간이며 처음부터 5초 무응답을 허용하는 뜻이 아닙니다.

보관된 복사 루프는 32바이트 단위로 EA_wdgTriggerUpdateSlow()를 호출한 다음 인터럽트를 비활성화하고 Flash write를 수행합니다. 호출 존재는 확인했지만 watchdog 드라이버의 동작, erase 최장 지연과 진단 응답 기한 준수는 실행 검증하지 않았습니다. 공개 소스 범위에서는 이 장시간 처리에 대한 NRC 0x78 송신을 확인하지 못했습니다.

코드 영역은 504KiB이지만 복사 루프의 MEMORY_SIZE_APPLICATION은 512KiB−32B = 524256B입니다. Flash 처리 시간이나 다운로드 처리량의 측정값으로 혼동하지 않습니다.

RoutineControl 실제 정의

아래 RID는 교육 프로젝트 정의입니다. 표준 eraseMemory 0xFF00, checkProgrammingDependencies 0xFF01과 다르며 표준값으로 제시하지 않습니다.

#define RID_CheckProgrammingDependencies 0x0001u
#define RID_EraseMemory                  0x0002u
#define RCOR_EraseMemory_App             0xF001u

31 01 00 02 F0 01
|  |  |-----| |---|
SID   RID       RCOR

BswDcm
→ Rte_Call_BswDcm_rEcuAbsFls_erasePflashBlock()
→ REoiEcuAbs_pEcuAbsFls_erasePflashBlock()
→ EA_erasePflashBlock()

설계 의도와 당시 구현의 차이: SHA-256 불일치 시 EA_AppRestore()를 호출하는 복구 분기는 구현했지만, RequestTransferExit에서 해시 검증 전에 valid pattern을 기록했습니다. 검증 성공 후에만 valid pattern을 기록하도록 바꾸는 것은 미적용 개선안입니다. 이 자료는 불일치·전원 중단 상황에서 신규 Application 부팅이 항상 차단된다고 주장하지 않습니다.

TEST RESULTS

직접 보여줄 수 있는 캡처·소스와 수행 서술을 구분했습니다. 아래 자료는 보관 기록이며 현재 환경에서 새 빌드나 ECU 재시험을 수행한 결과가 아닙니다.

Bootloader 공개 확인 자료
연결 ID확인 내용근거 유형확인 범위
BL-TC-09CAN 응답 중단과 Alignment TrapCANoe·Trace32 캡처오류 명령·주소·Trap 원인의 연결
BL-TC-10정렬 버퍼 수정수정 전후 소스uint32 저장 공간과 바이트 복사 변경 확인; 수정 후 ECU 실행 로그는 공개 자료에 없음
BL-TC-01·05·06·07다운로드·해시 불일치·Backup·Restore구현 흐름과 수행 기록 요약기능 분기와 재검증 서술; 독립적으로 실행 PASS를 확인할 원본 로그는 비공개
BL-TC-04valid pattern 기록 순서정적 코드 리뷰검증 전 valid 기록 문제 확인; 중단 시 안전 부팅 성공으로 판정하지 않음

추가 검증이 필요한 조건

길이·권한 검사와 valid pattern 순서 개선안은 미적용·미검증입니다. 호스트 단위 테스트를 추가하더라도 Flash 하드웨어·전원 중단·실제 부팅 시험을 대신하지 않습니다.

CODE REVIEW

기능 동작으로 끝내지 않고 완성된 C/H를 다시 읽어 입력 경계와 검증 순서를 점검했습니다. 아래는 스스로 찾아 문서화한 결함입니다.

이 항목들은 게시된 소스를 정적으로 검토해 확인한 것이며, 개선안을 실제로 구현·빌드·ECU에서 검증한 결과가 아닙니다. 교육 당시 snapshot은 무결성 비교를 위해 수정하지 않고 보존했습니다.