Linux 7.1이 출시되었으며, 이번에도 새로운 진행 보고서를 전합니다. M3 진행 상황, Apple 버그, 그리고 그 밖의 여러 소식을 담았습니다!
Linux 7.1이 이제 출시되었고, 물론 이에 맞춰 또 하나의 진행 보고서를 전합니다. M3 진행 상황, Apple 버그, 그리고 더 많은 이야기가 있습니다!
Mac에서 전원 버튼을 길게 눌러 부트 피커를 띄우거나(또는 Startup Disk 응용 프로그램을 사용하는 경우) Asahi로 표시되는 항목은 실제로 운영체제가 들어 있는 파티션이 아닙니다. Apple의 부트 도구는 APFS 컨테이너 안에 있는, Apple이 “유효한” macOS 설치로 간주하는 것하고만 동작합니다. 사용자가 Asahi를 사용할 때마다 Recovery에서 명령을 실행할 필요 없이 Apple의 부트로더를 사용할 수 있도록, Asahi Installer는 작은 APFS 컨테이너(2.5 GB)를 만들고, 그 안에 Apple의 도구가 m1n1을 커널로 사용하는 부팅 가능한 macOS 설치라고 믿게 만들 만큼의 macOS만 넣습니다. 이 구성은 macOS 12부터 macOS 26까지 완전히 변경 없이 동작했으며, Apple은 심지어 실제 XNU 커널이 아닌 원시 바이너리를 부팅하려 할 때만 마주치는 자사 도구의 버그 몇 가지도 수정했습니다.
하지만 macOS 27 Golden Gate 개발자 베타가 공개된 직후, 사용자들로부터 더 이상 자신의 기기에서 Linux로 부팅할 수 없다는 보고가 들어오기 시작했습니다. 그 옵션이 Startup Disk와 부트 피커 양쪽에서 그냥 사라져 버린 것입니다! 당연히 이는 꽤 우려스러운 일이었고, 그래서 우리는 이 문제 조사를 우선순위로 두었습니다.
diskutil로 디스크를 검사해 보니 macOS 27로 업그레이드한 뒤에도 Asahi 관련 파티션은 모두 디스크에 그대로 존재하고 있었습니다. 데이터 손실은 발생하지 않고 있었고, 이는 긍정적인 신호였습니다. 또한 같은 기기에서 macOS 26의 두 번째 설치본의 부트 도구를 사용하면 Asahi는 여전히 부팅 가능했습니다.
chaos_princess는 Apple의 macOS Installer 자체와, 우리가 처음 Apple의 부트 도구를 파헤치던 아주 오래전의 예전 스트림들을 살펴보기 시작했습니다. macOS Installer는 기기를 재부팅하기 전에 일부 APFS 메타데이터를 설정하는데, 추가 조사 결과 이것이 볼륨을 부팅 가능으로 표시하는 플래그라는 것이 드러났습니다. macOS 27 이전까지는 부트 도구가 이 플래그를 완전히 무시했습니다. 이 플래그를 Asahi APFS 컨테이너에 수동으로 설정하면, 다른 변경 없이도 macOS 27의 부트 피커에 다시 나타납니다.
앞으로는 모든 새 Asahi 설치에서 Asahi Installer가 이 플래그를 자동으로 설정하게 됩니다. 기존 설치를 수정할 수 있는 설치 프로그램 모드도 추가했습니다. macOS 27 개발자 베타를 설치했고 Asahi 설치에 접근할 수 없다면, 설치 프로그램을 다시 실행한 뒤 “Fix macOS 27 boot picker compatibility” 옵션을 사용해 주세요.
chaos_princess는 Linux에서 실행해 이 문제를 고칠 수 있는 프로그램도 개발했습니다. 우리는 결국 이 수정을 자동으로 배포하고 싶지만, 그것이 신뢰할 수 있고 누구의 파일시스템도 망가뜨리지 않는다는 점을 확인하려면 더 많은 테스트 데이터가 필요합니다. 여기서 여러분의 도움이 필요합니다. 테스트를 도와주실 의향이 있다면 이 저장소를 복제한 뒤, macOS 27로 업그레이드하기 전에 Linux에서 빌드하고 실행해 주세요. 이후 macOS에서 Asahi 볼륨이 여전히 부팅 대상으로 선택 가능하다면 성공한 것입니다. 진행 결과는 OFTC나 Matrix의 우리 채널 중 하나에 들러 꼭 알려 주세요. 특히 어떤 문제를 겪었다면 더욱 그렇습니다.
macOS 27은 전역 펌웨어를 사용하는 모든 주변장치의 펌웨어 업데이트도 함께 가져왔고, 여기에는 SMC도 포함됩니다. SMC의 수많은 기능 중 하나는 배터리 관리입니다. 우리의 Linux 전원 공급 드라이버는 SMC와 통신하여 충전 상태, 전압, 방전까지 남은 시간, 배터리 상태 같은 정보를 가져옵니다. 이 드라이버는 또한 SMC의 펌웨어 인터페이스를 사용해 충전 시작 및 중지 임곗값을 설정하여 배터리 수명을 늘립니다. macOS 27의 SMC 펌웨어는 배터리 관리 인터페이스 중 하나를 32비트 정수를 반환하던 방식에서 단일 바이트를 반환하는 방식으로 변경했습니다. 이 변경은 우리 드라이버를 혼란스럽게 만들었고, 특정 조건에서는 배터리가 고장 났다고 판단하여 시스템 보호를 위해 긴급 종료를 시작합니다. 우리는 이미 다운스트림 커널에서 이를 패치했습니다. 버전 7.0.12부터 전원 공급 드라이버는 두 펌웨어 ABI를 모두 처리할 수 있습니다.
이런 종류의 버그는 개발자 베타가 말 그대로 개발자 베타라는 점을 다시금 일깨워 줍니다. 운영 중인 실제 기기에 이를 설치하는 것은 권장되지 않습니다. 지금까지 우리가 겪은 두 가지 문제는 다행히도 경미했지만, 그렇다고 앞으로의 모든 문제가 그럴 것이라는 뜻은 아닙니다. 전역 펌웨어 업데이트는 사실상 영구적이기도 하며, 기기의 DFU 복원을 통해서만 되돌릴 수 있습니다. 앞으로는 개발자 베타 설치를 자제해 주세요. 우리는 여러분을 대신해 이런 것들을 시험할 희생용 기기들을 보유하고 있으므로, 비싼 하드웨어와 중요한 데이터를 직접 위험에 노출할 필요는 없습니다.
컴퓨터 플랫폼과 그 안에 들어가는 IC를 설계하고 검증하는 일은 극도로 비용이 많이 들고 시간도 오래 걸리므로, 꼭 필요하지 않다면 기존 설계를 바꾸는 것은 거의 합리적이지 않습니다. 프로젝트 초기에 우리는 Apple도 같은 판단을 내리고 둘 모두에 지속적으로 호환성 파괴 변경을 가하지는 않을 것이라고 예상했습니다. GPU처럼 세대마다 바뀌는 것이 거의 필수적인 더 큰 SoC 블록 몇 개를 제외하면, 이 예상은 대체로 들어맞았습니다.
Apple Silicon 노트북의 오디오는 여러 가지 IC와 SoC 블록이 관여합니다. 오디오 IC의 사실상 업계 표준은 오디오 데이터에 최적화된 I 2 C 기반 버스인 I 2 S입니다. Apple의 I 2 S 컨트롤러는 M1 이후 바뀌지 않았습니다. 이 모든 오디오 IC는 안정적인 클록 소스도 필요하며, 이는 다양한 오디오 데이터 속도에 맞게 설정 가능해야 합니다. Apple의 Numerically Controlled Oscillator (NCO) 역시 M1 이후 바뀌지 않았습니다. 또한 Apple은 거의 모든 Apple Silicon 기기에서 정확히 같은 스피커 및 헤드셋 증폭기 칩을 사용해 왔습니다. 따라서 chaos_princess가 M3 기기에 스피커와 헤드폰 잭 지원을 추가하기 시작했을 때, asahi-audio와 speakersafetyd를 위한 사소한 Devicetree 추가와 설정 파일 외에는 거의 더 필요하지 않았습니다. 그 결과 M3 기기는 이제 Asahi Linux에서 고품질 오디오 출력을 제공합니다!
M3 기기에는 CPU 주파수 전환과 올바른 big.LITTLE 작업 스케줄링 지원도 추가되었습니다. Apple은 기본 M2 이후 CPU 주파수 전환 방식도 바꾸지 않았기 때문에, 모든 M3 및 M3 Pro/Max/Ultra SoC는 기존 cpufreq 드라이버와 함께 동작하도록 Devicetree 변경만 있으면 충분했습니다. 이제 작업은 요구 사항에 따라 효율 코어 또는 성능 코어에 더 지능적으로 배치되어야 하며, CPU 코어 자체도 부하에 따라 클록을 올리고 내릴 것입니다. 이는 에너지를 절약할 뿐 아니라 성능도 향상시킬 것입니다!
SMC 하드웨어 센서 지원 추가도 비슷하게 간단했습니다. SMC의 펌웨어는 기기마다 실질적인 차이가 없기 때문에, 여기에서도 다시 몇 가지 Devicetree 변경만으로 충분했습니다.
위 내용에 더해, M3 계열 기기에서는 Linux용 PCIe, WiFi, Bluetooth, NVMe, 키보드, 트랙패드 및 기타 핵심 SoC 블록 드라이버도 동작하고 있습니다. 이 작업의 대부분은 Yureka의 공로로, 그는 한동안 자신의 M3 계열 기기들로 m1n1과 Linux 양쪽을 매우 활발히 해킹해 왔습니다. 이 기기들에 대해 Asahi Installer 지원을 활성화하기까지는 아직 갈 길이 남아 있지만, 진전 속도는 매우 빠르니 계속 지켜봐 주세요!
이 플랫폼의 복잡한 하드웨어 대부분은 복잡한 펌웨어 블롭을 사용합니다. 이들 대부분은 RTKit을 기반으로 하는데, RTKit은 Apple이 여러 하드웨어 구성 요소와 커널이 통신할 수 있도록 대체로 표준화된 인터페이스를 제공하기 위해 사용하는 RTOS 유사 펌웨어 프레임워크입니다. 하지만 예외도 있습니다. DCP와 AOP 같은 일부 블록은 펌웨어의 기반으로 RTKit을 사용하지만, 그 위에 EPIC이라는 또 다른 추상화 계층을 올립니다. 또 Broadcom WiFi/Bluetooth 칩셋처럼 Apple이 직접 통제하지 않는 서드파티 펌웨어를 사용하는 경우도 있습니다. 그리고 Apple Video Decoder (AVD)가 있습니다.
AVD는 특별합니다. 그 펌웨어는 RTKit도 아니고 EPIC도 아닙니다. 비밀스러운 제3의 무언가입니다. 하드웨어 자체는 본질적으로 ARM Cortex-M3가 AVC (H.264), HEVC (H.265), VP9, 그리고 더 최근 SoC에서는 AV1로 인코딩된 비디오 프레임을 디코딩하기 위한 일련의 고정 기능 하드웨어 유닛을 제어하는 구조입니다. 이 CM3는 XNU가 비디오 데이터를 가리킬 수 있는 인터페이스를 제공하는 펌웨어 블롭을 실행하고, 실제 디코더 하드웨어는 그 펌웨어가 직접 설정합니다. 보통이라면 괜찮았겠지만, Apple은 흥미롭게도 AVD의 펌웨어와 한 무더기의 설정 데이터를 AVD kext 안에 함께 묶어 두는 선택을 했습니다. 더 나쁜 점은 각 SoC가 조금씩 다른 AVD 변형을 가진다는 것입니다. 이는 물류적으로 까다롭습니다. Asahi Installer가 kext 내부의 펌웨어 데이터 오프셋에 대한 Apple의 변경을 지속적으로 갱신하고 추적해야 하기 때문입니다. 물론 할 수는 있지만, 더 나은 방법이 있다면 어떨까요?
XNU가 로드하는 펌웨어는 CM3에 의해 검증되지 않습니다. 신호를 받으면 실제로 무엇이 들어 있든 리셋 벡터부터 실행을 시작합니다. 그렇다면 그냥… 우리 자신의 펌웨어를 사용하면 어떨까요?
이 펌웨어는 사실상 기저의 비디오 디코더 하드웨어를 추상화하기 위해 존재할 뿐이므로, 여러 하드웨어 블록에 대한 인터럽트 핸들러만 설치한다면 실제로 무엇을 하든 상관없습니다. 기저 하드웨어가 무엇을 기대하는지만 이해할 수 있다면, 나머지는 Linux 드라이버에서 직접 모두 설정할 수 있습니다. 이를 위해서는 펌웨어가 각 디코더를 어떻게 구동하는지 이해해야 합니다.
표준적인 Cortex-M3 코드이므로, AVD 펌웨어를 에뮬레이터에서 실행하는 것이 가능합니다. 이를 위한 여러 해결책이 있으며, QEMU도 그중 하나로 프로그램을 한 단계씩 실행하고 버스 및 레지스터 동작을 조사할 수 있습니다. 이 작업의 기초는 수년 전 Jamie, R, 그리고 Eileen이 마련했습니다. 이들은 공동의 노력으로 AVC와 VP9 디코더가 필요로 하는 명령과 데이터 형식을 리버스 엔지니어링하는 데 성공했습니다.
XNU kext는 각 AVD 리비전에 대해 고유한 조정값 집합도 적용합니다. 우리는 이것들이 정확히 무엇을 하는지 완전히 확신하지 못하므로, 이를 적용하는 과정은 사실상 XNU가 수행한 MMIO 쓰기를 재생하는 방식이어야 합니다. 우리는 각 AVD 리비전, 각 조정값 집합, 그리고 그것이 어떤 리비전에 적용되어야 하는지를 추적해야 합니다. 이는 업스트림 Linux 커널 드라이버 안에서 만족스럽게 유지보수하기 불가능하므로, 이것도 아마 펌웨어 쪽에 두는 것이 맞을 것입니다.
오랫동안 이 전선에서 큰 진전은 없었지만, 새로운 기여자 sofus가 최근 이 공백을 메우기 위해 나섰습니다. 단순히 인터럽트 핸들러를 설치하고 각 변형의 조정값 집합을 적용하는 사용자 정의 AVD 펌웨어 블롭을 통해, 그는 AVC 하드웨어용으로 동작하는 V4L2 드라이버를 작성할 수 있었습니다! 이 하드웨어는 최대 4K의 10비트 AVC 인코딩 비디오를 디코딩할 수 있으며, V4L2 Request API를 구현한 소프트웨어와 잘 동작합니다. 펌웨어를 기본적이고 무상태로 유지하고, 모든 비디오 데이터 파싱과 디코더 자체 설정의 책임을 사용자 공간과 커널이 지도록 하는 방식은, 앞으로 어느 시점에는 VA-API와 Vulkan Video 같은 다른 비디오 가속 API도 더 쉽게 지원할 수 있게 해 줍니다.
사용자에게 AVD 지원을 제공하기 전에는 아직 할 일이 조금 남아 있습니다. AVD는 VP9, HEVC, 그리고 일부 SoC에서는 AV1까지 지원하지만, 우리는 아직 이들 어느 것에 대해서도 지원을 구현하지 않았습니다. 일부 기기에는 드라이버에서 시험하고 반영해야 할 특이사항도 있습니다. 너무 멀지 않은 미래에 여러분께 제공할 수 있는 무언가를 갖추길 바라고 있습니다!
최근 우리는 m1n1 버전 1.6.0에도 태그를 달았습니다. 이 릴리스는 배포판에 중요한 의미를 가지는데, stage 2 빌드에 Rust를 요구하는 첫 번째 버전이기 때문입니다. 이전에는 m1n1이 체인로딩 지원으로 빌드될 때만 Rust를 사용했습니다. stage 1 m1n1은 Apple의 부트 도구에서 XNU 커널을 대체하며, EFI System Partition을 마운트하고 그곳에서 stage 2 m1n1을 체인로드하는 데만 사용됩니다. 하지만 얼마 전 우리는 GPU 초기화를 m1n1으로 옮기기로 결정했습니다. 이로써 커널 드라이버가 Apple의 하드웨어 초기화 데이터에 들어 있는 부동소수점 숫자를 다룰 필요가 없어졌고, Devicetree 바인딩도 크게 단순화되었습니다. 우리가 결국 Linux Kernel Mailing List에 제출하게 될 GPU 드라이버 버전은 따라서 이 초기화를 m1n1이 대신 수행하는 것에 의존하게 됩니다. 또한 우리는 Apple Device Tree 파싱 코드를 Rust로 포팅했는데, 이는 m1n1의 사실상 거의 모든 다른 부분에서 사용됩니다.
m1n1은 사실상 펌웨어이기 때문에 no_std Rust를 사용하고 aarch64-none-softfloat를 대상으로 합니다. 불필요한 의존성을 끌어오지 않으려면, make에 BUILDSTD=1을 전달하여 전체 softfloat 툴체인 설치 없이 core와 alloc을 빌드할 수 있습니다.
버전 1.6.0은 또한 SPMI 컨트롤러와 PCIe 초기화 지원을 포함해 M3 계열 지원에 대한 대규모 개선을 가져옵니다. 이제 kisd를 사용하여 SoC의 하드웨어 UART를 DebugUSB를 통해 직접 터널링하는 것도 지원하며, 이를 통해 Central Scrutiniser와 거의 같은 기능을 구현할 수 있습니다. 이 작업의 상당 부분 역시 Yureka의 공로입니다.
또한 우리는 Apple의 비-macOS 부트 모드에 대한 더 나은 처리와 Apple Device Tree에서 발견되는 새로운 전원 도메인 메타데이터 지원을 포함해 M4와 A18 Pro (MacBook Neo) 지원의 기반도 마련하고 있습니다.
언제나처럼 GitHub Sponsors와 Open Collective에서 아낌없이 후원해 주시는 분들께 감사드립니다. 여러분이 없었다면 미완성인 M1 및 M2 기능 작업을 계속하거나, 열정적인 새로운 기여자들을 지원하면서 M3, M4, A18 Pro 지원 작업을 진행할 수 없었을 것입니다!
James Calligeros · 2026-06-30