애플이 부트 체인을 잠그자, 그는 30일 만에 M4 리눅스 GPU 드라이버를 작성했다

애플이 부트 체인을 잠그자, 그는 30일 만에 M4 리눅스 GPU 드라이버를 작성했다

LinuxApple SiliconGPUAI

데이터 소스:codyho.dev

M4에서 212 프레임 달성

M4 Mac Mini에서 Minecraft를 212fps로 실행하거나 브라우저에서 WebGL을 부드럽게 렌더링하려면 로우 레벨 개발에 얼마나 많은 시간이 필요할까? 애플 실리콘용 리눅스 드라이버 작성은 예전에는 길고 지루한 마라톤과 같았다. M1 시대의 커널 드라이버는 Asahi Lina가 매일 12시간씩 일하며 힘겹게 만들어낸 결과물이었다. 하지만 이제 개발자 Cody Ho와 Niklas는 이 수년간의 엔지니어링을 단 한 달로 압축하여 OpenGL ES 3.0과 호환되는 GPU 드라이버를 처음부터 구축했다.

여기에는 기업 비밀 유출이 전혀 없다. 이들은 클린룸 리버스 엔지니어링을 채택하여 애플의 바이너리를 전혀 보지 않고 자신들이 작성한 셰이더와 하드웨어 실행 트레이스에만 의존하여 개발을 진행했다. 블랙박스 생태계에서도 실제 실행되는 신호만 가로챌 수 있다면, 커뮤니티는 대체품을 만들어낼 수 있다.

이 드라이버에서 WebGL을 실행하는 Chrome 및 Firefox 그림: Chrome과 Firefox가 이 드라이버에서 정상적으로 렌더링되고 있다. 출처: codyho.dev

애플, 드라이버를 반으로 쪼개다

최신 애플 실리콘에서 드라이버를 작성할 때 가장 큰 장애물은 애플의 독자적인 펌웨어 ABI(응용 프로그램 바이너리 인터페이스)이다. 전통적인 커널 드라이버는 하드웨어와 직접 통신하지만, 애플의 방식은 드라이버를 두 개로 나누는 것이다. 절반은 RTKit이라는 맞춤형 운영 체제에 펌웨어로 포함되고, 나머지 절반은 공유 메모리의 데이터 구조를 통해 호스트와 통신한다.

M4 및 A18 Pro 칩에서 이 통신 메커니즘은 M1 시대보다 훨씬 더 복잡해졌다. 데이터 구조의 수는 1.5배 증가했고, 포인터 수는 두 배로 늘어났으며, 렌더링 작업을 제출하는 과정은 미로와 같다. 펌웨어 고유 필드와 호스트 제어 필드가 서로 얽혀 있어 이를 풀어내는 것은 결코 쉽지 않다.

문서를 읽는 것보다 무식한 방법이 통했다

이 메커니즘을 어떻게 해독할 것인가? Cody Ho가 꺼낸 도구는 macOS의 실제 하드웨어 동작을 정확하게 기록하기 위해 자체 개발한 하이퍼바이저(가상 머신 모니터)였다. 그런 다음 대규모 언어 모델(LLM) 에이전트를 파이프라인에 투입하여 블라인드 테스트를 실행했다.

에이전트의 작업은 매우 직접적이다. 첫 번째 펌웨어 표시 이벤트가 나타날 때까지 기다렸다가 GPU 메모리 상태를 전체 저장한다. 재부팅 후 그 상태를 호스트 메모리에 그대로 복사하여 실행을 트리거하고 출력 페이지의 메모리 변화를 뚫어지게 관찰한다.

틀렸다면 포인터와 필드를 조정하고 다시 실행한다. 실험이 진행됨에 따라 하드 카피가 필요한 메모리 페이지가 점점 줄어들었고, 마침내 코드를 통해 모든 것을 처음부터 구성할 수 있게 되었다. GPU 드라이버 개발은 머리를 쥐어짜는 논리적 추론에서 고빈도 시행착오 루프로 바뀌었다.

M4 Mac Mini에서 212fps에 도달한 Minecraft 그림: M4 Mac Mini에서 212fps에 도달한 Minecraft. 출처: codyho.dev

컴퓨팅 파워보다 깨끗한 데이터가 더 중요하다

하지만 이 시행착오 접근 방식은 컴퓨팅(Compute) 모듈에서 벽에 부딪혔다. 그래픽 인터페이스 환경에서는 컴퓨팅 작업이 항상 수많은 렌더링 작업 뒤에 대기하기 때문에 기록된 실행 트레이스가 336MB에 달했고, 안에는 관련 없는 노이즈로 가득 찼다. 에이전트는 일주일 넘게 객체를 직접 구성하려고 시도했지만 아무런 진전이 없었다.

해결책은 엔지니어링 직관으로 돌아가는 것이었다. Cody Ho는 그래픽 인터페이스를 끄고 단일 사용자 모드로 진입한 후, 그래픽 인터페이스를 사용할 수 있게 된 순간 바로 작은 프로그램을 실행하여 극도로 작고 순수한 컴퓨팅 실행 트레이스를 추출했다. 이 데이터는 몇 시간 만에 분석되었고, 컴퓨팅 모듈은 며칠 내로 정상 작동하게 되었다. 에이전트에게 300MB의 더러운 데이터를 먹이는 것보다 확실한 결과를 출력하는 스캐폴딩을 구축하는 데 몇 시간을 투자하는 것이 훨씬 낫다.

폐쇄가 가속기가 되었다

애플이 부트 체인을 강화하면서 오픈소스 커뮤니티는 Mac에서 리눅스를 실행하기 위해 자체 드라이버를 개발할 수밖에 없게 되었다. 가장 어려워 보였던 이 선택은 기록 및 재생 메커니즘과 자동화 도구의 결합으로 인해 오히려 지름길이 되었다.

팀 단위로 수년이 걸릴 개발량을 한 달로 압축할 수 있었던 것은 모델이 갑자기 로우 레벨 구조를 깨달았기 때문이 아니다. 개발자가 하이퍼바이저를 사용하여 복잡한 시스템의 블랙박스를 무한히 리셋하고 결과를 즉시 확인할 수 있는 실험장으로 바꿨기 때문이다. 폐쇄적인 펌웨어 문서를 읽는 길은 막혔지만, 초고속 피드백 루프를 통한 블라인드 테스트의 길은 열려 있었다.

참고 링크:

  • Cody Ho: 한 달 만에 처음부터 GPU 드라이버 구축하기
  • Asahi Linux 프로젝트 (M1/M2 커널 드라이버 배경)