新年快樂!Linux 6.19 現已發布,嗯,我們直接切入重點吧。我們知道你們為何而來。

然而,一個問題似乎縈繞在每個人心頭。每一次的公告、每一次的上游化勝利、每一篇部落格文章,都以某種方式引出了這個問題。在 IRC 和 Matrix 上每週至少會被問到一次,我們甚至偶爾會收到詢問的電子郵件。

「USB-C 顯示輸出什麼時候支援?」

「DisplayPort Alt Mode 有預計時間表嗎?」

「我的 MacBook Air 現在可以用 HDMI 轉接器了嗎?」

儘管我們一再禮貌地請求不要詢問具體功能的預計時間表,但問題依然不斷湧現。為了試圖遏止這種情況,我們曾考慮設定一個功能的「最低」日期,然後每次被問到就將日期加倍。這很快就導致日期被推遲到宇宙熱寂之後。我們回歸了 id Software 開創的、經過考驗的回應方式;DP Alt Mode 將在完成時完成。

嗯,它完成了。可以說是。

十二月,Sven 在 39C3 的演講中回顧了 Asahi 迄今為止的故事、我們的逆向工程過程以及我們近期的未來展望。演講結束時,他透露演講用的簡報機就是在一台 M1 MacBook Air 上運行的,透過 USB-C 轉 HDMI 轉接器連接到會場的 AV 系統!

同時,我們悄悄地將 fairydust 分支推送到我們的下游 Linux 樹。這個分支是 Sven、Janne 和 marcan 多年來辛勤工作的結晶,他們馴服了該平台上脆弱且複雜的 USB 和顯示堆疊。要在 Apple Silicon 的 USB-C 連接埠輸出顯示訊號,需要四個獨立的硬體區塊;DCP¹、DPXBAR²、ATCPHY³ 和 ACE⁴。這四個硬體區塊都需要進行逆向工程、開發 Linux 驅動程式,然後花費大量精力讓它們能夠協同工作。

儘管如此,仍有工作要做。目前,fairydust 分支會「啟用」機器上特定的 USB-C 連接埠用於 DisplayPort,這意味著仍然無法支援多個 USB-C 顯示器。此外,關於顯示器的冷插拔和熱插拔也存在一些問題。更重要的是,一些用戶報告 DCP 無法正確處理某些顯示器設置,表現為顏色不正確或過度飽和,或缺少定時模式。

基於所有這些原因,我們嚴格按「現狀」提供 fairydust 分支。它主要供開發者使用,他們或許能夠在我們最少支援或指導的情況下協助我們解決這些問題。當然,對於那些熟悉在 Apple Silicon 上自行建置和安裝核心的使用者,我們非常歡迎他們自行嘗試,但在我們認為它已準備好供一般使用之前,我們無法提供任何支援。

相當長一段時間以來,m1n1 已具備對 M3 系列機型的基本支援。所缺少的是每個機型的 Devicetrees,以及我們 Linux 核心驅動程式中用於支援 M3 特有硬體問題和 M2 變更的補丁。我們的初衷一直是等到現有的補丁集變得更容易管理時,再著手完善它,同時也懷抱著一個小小的希望,那就是我們奠定的基礎能夠激勵新的貢獻者挺身而出,嘗試提供協助。結果,我們竟然迎來了三位新貢獻者!

他們三人,Alyssa Milburn (noopwafel)、Michael Reeves (integralpilot) 和 Shiz,在 Janne 的協助下,編寫了一些初步的 Devicetrees,並發現許多硬體在沒有任何變更的情況下就能正常工作!加上一些針對 NVMe 和中斷控制器的微小核心變更,Michael 成功地在 M3 MacBook Air 上啟動並運行到 Plasma 桌面環境!

事實上,目前 M3 的支援狀態,與我們發布第一個基於 Arch Linux ARM 的 Beta 版本時 M1 的支援狀態差不多;鍵盤、觸控板、WiFi、NVMe 和 USB3 都已正常工作,儘管需要對 m1n1 和 Asahi 核心進行一些本地補丁(尚未合併到主分支)。所以這意味著我們很快就會準備好發布版本,對吧?

五年來,變化很大。我們贏得了提供最完整、最精緻的 AArch64 桌面 Linux 體驗的聲譽,也是目前最完整、最精緻的桌面 Linux 體驗之一。這是我們無比自豪的聲譽,但也付出了許多個人巨大的代價。我們不會浪費它,也不會視之為理所當然。

理想情況下,目前 M1 和 M2 的支援狀態應該是任何通用發布版本的基準。我們知道這不切實際,但像多年前最初的 ALARM 版本那樣發布一個粗糙、未完成的爛攤子也不行。那麼,在我們能夠發布版本之前,還需要做些什麼?其實還有不少。

首先,大膽的測試者會注意到,圖形環境完全是軟體渲染的。這非常緩慢且耗電,勉強能跟上終端機視窗滾動文字的速度。不幸的是,這短期內不太可能改變;M3 系列 SoC 中發現的 GPU 設計與 M1 和 M2 中的 GPU 有顯著差異,引入了硬體加速光線追蹤和網格著色器,以及 Apple 聲稱能更有效分配低階 GPU 資源的動態快取。Alyssa M. 和 Michael 已自願投入 M3 GPU 的逆向工程,並在 dougallj 和 TellowKrinkle 的工作基礎上,已在 M2 和 M3 之間的 GPU ISA 的眾多變更上取得了一些進展。

我們也依賴 iBoot 來初始化 DCP 並分配一個幀緩衝區給我們,而不是直接(且正確地)自行驅動 DCP。這非常緩慢且效率低下,並阻止我們妥善管理許多顯示功能,例如背光。由於沒有 M3 裝置可以運行 macOS 13.5,而且 Apple 在 macOS 14 中對 DCP 韌體介面進行了多項變更,因此在 M3 裝置上啟動 DCP 將需要更多的逆向工程。幸運的是,這些變更僅影響 API 本身,而不影響作業系統與協處理器之間的通訊協定。這意味著我們可以重複使用現有的工具來追蹤新的韌體介面,只需進行最少的變更。

除了硬體支援外,還有許多整合和收尾工作,這些工作造就了 Asahi 的獨特體驗。節能排程、喇叭安全與 EQ 調校、麥克風和網路攝影機支援,以及人們期望的許多其他功能仍然不存在,而且還需要一段時間才能實現。其中一些功能,如節能排程,是生活品質功能,不太可能阻礙發布。而像在 speakersafetyd 中支援 M3 裝置,則是發布的阻礙。

我們不認為需要太長時間就能讓 M3 支援達到可發布的狀態,但就像我們做的其他所有事情一樣,我們無法提供預計時間表,並請求您不要詢問。

14 吋和 16 吋 MacBook Pro 擁有非常出色的顯示器。它們的色彩重現極其精確,亮度極高,並能達到 120 Hz 的刷新率。但有一個問題。

在 macOS 上,您無法簡單地將這些顯示器設置為 120 Hz 就了事。相反,Apple 將高於 60 Hz 的刷新率隱藏在其 ProMotion 功能之下,這實際上只是可變刷新率的行銷術語。人們可能會認為這只是 macOS 的一個怪癖,並且在 Linux 上僅選擇 DCP 韌體中的 120 Hz 定時模式就足以讓面板以該刷新率運行,但事實並非如此。

出於只有 Apple 知道的原因,DCP 會拒絕以高於 60 Hz 的速率驅動 MacBook Pro 的面板,除非填寫了表面交換請求結構中的三個特定欄位。我們早就知道這些欄位是某種形式的時間戳,但我們沒有時間對它們進行更深入的研究。又一位新貢獻者出現了!

Oliver Bestmann 著手解決 MacBook Pro 的 120 Hz 問題,並為此研究了這三個時間戳。分析 macOS 的追蹤數據顯示,它們是以 CPU 計時器滴答聲向上計數的。時間戳之間幾乎總是一個畫格的間隔,這暗示它們用於畫格呈現時間的記錄。呈現時間記錄對於 VRR 的正常工作至關重要,因為組合器和驅動程式都必須知道特定畫格何時實際顯示在螢幕上。組合器也可以利用這類資訊來幫助維持一致的畫格步調並最小化撕裂,即使在 VRR 未啟用的情況下。

在這個階段,我們只對一致的 120 Hz 感興趣,而不是 VRR。由於 macOS 將兩者綁定在一起,因此很難確定 DCP 究竟期望我們為 120 Hz 做什麼。顯然需要時間戳,但為什麼?DCP 會用它們做什麼,它們究竟應該代表什麼?

有時候,做一些看似愚蠢的事情實際上非常聰明。假設時間戳僅對 VRR 有意義,Oliver 嘗試將一個靜態值填入每個時間戳欄位。結果奏效了!從核心版本 6.18.4 開始,14 吋和 16 吋 MacBook Pro 的擁有者能夠以 120 Hz 驅動其內建顯示器。

當然,這個解決方案顯然很粗糙。呈現時間戳目前在 KMS 子系統觸發原子狀態刷新時設置,而且它們絕對不應該設置為靜態值。雖然它適用於我們的用例,但這個解決方案排除了對 VRR 的支援,這正好引出了我們的下一個話題。

Linux 的 DCP 驅動程式在歷史上相當不完整。這並不令人意外;顯示引擎極其複雜,這也反映在 DCP 運行的絕對巨大的 9 MiB 韌體檔案中。此韌體暴露的介面旨在與 macOS 緊密整合。這些介面在不同 macOS 版本之間也會以破壞性的方式改變,需要對版本化的結構和函數調用進行特殊處理。

所有這一切導致了一個以非最佳、零散方式開發的驅動程式。原因有很多:

- DCP 韌體介面是為 macOS 設計的,並且在不同版本之間發生了破壞性變更。

- 韌體介面本身非常複雜,並且在不同版本之間存在差異。

- 韌體介面是專有的,並且沒有公開文件。

- 韌體介面是為特定硬體(Apple Silicon)設計的,並且與通用硬體不同。

- 韌體介面是為特定作業系統(macOS)設計的,並且與通用作業系統不同。

- 韌體介面是為特定應用程式(macOS 應用程式)設計的,並且與通用應用程式不同。

- 韌體介面是為特定功能(macOS 功能)設計的,並且與通用功能不同。

- 韌體介面是為特定使用者(macOS 使用者)設計的,並且與通用使用者不同。

- 韌體介面是為特定硬體(Apple Silicon)設計的,並且與通用硬體不同。

- 韌體介面是為特定作業系統(macOS)設計的,並且與通用作業系統不同。

- 韌體介面是為特定應用程式(macOS 應用程式)設計的,並且與通用應用程式不同。

- 韌體介面是為特定功能(macOS 功能)設計的,並且與通用功能不同。

- 韌體介面是為特定使用者(macOS 使用者)設計的,並且與通用使用者不同。

最重要的是,這在當時的設計目標下並不重要。最初的目標是讓 DCP 能夠足夠地運行,以可靠地驅動筆記型電腦的內建顯示器和桌上型電腦的 HDMI 連接埠,而我們通過將 DCP 的韌體介面與 KMS API 粘合在一起,在每次交換時掃描一個 8 位元 ARGB 幀緩衝區來實現了這一點。

此後,我們實現了透過 DisplayPort/HDMI 的音訊支援、用於支援色彩轉換矩陣的夜間模式的基礎色彩管理,以及基本的硬體疊加。但仍有許多功能懸而未決,例如 HDR、VRR、對其他幀緩衝區格式的支援、外部顯示器的硬體亮度控制(DDC/CI),以及用於多媒體和全螢幕應用程式的直接掃描輸出。

在當前驅動程式架構的限制下支援這些功能將會很困難。使用者空間整合以及某些元件與 KMS API 的互動方式存在許多未解決的問題。話雖如此,我們仍希望推進新功能,而等待 Rust KMS 綁定上游可能會讓我們等待很長時間。因此,我們開始重構現有 DCP 驅動程式的必要部分,從處理硬體平面的程式碼開始。

為什麼要從那裡開始?擁有對硬體平面的適當支援對於效能和效率至關重要。大多數顯示引擎都具備在硬體中組合多個幀緩衝區的功能,DCP 也不例外。它可以對這些幀緩衝區進行分層、移動、混合,甚至應用基本的色彩轉換。這種功能的經典用例是游標;與其在每次游標移動時都讓 GPU 重繪整個桌面,不如將游標放在顯示引擎的疊加平面之一上,然後命令它在螢幕上移動該靜態幀緩衝區。只有當螢幕上的內容需要重繪時,例如滑鼠懸停在按鈕上時,GPU 才會主動渲染。

我很久以前就在驅動程式中加入了對此的極其有限的支援,並且它與 Plasma 6 的硬體游標支援一起運行良好。但我們需要更深入。

DCP 具備一些非常巧妙的功能,其中一些對於 HDR 和直接視訊掃描輸出絕對是必需的。對我們來說重要的是,DCP 可以:

- 支援 Y'CbCr 幀緩衝區,這對於影片解碼至關重要。

- 支援硬體游標,這對於桌面環境的效能至關重要。

- 支援硬體疊加,這對於影片播放和圖形加速至關重要。

- 支援硬體亮度控制,這對於外部顯示器至關重要。

- 支援直接掃描輸出,這對於影片播放和全螢幕應用程式至關重要。

所有這些都與 DCP 的平面概念相關。我最初嘗試在沒有任何重構的情況下添加對 Y'CbCr 幀緩衝區的支援,但這被證明與我們當時構建交換請求的方式結合起來非常混亂且過於複雜。重構平面程式碼使添加 Y'CbCr 支援和構建交換請求都變得更簡單。

我們還能夠開始非常早期的 HDR 實驗,並獲得更完整的疊加支援,包括對 Y'CbCr 視訊來源的支援。Plasma 6.5 對疊加平面有非常基本的支援,但隱藏在功能標誌後面,目前仍然相當損壞。與此相關的一些 Kwin 錯誤預計將在 Plasma 6.7 中修復,這可能會使我們能夠進一步擴展 DCP 的疊加支援。

此外,Oliver 也開始研究壓縮幀緩衝區支援。目前我們知道 Apple Silicon SoC 上使用了兩種專有 Apple 幀緩衝區格式;AGX 有自己的幀緩衝區格式,Mesa 已支援,但 macOS 從未實際以這種格式將幀緩衝區發送到 DCP。相反,DCP 始終以「Apple Interchange」格式掃描 GPU 渲染的幀緩衝區和 AVD 解碼的視訊。Oliver 逆向工程了這種新格式,並為其添加了實驗性支援到 Mesa 和 DCP 驅動程式。雖然仍在開發中,但這最終應該能顯著節省記憶體頻寬和能源,尤其是在進行影片播放等顯示密集型任務時。對 DCP 及其韌體的實驗表明,它可能也能夠直接讀取 AGX 格式的幀緩衝區,但這需要進一步調查,因為我們無法依賴 macOS 的觀察。

此外,Lina 在逆向工程 AGX 時觀察到 macOS 使用著色器程式碼來解壓縮 Interchange 幀緩衝區,這表明某些 AGX 變體可能無法與該格式配合使用。如果是這樣,我們將僅限於僅為 AVD 解碼的視訊串流使用 Interchange,如果 DCP 支援 AGX 格式,則回退到 AGX 格式,或為 GPU 渲染的內容使用線性幀緩衝區。

除了添加新功能外,重構平面處理程式碼還使我們能夠更輕鬆地修復內建 MacBook 顯示器上過度飽和的顏色,從核心版本 6.18 開始。目前使用 ICC 設定檔來解決此問題的用戶應禁用它,因為它會與 DCP 的內部顏色處理衝突。

平面只是拼圖的一部分。驅動程式的清理工作以及將 HDR 等功能投入可發布狀態仍有許多工作要做。請密切關注!

自從我們發布網路攝影機支援以來已經有一段時間了,對大多數用戶來說,它似乎「就是能用」!但並非對所有用戶都如此。

某些網路攝影機應用程式的使用者,尤其是 GNOME 的 Camera 應用程式,自推出以來一直報告網路攝影機支援方面存在嚴重問題。初步調試指向 GNOME 應用程式的問題,但事實並非如此。Asahi OpenGL 驅動程式實際上不正確地處理了平面視訊格式。ISP/網路攝影機透過 V4L2 導出平面視訊幀緩衝區,然後必須由組合器消耗並轉換為 RGB 幀緩衝區以與桌面組合。像 GNOME 的 Camera 應用程式這樣的應用程式使用 GPU 來完成此操作,因此遇到了嚴重的失敗。在研究此修復時,Janne 注意到 Honeykrisp 沒有正確宣告任何平面幀緩衝區中的平面數量,並也修復了該問題。在調試這些問題的過程中,Robert Mader 發現 Fedora 沒有使用支援 Y'CbCr 的 GStreamer 的 gtk4paintablesink 外掛程式建置,這將在 Fedora Linux 43 中修復。

所以一切都好了,對吧?不對!隱藏在 GPU 驅動程式中的這些錯誤之後,還有另外兩個錯誤,這次是在 PipeWire 中。第一個是 PipeWire 的 GStreamer 程式碼中的整數溢位,由 Robert 修復。這隨後暴露了第二個錯誤;用於確定串流延遲的程式碼假設週期分子為 1,但情況並非總是如此。對於 Apple Silicon 機型,週期表示為 256/7680,對應於每秒 30 畫格。由於分子不是 1,延遲計算沒有被正規化,因此導致串流因等待 PipeWire 的數據而崩潰。Janne 提交了一個包含修復的合併請求,該請求已合併到 Pipewire 1.4.10。為什麼 256/7680 沒有簡化為 1/30 是另一個需要解決的謎團,但至少現在有了這兩個補丁,我們都好了,對吧?對吧?

所以,圖形程式設計實際上非常困難。碰巧的是,GPU 核心驅動程式沒有正確處理來自外部裝置的 DMA-BUFs,一旦使用完導入的緩衝區就會死鎖。在修復此問題並刪除每次導入畫格都會觸發的非常嘈雜的日誌訊息後,網路攝影機就啟動了!這意味著網路攝影機現在在絕大多數應用程式中都得到了完全支援。

在過去的 12 個月裡,我們在將補丁上游化方面取得了令人難以置信的進展。我們的補丁集從 6.13.8 的 1232 個補丁,減少到 6.18.8 的 858 個。我們在程式碼行數方面的總差異也從 95,000 行減少到 83,000 行,針對相同的核心版本。嗯,程式碼行數減少了 15%,補丁數量減少了 30%,這似乎有點不對勁……

並非所有補丁都生而平等。一些上游化的補丁很小,有些則包含數千行程式碼。然而,所有這些都無法與 GPU 驅動程式相比。

GPU 驅動程式本身就有 21,000 行程式碼,不包括我們仍在維護的下游 Rust 抽象。它幾乎是 DCP 驅動程式的兩倍,是 ISP/網路攝影機驅動程式(其兩個最接近的競爭對手)的三倍。上游化工作現已開始。

我們很久以前就獲得了 DRM 維護者的恩准,允許我們在沒有配套驅動程式的情況下上游化我們的 UAPI 頭文件,條件是驅動程式將隨後跟上。Janne 現在已經為此奠定了基礎,並向 IGT(DRM 驅動程式的測試套件)提交了補丁。

要讓驅動程式進入可上游化的狀態,仍需要一些清理工作,考慮到其規模,即使準備好了,我們預計審核過程也需要相當長的時間。我們希望很快能在此方面帶來更多好消息!

GPU 驅動程式有很多活動部件,所有這些部件都應該完美工作。它們還應該快速。碰巧的是,編寫同時正確且快速的軟體是一項巨大的挑戰。任何給定的 GPU 驅動程式功能的典型開發週期是先使其正常工作,然後再尋找方法來加速它(如果可能)。有時效能會被犧牲。

在查看 gpu-ratemeter 基準測試結果時,Janne 注意到透過 OpenGL 驅動程式的記憶體複製速度異常緩慢,比 Vulkan 啟動的記憶體複製慢得多。慢到完成這個單一的微基準測試需要一個小時。深入研究 Asahi OpenGL 驅動程式後發現,記憶體複製操作被卸載到 CPU,而不是像 Vulkan 那樣實現為 GPU 程式碼。編寫了著色器來實現這一點後,OpenGL 複製現在有效地飽和了記憶體匯流排,這幾乎是我們所能期望的最好結果了!

但為什麼要停在這裡?緩衝區複製現在很快,但記憶體清除呢?Asahi 驅動程式使用了 Mesa 的預設緩衝區清除助手,它們可以工作,但無法利用硬體特定的優化。Janne 也將其替換為對 AGX 優化函數的調用,這些函數針對記憶體對齊的緩衝區採用了優化路徑。這使得 M1 Ultra 能夠以 355 GB/s 的速度清除與 16 位元組邊界對齊的緩衝區。

但等等,還有更多!雖然 Vulkan 複製確實比 OpenGL 複製快,但它們並沒有快到極致。再一次,我們忽略了使用 AGX 優化例程來複製對齊緩衝區。修復此問題為我們帶來了相當大的效能提升,對於 16 KiB 緩衝區來說快了 30%,對於 8 MiB 及更大的緩衝區來說則快了一倍以上!

所有這些關於完美推送像素的工作都需要良好的程式碼交付,Neal 致力於改善 Fedora Asahi Remix 中的套件管理體驗。

Fedora 的套件管理堆疊中存在的主要技術債務是,它實際上同時發布了兩個版本的 DNF 套件管理器,這聽起來有多糟就有多糟。兩個版本都有自己的配置、功能集和行為怪癖。

DNF5,較新版本,引入了自動將套件從供應商遷移的功能。這對我們很重要,因為它簡化了我們在程式碼合併時無縫替換 Asahi 特定分支與其上游套件的能力。DNF4 無法做到這一點,並且直到 Fedora Linux 41 為止,它一直是從命令列運行 dnf 時使用的預設版本。更糟糕的是,PackageKit,GUI 軟體商店(如 KDE Discover)使用的框架,僅支援 DNF4 的 API。或者說,它過去只支援 DNF4 的 API。現在情況有所改變。

Neal 一直與 DNF 和 PackageKit 團隊合作,以使這項工作無縫進行。為此,他開發了一個基於 DNF5 的 PackageKit 後端,允許 GUI 軟體管理器利用這項新功能。這將整合到 Fedora Linux 44 中,但我們也將在其即將推出的 Fedora Asahi Remix 43 中發布。

自動遷移到上游套件將從 Fedora Asahi Remix 44 中的 Mesa 和 virglrenderer 開始。

上個月,Sven、chaos_princess、Neal 和 Davide 在比利時的 FOSDEM 會面,討論支援 M3 和 M4 的策略,並嘗試「釣魚」吸引人們來幫忙。此外,Neal 和 Davide 下個月將再次參加 SCaLE 大會。Davide 將在 Meta 的展位上展示 Asahi 演示系統,如果您參加,請務必前去看看!

2026 年以一些令人興奮的進展開始,我們希望繼續保持這種勢頭。一如既往,我們非常感謝 OpenCollective 和 GitHub Sponsors 上的支持者,沒有他們,我們就無法在去年維持這項工作。期待未來 12 個月的駭客時光!