附錄

查東西的時候才來:名詞、出處、要買什麼,以及每次動手留下的紀錄。

§1名詞表

這個專案橫跨磁碟、開機、kernel、晶片四個層次,名詞會一直冒出來。 這裡只收會重複出現的,每條一句話,附上「跟這個專案有什麼關係」。

磁碟與分割

名詞是什麼跟你的關係
分割區硬碟上切出來的一塊空間,大小固定—
APFS container分割區裡的一大塊硬碟空間,裡面的 volume 共用它、不用事先切死大小裝第二份 macOS 時會建一個新的
volumecontainer 裡的一個檔案系統—
volume groupSystem + Data + Preboot + Recovery 的組合 = 一個 macOS 安裝hypervisor 要的 14.8.3 需要一整組,不是單一 volume
Preboot存放「主系統掛載前就需要的東西」的 volume,每個安裝一個 UUID 資料夾韌體、開機政策、kernelcache 都在這裡 —— 你要挖 kernelcache 就是去這
stubAsahi 安裝時建的約 2.5GB 迷你 macOS,有殼沒肉、不能開機進去用裡面有韌體 + m1n1 + 開機政策。刪掉 Asahi 就開不了機
ESP(EFI 分割區)FAT32 分割區,掛在 /boot/efi放 GRUB 和 vendorfw/。kernel 不在這裡,在 /boot

開機鏈

名詞是什麼跟你的關係
Boot ROM燒在矽晶片裡的第一棒,永遠不可改信任鏈的根,你碰不到
iBoot 第一階段Apple 韌體,全機共用一份。初始化記憶體、儲存、DFU—
iBoot 第二階段每個 OS 安裝各自一份。載入該 OS 的韌體組、執行它的安全政策這就是為什麼 Asahi 能降安全等級而 macOS 26 不受影響
m1n1Asahi 的開機載入器,被註冊成 stub 那個「OS 的 kernel」現在就在你的開機鏈裡。hypervisor 是它的另一種模式,不是新裝的東西
U-Boot把 Apple 的特殊環境轉成標準 Linux 開機介面(內含 UEFI 實作)—
GRUB讀開機項目清單、顯示選單、載入你選的 kernel動手前先讓它顯示出來,否則新 kernel 開不起來沒地方退回
DFU 模式用另一台 Mac 重刷韌體的救援模式,分兩種: revive 只重刷韌體、保留資料;restore 才會清空整顆硬碟 最後的安全網。先試 revive,restore 是最後手段(所以還是要備份)
ADTApple 自己的 device tree 格式,由 iBoot 提供m1n1 讀它來認機型、抓執行期數值

kernel 與檔案

名詞是什麼跟你的關係
vmlinuz編譯好的 kernel 本體(壓縮過)在 /boot/vmlinuz-<版本>
initramfs開機用的暫時根目錄,讓 kernel 有辦法掛載真正的 rootfs必須在 target 機器上產生,不能在 macOS 上做
device tree一份硬體清單,告訴 kernel「有哪些區塊、在哪個位址、用哪條中斷」ARM 的硬體無法自我介紹,所以必須有人寫下來。DTS 就是逆向成果的存放處
DTBdevice tree 編譯後的二進位檔裝 kernel 一定要連 DTB 一起裝,否則新 driver 永遠不會被實體化
BLS / loader entries/boot/loader/entries/,一顆 kernel 一個 .conf裝完看這裡有沒有多一項 = 最快的驗證
.configkernel 的編譯設定檔,幾千個選項一定要從 /boot/config-$(uname -r) 複製當起點
16K page記憶體分頁大小。TLB 涵蓋範圍大四倍,Apple 硬體照這個設計編錯成 4K 會壞掉 —— 從現有 config 起手就自動正確
fairydustAsahi 的實驗分支,含 USB-C DP 輸出的程式碼官方明說「strictly as-is」,只給開發者、不提供支援。 但 USB-C 出圖只有這裡有 —— #601 的結論就是「換到這個分支就好了」

晶片內部

名詞是什麼跟你的關係
APApplication Processor —— 跑作業系統的主 CPU 核心「AP call」= 協處理器反過來呼叫作業系統
協處理器SoC 裡的其他 CPU,各自跑自己的韌體一顆 M1 Pro 裡有十幾顆
DCP顯示協處理器。在 Mac 裡,跑 Apple 韌體,實際操作顯示硬體斷點 2 的對話對象。你只能透過 mailbox 跟它講話
A13在 Studio Display 裡的一整顆 SoC,管面板、hub、攝影機斷點 2 要叫醒的是它,但做這件事的是 DCP,不是你
atcphyType-C PHY,把訊號送上線。driver 直接讀寫它的暫存器斷點 1 的位置(phy/apple/atc.c)。 stable kernel 沒有 DP 這條路,fairydust 有
tipdUSB-PD 控制器,負責協商模式與供電決定協商到 DP Alt Mode 還是 TB
ACIOApple Converged I/O —— Thunderbolt 那組硬體(含 Cortex-M3)路線 B 的核心,Sven 的 22 個 patch 在處理
RTKitApple 協處理器共用的通訊協定已逆向完成,多個 driver 共用
DARTApple 的 IOMMU(記憶體存取保護)已上游,16K 粒度
mailbox / AP callAP 與協處理器之間的雙向訊息機制兩邊都能發起。call 20 是 DCP 問你,不是你問它

「韌體」的三種意思

種類存在哪例子
燒在矽晶片裡不可改,永久Boot ROM
裝置自帶裝置自己的快閃記憶體,可更新但持久Studio Display 的 A13、SSD 控制器
開機時載入平常是磁碟上的檔案,每次開機載進協處理器DCP、WiFi、ACIO

第三種是 Asahi 要從你的 macOS 抓出來的那種,也是「OS-paired firmware」的意思 —— 你的 DCP 韌體來自 macOS 26,跟其他回報者不同。

這個專案的專用說法

名詞意思
t8103 / t600xSoC 代號。t8103 = 原版 M1(你的 mini);t600x = M1 Pro/Max(你的 MBP)
target被觀測的機器。螢幕插這台,m1n1 和 macOS guest 都在這台
host旁觀者。只跑 Python、收資料、印 trace,不影響 target
DP Alt Mode把 Type-C 的實體通道直接改接成 DisplayPort。不是降級版的 TB,是另一套協定
DSCDisplay Stream Compression,顯示串流壓縮。頻寬不夠時靠它擠出高解析度
斷點 1 / 斷點 2斷點 1 = atcphy 切不進 DP 模式 (已解:換 fairydust,#601 closed);斷點 2 = DCP 的 call 20 沒人會回 (未解,#579 open)。舊版本頁面稱它們為 Bug 1 / Bug 2

兩個斷點(狀態為 2026-09-23 查證)

  • #601 —— M1 Pro atcphy_mux_set / Failed to lock pipehandler —— closed(2026-09-07,completed)。 同型機(MacBookPro18,3)回報者換到 fairydust 後 USB-C 螢幕點亮; 結論是 stable kernel 的功能缺口,不是 bug。
    • 他的 .config 直接拿現在跑的那顆(/proc/config.gz),需要的符號本來就都開著:CONFIG_DRM_APPLE、CONFIG_PHY_APPLE_ATC、CONFIG_PHY_APPLE_DPTX、CONFIG_MUX_APPLE_DPXBAR、CONFIG_TYPEC_DP_ALTMODE
    • 裝成獨立的並存 package,stable kernel 留在 GRUB 當退路
    • 冷插比熱插可靠 —— 開機前就把螢幕插著
  • #579 —— Studio Display unhandled AP call 20 —— open,4 則討論。 2026-08-24 由 M2 13"(t8112)回報;thejamescollins 在 M1 Max 16"(t6001)重現, 並在同機用 USB-C→HDMI 轉接頭跑到 4096x2160@60;chadmed 要求的 「full-spec 非 Thunderbolt USB-C 線」測試還沒有人做。

相關 PR(都沒 merge)

工具與現成方案

官方文件

§3材料清單

硬體

  • MacBook Pro 14" M1 Pro(MacBookPro18,3,t600x)—— host, 跑 python proxyclient,同時是最終要修好的那台。 host 只需要能跑 python 和認到 USB 序列裝置;官方文件是以 host OS(macOS / Linux) 區分裝置節點名稱,沒有對 host 的 CPU 設限。你的 host 跑 Linux,所以裝置是 /dev/ttyACM0。
  • Mac mini M1(t8103)—— target,被觀測的那台。 macOS 14.8.3、降安全模型、關 SIP 都發生在這台。
  • Apple Studio Display —— 最終目標。trace 時插在 target(mini)上
  • host ↔ target 的 USB 線:先試 Apple 原廠 USB-C 充電線(C-to-C,不要用 Thunderbolt 線); 不順就換 USB-C→USB-A(m1n1 文件建議這種,插 host 的 USB-A 孔)
  • 一條 full-spec 非 Thunderbolt 的 USB-C 線 —— 接 Studio Display 用,優先度最高。 chadmed 在 #579 點名要這種線的測試結果,至今沒人做得出來(回報者手上沒有)。 不要 Thunderbolt 線、不要充電線;要標示支援 USB 3.2 / DP Alt Mode 的全規格線。
  • ThinkPad X1 Gen 9(可選的 host)—— host 是純終端機, x86 和 arm64 沒有差別,Asahi 開發者多數就是用 x86 Linux 當 host。 唯一差別是編譯 m1n1 要裝交叉編譯器(gcc-aarch64-linux-gnu), 而在 Mac 上一樣要裝裸機工具鏈。用它當 host 可以把 MBP 空出來當日常機。 注意:萬一 target 需要 DFU revive,那只能用 Mac 做。
  • 一台「笨」螢幕 —— 用來確認「斷點 1 在你機器上真的沒了」,也是階段 3 的對照組。
    建議挑同時有 USB-C(DP Alt Mode)和 HDMI 輸入的: USB-C 那孔驗證 fairydust 的 DP 路徑,HDMI 那孔測內建 HDMI 在 macOS 26 韌體下還會不會動,平常還能當第二螢幕。
    • 必要:USB-C 輸入要標明支援 DP Alt Mode(有些 USB-C 孔只供電或只傳資料)
    • ❌ 避開 DisplayLink:它走 USB 資料由 CPU 算圖,完全繞過 DP 路徑 —— 可能真的會出圖,但你什麼都沒測到,還會誤判 DP 路徑已經通了
    • ❌ 不要 Apple 的顯示器:有內建處理器就會觸發斷點 2,失去當對照組的意義
    • ❌ 沒有「Thunderbolt 專用」這種規格,買普通的就好
    • 加分:#601 的回報者就是用 ARZOPA Z1FC 16"(純供電模式)在 M1 Pro 上成功的。 買同一台,等於直接複製一個已知會成功的實驗
  • 替代方案:USB-C → HDMI 轉接頭 + 現有的電視,最便宜,一樣避開 DisplayLink
  • 外接 SSD(選配)—— 放測試用的 macOS volume,不佔內建空間

軟體與帳號

  • Fedora Asahi Remix(已裝,在 host 上)
  • macOS 14.8.3(備案 13.5),裝在 target(Mac mini)上一個完整的獨立 volume group。 不要用你現在的 macOS 安裝。你的兩台機器出廠版本都夠舊,macOS 26 不會擋住這件事(見方向 §5)
  • m1n1 repo + python proxyclient 相依套件(裝在 host,也就是 MBP 上)
  • img4tool —— 解 kernelcache
  • GitHub 帳號 —— 留言、送 PR
  • Apple Developer 帳號(選配)—— 下載 KDK 取得帶符號的 kernel。第一次可以不用
firmware 版本要對齊。 Asahi 直接載入 macOS 安裝裡的 DCP firmware,而協議會隨 firmware 版本改變 (driver 裡有針對不同版本的 struct layout)。錄 trace 的版本要跟你 Linux 下跑的同一版。 這是一般 Linux 驅動開發者不會遇到的概念,但它會解釋掉你之後看到的一半怪現象。

要補的知識地圖

MMIO(記憶體映射 I/O)· 中斷 · DMA / IOMMU · clock 與 power domain · device tree · bus 列舉 · 協處理器的 mailbox / RPC · firmware 版本化的 ABI(Asahi 特有)

語言

這個社群大多數人母語都不是英文;你的貢獻內容 —— dmesg、trace dump、 「這樣會動/不會動」—— 是語言中性的;issue tracker 是非同步的,一則訊息花一小時寫沒人在意。 用翻譯工具處理你自己要講的話跟查字典一樣,不涉及 trace 解讀,碰不到政策那條線。

§4日誌

每次動手記一筆:做了什麼、量到什麼、發現什麼、哪裡做得不好、下次從哪裡接。最新的在最上面。
技術細節不寫在這裡 —— 那些整理進實作頁,這裡只留當下的過程和判斷。

2026-09-23 晚 ~ 09-24 凌晨 · 第一次動手

從「這份計畫書該怎麼修」開始,結果一路做到外接螢幕點亮。

一句話結論

冷插完全正常;熱插拔畫面回不來,但套了 #622 之後不會再卡住整台電腦。 剩下的卡點在合成器:一個永遠等不到完成的 page flip 把 aquamarine 鎖死了。

做了什麼

  1. 查證計畫書的前提,發現 #601 已在 2026-09-07 結案 —— 原本「兩個 bug、先解 Bug 1」的框架不成立了。 整份計畫書依此改寫,六張圖用 archify 重新產生
  2. 讀完 build 腳本(600 行)。確認 kernel 原始碼是執行時從上游 clone、 .config 抄本機的、README 講的第 9 步在 main() 裡是註解掉的
  3. 跑 build。第一次 --filter=blob:none 的 clone 空等三分鐘零 bytes(GitHub 在算 pack), 改用 --depth 1 才動。編譯本身 60~90 分鐘
  4. 開機設定:asahi-bless --set-boot fedora(預設不再開進 macOS)、 grubby --set-default 指到 fairydust、把 GRUB 選單叫回來
  5. 第一次插螢幕沒反應 —— 插到左後那孔了。查 device tree 的 connector label 才確認 DP 只在 usb-pd@3f = USB-C Left Front
  6. 換孔,亮了。MSI MAG161V,1920x1080@60,Hyprland 正常接手
  7. 測熱插拔 → 不亮,而且整台卡住幾十秒
  8. 診斷後找到 #622,確認能乾淨套用到現在的 tree
  9. 白做了一輪:中途跑過 git apply -R 把 patch 退掉卻沒發現, 裝上去的是沒 patch 的模組,測出來當然跟原本一樣
  10. 重套、驗證 .ko 裡真的有 patch 的字串、重裝、重測
  11. 結果:不卡了,但畫面還是回不來。追到 hyprland.log 才看清楚原因

量到的東西

指標#622 前#622 後
冷插(開機前就插著)會不會亮✅ 會✅ 會
atcphy_mux_set WARNING有沒有了
flip_done timed out2 次0 次
AFK[ep:28]: too many enabled services!有沒有了,改成正常的 new service DCPDPService on channel 17/19
熱插拔後畫面回來❌❌ 還是不會
熱插拔時整台卡住卡數十秒不卡

也就是 #622 在 t600x 上確實有效,只是沒有把問題解完。 這是目前 #579 上沒有的資料點。

發現了什麼

  • 斷點 1 對這台機器不存在。換到 fairydust 就有 USB-C DP 輸出,不用改任何程式碼
  • DP 只有一個孔(左前),插錯孔完全沒有反應,而且不會有任何錯誤訊息
  • #622 在 t600x 上有效但沒解完:WARNING 和 flip_done timed out 都消失、 不再卡住整台電腦,但熱插拔的畫面仍然回不來。量化數字見上面「量到的東西」
  • 真正的卡點在合成器:一張永遠等不到完成的 page flip,讓 aquamarine 之後拒絕所有 commit (Cannot commit when a page-flip is awaiting,出現 14 次)。 Hyprland 不是沒反應 —— 它有偵測到、有列模式、有嘗試 modeset
  • 單獨跑 make install 會把 /boot/dtb 指歪,這次真的發生了。 只改模組的話根本不需要它
  • 驗證要驗二進位檔。git diff 和時間戳都可能騙人, 要 strings *.ko | grep 確認編出來的東西裡有

當時的狀態快照不留在這裡 —— 會變的東西只住在入口一份。 那晚實測的增量編譯是 38 秒。

沒做到 / 做得不好的地方

  • 整晚幾乎都是「跑腳本、套別人的 patch、看結論」,沒有寫過一行 C,也沒碰過任何暫存器。 這不是計畫的問題 —— 階段 0 本來就不是學習關卡 —— 但要記得它不算數
  • #622 兩塊改動的原理當下沒搞懂,是事後才補寫進流程 §3 的
  • git apply -R 那一輪白測,浪費約 20 分鐘

明天要幹嘛

  1. 先一起寫一份學習計畫(不是由 Claude 單方面寫完丟過來)
  2. 把兩個 patch 逐行看懂 —— 0001(內建 HDMI resume,11 行,暖身用)和 #622(兩塊,42 行)
  3. 討論熱插拔。重點不只是修好,是搞懂那些探測手段: udevadm monitor、/sys/class/drm、journalctl -k、hyprland.log 各自在講哪一層,輸出怎麼讀
  4. 然後才動 iomfb.c。程式由自己寫,Claude 負責解釋機制、指路、讀結果、review
兩分鐘就能做、但還沒做的事:把 Studio Display 插上去冷開機一次。 到目前為止正主都還沒上場,很可能會看到 acking unhandled call 20 —— 那是跟今天完全不同的一條線(斷點 2),先知道它長什麼樣,排優先順序會比較有依據。