본문으로 건너뛰기
0
r/jeffnews HN 약 7분

RK3588 GPU 안에 숨어있는 Cortex-M7 MCU를 뜯어보고 Rust/gdb/MicroPython까지 올려본 이야기

open-source

요약

RK3588의 Mali-G610 GPU 내부에 990MHz로 동작하는 Cortex-M7 MCU가 있으며, 이 펌웨어가 커널 대신 GPU 작업을 관리함. 메모리 접근의 3단 계층 구조, 인터럽트 시스템, 펌웨어 이미지 포맷을 분석하고, 실제로 Rust 정적 라이브러리, gdb 디버깅, MicroPython까지 MCU 위에서 구동하는 과정을 상세히 다룸.

기사 전체 정리

펌웨어가 뭐하는 물건인고

  • RK3588의 Mali-G610 GPU 내부에는 Cortex-M7 (r1p2) MCU가 들어있으며, GPU 클럭을 공유해 최대 990MHz로 동작함. FPU, ECC 캐시, TCM은 없는 구성임
  • 이 펌웨어(mali_csffw.bin)는 기존에 커널이 처리하던 GPU 관련 작업들을 MCU가 대신 처리하도록 넘겨받은 것임. 커맨드 스트림 관리, 전력 관리, 컨텍스트 스위칭 등이 포함됨
  • MCU는 32비트인데 GPU는 48비트 가상 주소 공간 8개를 지원함. 해결책은 MCU가 자기 페이지 테이블을 직접 제어하는 것임

메모리 접근의 3단 구조

  • 메모리 접근 시 MPU → MCU 매핑 → GPU MMU 세 계층을 순서대로 통과해야 함. 각 계층의 역할이 다름
  • MPU: 권한과 L1 캐시 동작을 설정하며, 거의 임의 크기의 리전 16개를 지원함. 폴트 시 MCU 예외가 발생함
  • MCU 매핑: 순수 매핑 전용으로 권한 설정은 불가능하며, 128MiB 크기의 리전 8개를 64MiB 정렬로 제공함. 폴트 없음
  • GPU MMU: 권한, 매핑, L2 캐시, 코히런시를 모두 제어하며, 4KB 페이지 단위로 48비트 주소 공간을 관리함. 폴트는 커널이 처리하고, MCU 주소 공간에서 폴트 발생 시 리셋됨
  • 보안 관점에서 MCU가 제어하는 건 앞의 두 계층뿐이라, 익스플로잇으로도 GPU가 매핑하지 않은 메모리에는 접근 불가함

인터럽트 시스템

  • 커널 → MCU: doorbell을 울려 MCU를 깨움. 펌웨어 초기화, 커맨드 스트림 설정, 전력 관리, protected mode 진입 등에 사용됨
  • MCU → 커널: 커널 요청 처리 완료 알림이나 GPU 작업 완료 시 유저스페이스 스레드를 깨우는 데 사용됨. 에러 시그널링도 이 경로임
  • 유저스페이스 → MCU: 매핑된 doorbell 페이지에 쓰기를 하면 MCU 레지스터가 설정되고 인터럽트가 발생함. GPU에 커맨드 스트림 처리 시작을 알리는 용도임
  • GPU → MCU: 커맨드 스트림 처리 완료 시나, "event add" 같은 에뮬레이션이 필요한 인스트럭션 실행 시 발생함
  • MCU 타이머 인터럽트: 일정 시간 후 코드 실행에 활용됨. 예를 들어 fragment job을 soft-stop해서 다른 컨텍스트에 렌더링 기회를 주는 식임

MMIO와 주요 메모리 영역

  • 0x04000000에 64MiB 영역: 커널과 MCU 간 공유 버퍼로, 상태 변경 요청(커맨드 스트림 그룹 온라인, 레지스터 서스펜드 등)과 tracebuffer 디버그 출력에 사용됨
  • 0x40000000에 256KiB MMIO 영역: GPU 하드웨어 제어용으로, 인터럽트 시그널링, MCU 메모리 매핑 설정, GPU 상태 조회, 커맨드 스트림 프로세서 실행 등을 처리함

펌웨어 이미지 포맷

  • mali_csffw.bin은 20바이트 헤더(버전 정보 + 엔트리 크기)로 시작하고, 그 뒤에 다양한 엔트리가 이어지는 구조임
  • Interface 엔트리: 메모리 섹션을 설정하며, GPU 페이지 테이블용 권한을 지정함. 첫 번째 인터페이스에는 "This firmware image is GPL-2"라는 라벨이 붙어 있어 라이선스 확인이 가능함
  • Tracebuffer 엔트리: MCU가 CPU로 트레이스 데이터를 쓰는 버퍼를 설정함. fwlog(로그 메시지), fwin/fwout(gdb용) 등이 있음
  • 그 외에 Configuration 엔트리(sysfs를 통한 설정 변경), Timeline metadata 엔트리(트레이스 이벤트 정보), Build info metadata 엔트리(git SHA 저장) 등이 존재함
  • ELF에서 변환하는 건 간단하지만, 역방향 변환은 Ghidra로 Arm 펌웨어를 로드하고 싶은 유혹 때문에 일부러 구현하지 않았다고 함. GPU 리버스 엔지니어링 윤리를 지키려는 의도임

MCU에서 이것저것 돌려보기

  • Rust: 언어 자체는 괜찮은데 빌드 툴링이 고통스러웠음. 결국 순수 Rust 펌웨어는 포기하고, Meson에서 Cargo를 호출해 C에서 불러오는 정적 라이브러리로 타협함
  • gdb: Adam Green이 만든 MRI(Armv7-M 셀프 호스트 디버그 기반 gdb 서버)를 활용해 SoC 내장 MCU에서도 gdb 디버깅이 가능함. 다만 패치된 커널이 필요하고, debugfs의 fw_io 파일을 통해 tracebuffer로 통신함
  • watchpoint: Cortex-M의 하드웨어 워치포인트가 비동기적으로 동작해서, 실제 접근 시점보다 몇 인스트럭션 뒤에 예외가 발생함. 사실상 쓸모없음. 대안으로 MPU 리전 접근 차단이나 싱글스테핑을 사용해야 함
  • 크리티컬 섹션: 원자적 연산 대신, ISR이 온스택 컨텍스트 연결 리스트를 순회하며 하위 우선순위 컨텍스트의 일관성을 보장하는 방식을 채택함. Linux의 RSEQ(restartable sequences)와 비슷한 아이디어임
  • MicroPython: MCU에서 동작하며, GPU 컨텍스트 메모리의 tracebuffer를 I/O로 사용함. 실제 Python보다 훨씬 빠르게 시작되고, root 권한이나 패치 커널 없이도 접근 가능함. "일단 Python으로 구현하고 나중에 Rust로 재작성" 전략임
  • 전체 코드는 panFWost git 저장소에 공개되어 있으며, Alyssa Rosenzweig의 도구들이 큰 도움이 되었다고 함

핵심 포인트

  • GPU 내장 Cortex-M7 MCU가 최대 990MHz로 동작하며 기존 커널의 GPU 관리 역할을 대체함
  • 메모리 접근은 MPU → MCU 매핑 → GPU MMU 3단 계층을 거치며, MCU는 앞 2개만 제어 가능해 보안상 이점이 있음
  • 5가지 인터럽트 경로(커널↔MCU, 유저스페이스→MCU, GPU→MCU, 타이머)로 시스템 간 통신함
  • mali_csffw.bin은 GPL-2 라이선스의 20바이트 헤더 기반 펌웨어 포맷임
  • Rust(정적 라이브러리), gdb(MRI 기반 셀프호스트 디버그), MicroPython을 MCU에서 실행하는 데 성공함

인사이트

GPU 내부 MCU의 동작 원리를 이 정도로 상세하게 공개한 글은 드묾. 특히 MicroPython으로 프로토타이핑 후 Rust로 재작성하는 전략은 임베디드 펌웨어 개발에서 참고할 만한 접근법임.

댓글

댓글

댓글을 불러오는 중...

open-source

Microsoft가 공개한 Rust 트레이닝 자료 — 초급부터 전문가까지 7개 코스

Microsoft가 배경 언어별 입문서 3권과 심화/전문가/실무 과정 4권으로 구성된 Rust 트레이닝 자료를 GitHub에 공개했다. 각 권마다 15-16개 챕터, Mermaid 다이어그램, Playground 연습문제를 포함한다.

open-source

오픈소스가 전부를 줬고, 줄 것이 남지 않을 때까지 — Requests 창시자의 고백

Python Requests 라이브러리 창시자 Kenneth Reitz가 오픈소스가 준 커리어, 정체성, 그리고 진단되지 않은 양극성 장애와 맞물린 정신건강 위기를 솔직하게 회고한 에세이.

open-source

IBM Z/LinuxONE 오픈소스 2월 리포트 — Cassandra부터 Terraform까지 27개 검증

IBM이 s390x 메인프레임에서 27개 오픈소스 소프트웨어 호환성을 검증한 월간 리포트. upterm, Python websockets 등이 새로 s390x 지원을 시작했고, Open Mainframe Project가 Mainframe Software Hub를 발표함.

open-source

1년간 OS를 밑바닥부터 만든 개발자 — 부트로더에서 Doom 포팅까지

MONOLITH이라는 OS를 처음부터 만든 1년간의 개발 일지. GDT/IDT 초기화부터 시작해 메모리 관리, 유저스페이스, IPC, 데스크톱 환경까지 구현하고 최종적으로 Doom 포팅에 성공함.

open-source

2026년인데 아직도 VNC + 프로프라이어터리 EDA — 반도체 업계의 도구 현실

반도체 업계의 EDA 도구가 Cadence, Synopsys, Siemens 과점 하에 여전히 폐쇄적인 현실을 짚으면서, AI가 이 구조를 바꿀 수 있는 변곡점에 왔다고 주장하는 글.