"CPU hay quên": Hành trình đưa Linux lên chip Apple M4
Một lập trình viên đã chia sẻ chi tiết quá trình khởi động nhân Linux trên Mac mini M4, vượt qua hàng loạt rào cản phần cứng như SPTM, thanh ghi bị khóa và lỗi WFI khiến CPU mất trạng thái. Thành quả là các bản Linux và m1n1 mới nhất nay đã có thể chạy đa nhân trên M4, M4 Pro, M4 Max và cả M5.

Linux trên chip Apple Silicon từ lâu đã là một dự án đầy tham vọng của cộng đồng mã nguồn mở, và nay hành trình ấy đã tiến thêm một bước dài với dòng chip M4. Một lập trình viên đã ghi lại chi tiết quá trình đưa nhân Linux lên chiếc Mac mini M4 của mình, từ những lần khởi động thất bại đầu tiên cho đến khi hệ thống chạy được vỏ dòng lệnh với đầy đủ các nhân CPU.
Bối cảnh: Chip M4 khó hơn tưởng tượng
Vào tháng 11 năm 2024, tác giả mua một chiếc Mac mini M4 với hy vọng nó sẽ tương tự các máy M1–M3 và sớm được Asahi Linux hỗ trợ. Tuy nhiên, M4 là thế hệ Apple Silicon đầu tiên bắt buộc phải có SPTM (Secure Page Table Monitor) — cơ chế tăng cường bảo mật cho nhân XNU của macOS.
Điều này khiến quá trình đưa Linux lên máy trở nên phức tạp hơn hẳn. Ở các thế hệ trước, việc phân tích phần cứng chủ yếu dựa trên nhật ký ghi lại qua hypervisor m1n1. Với SPTM, các thay đổi lớn về m1n1 là điều kiện bắt buộc để chạy được macOS bên trong hypervisor — vượt xa khả năng của một người mới như tác giả.
Sơ đồ SPTM trên chip Apple Silicon
Bất chấp khó khăn, tác giả vẫn bắt đầu các thử nghiệm đầu tiên: tắt chế độ bảo mật khởi động nghiêm ngặt, cài m1n1 làm đối tượng khởi động tùy chỉnh qua chế độ phục hồi của macOS, và kết nối cổng serial để đọc nhật ký hệ thống.
Những thanh ghi bị khóa
Ban đầu, m1n1 chỉ khởi động được ở chế độ BRINGUP rồi lập tức gặp lỗi khi cố khởi tạo GXF. Hóa ra tính năng GXF đã bị khóa trên các SoC M4 trở lên, nên giải pháp đúng là bỏ qua bước khởi tạo này trên những máy đó.
Một vấn đề tương tự xuất hiện với RVBAR (Reset Vector Base Address Register) — thanh ghi xác định điểm bắt đầu thực thi của mỗi nhân CPU khi được cấp nguồn. Việc ghi vào thanh ghi này cũng gây lỗi trên M4, nhưng cuối cùng thì nó đã chứa sẵn giá trị đúng, nên chỉ cần bỏ qua thao tác ghi.
Kỹ thuật "in dòng lệnh" để gỡ lỗi
Sau một thời gian dài bỏ bẵng chiếc Mac mini, tác giả tìm lại động lực tại hội nghị Chaos Communication Congress cuối năm 2025. Lần này, anh ghép một cây thiết bị (device tree) tối giản chỉ gồm các nhân CPU và bộ điều khiển ngắt AIC, rồi nạp nhân Linux với tham số earlycon.
Lần khởi động Linux đầu tiên trên M4
Không thấy bất kỳ kết quả nào sau dòng "Vectoring to next stage", tác giả quyết định dùng cách thô sơ nhất: in ký tự để dò lỗi. Anh lấy đoạn hợp ngữ debug_putc từ m1n1, chỉnh lại để in ra ký tự 'a', rồi chèn vào rất sớm trong mã khởi động của Linux. Kết quả: ký tự 'a' xuất hiện!
Bằng cách chia đôi mã nguồn (bisect) để tìm điểm lỗi, tác giả phát hiện vấn đề nằm ở phần khởi tạo MMU (Memory Management Unit). Nguyên nhân không phải do MMU hỏng, mà do cổng UART được truy cập qua bộ nhớ ánh xạ (memory-mapped I/O). Khi MMU được bật, mọi truy cập bộ nhớ đều chuyển sang địa chỉ ảo — và Linux không tạo ánh xạ 1:1 cho vùng MMIO như m1n1, nên việc ghi log bị mất.
Sau khi thêm ánh xạ 1:1 cho vùng MMIO vào bảng trang khởi tạo, quá trình gỡ lỗi tiến xa hơn hẳn trong tiến trình khởi động.
Tiếp tục dò lỗi, tác giả chạm tới lệnh ghi vào thanh ghi SYS_IMP_APL_VM_TMR_FIQ_ENA_EL2 — một thanh ghi liên quan đến ảo hóa. Sau khi bỏ lệnh ghi này, nhân Linux đã khởi động được tới vỏ dòng lệnh. Đáng mừng là trong các phiên bản iBoot mới, thanh ghi này đã được mở khóa nên không cần bỏ qua nữa.
Vấn đề WFI và các nhân phụ
Khi m1n1 chưa khởi động các nhân phụ do thiếu smp_start_offset, tác giả thử dùng giá trị của dòng M1–M3 và bật được các nhân này. Nhưng ngay sau đó là một lỗi bí ẩn khác liên quan đến lệnh WFI (Wait For Interrupt).
Khởi động đa nhân trên M4
Trên các chip Apple Silicon trước đây, tùy trạng thái của một "chicken bit" (bit cho phép nhà sản xuất vô hiệu hóa một tính năng hay tối ưu nào đó của CPU), lệnh WFI có thể khiến các thanh ghi x0–x31 bị xóa về 0. Nhân XNU lưu các thanh ghi này vào ngăn xếp trước khi WFI và khôi phục lại sau đó để né vấn đề.
Điều đáng nói là trên M4, chicken bit này hoặc đã bị khóa, hoặc đã bị loại bỏ hoàn toàn, và hành vi mặc định không còn tuân thủ đặc tả ARM64 — vốn quy định rằng nếu WFI có thể hoàn thành thì nó không được phép làm mất trạng thái kiến trúc.
Vào tháng 4 năm 2026, tác giả đã khởi động được Linux trên M4 với đầy đủ các nhân bằng cách thay mọi lệnh WFI và WFIT bằng NOP (lệnh không thao tác).
Giải pháp được đưa vào nhân Linux chính thức
Ban đầu, tác giả cân nhắc xử lý theo cơ chế errata (các lỗi phần cứng đã biết) thường thấy trong Linux. Tuy nhiên cách này bị loại bỏ vì rất khó phát hiện chính xác khi nào nên thay WFI bằng NOP. Cụ thể, một máy ảo chạy dưới hypervisor macOS cũng sẽ kích hoạt logic errata, trong khi WFI ở đây lại được hypervisor dùng để lập lịch hiệu quả cho các khách (guest).
Will Deacon đã đề xuất một hướng khác: bổ sung tham số khởi động cho phép tắt WFI idle trong nhân Linux, rồi để m1n1 tự thêm tham số phù hợp khi chạy trên máy thật có lỗi WFI.
Kết quả là:
- Cơ chế ngăn Linux gặp sự cố với lệnh WFI và WFIT đã được hợp nhất vào nhân Linux chính thức.
- Thay đổi tương ứng trong m1n1 cũng đã được hợp nhất.
- Các bản phát hành mới nhất của hai dự án này nay có thể khởi động đa nhân trên máy Mac dùng M4.
Đáng chú ý, cùng cách xử lý WFI này cũng được xác nhận hoạt động trên M4 Pro, M4 Max và M5.
Những bước tiếp theo
Công trình này đã giải quyết một trở ngại nền tảng khi chạy Linux trên M4 và các chip Apple Silicon đời sau, giúp hệ thống khởi động tới vỏ dòng lệnh với toàn bộ nhân CPU dùng được.
Việc đảo ngược kỹ thuật (reverse engineering) các thiết bị ngoại vi vẫn đang tiến triển chậm mà chắc. Công sức của Sven trong việc giúp hypervisor m1n1 khởi động và ghi vết macOS trên các máy này sẽ rất hữu ích để chinh phục những thành phần phức tạp hơn như camera tích hợp, bộ điều khiển màn hình và khởi tạo GPU.
Tác giả cho biết phần lớn công việc được gửi trực tiếp lên các dự án thượng nguồn để cộng đồng cùng hưởng lợi. Toàn bộ hành trình này là minh chứng sống động cho sức mạnh của cộng đồng mã nguồn mở — nơi một cá nhân kiên trì có thể mở khóa cả một nền tảng phần cứng mới cho hàng triệu người dùng Linux.

