How Linux was ported to the Apple Silicon M1 Mac mini
Linux now works on the Mac mini with M1 processor — but Apple did not make it easy for the team to port the OS with its custom firmware and unique data paths. Here's how Corellium got it done.
In Thursday's post, Corellium says that they have been studying Apple's custom processors since the iPhone 6 released in 2014. The company used some exploits and the previous study to build a kernel port to the A10 processor in early 2020.
Apple released the Macs with M1 processor in November 2020. A follow-on OS update enabled users to install custom kernels. Following the addition of that ability, the Corellium team began working on a Linux port.
Corellium says that the M1 shares a lot of components with Apple's A-series processors. However, that only helps insomuch that Apple doesn't use the standards set forth by other ARM manufacturers.
The Corellium team broke down the exact challenges they faced when porting Linux.
The technical details
The Corellium team says Apple doesn't boot its CPUs using traditional means. First, the bootloader runs an executable called Mach object file format (Mach-O) wrapped in a signed wrapper format called IMG4. It gets even more complicated as more CPU cores are brought up, as they start at an address specified by a Memory-mapped I/O (MMIO) register then begin running the kernel.
Apple designed its own controller that was outside the usual ARM Generic Interrupt Controller (GIC) standards. The timer interrupts are routed to the Fast Interrupt Request (FIQ), which is not standard and reflects an older 32-bit ARM system. The team says that you have to provide a set of inter-processor interrupts (IPIs) to get multiple processors to communicate.
The Corellium team had experience dealing with FIQ support and were prepared for most of Apple's non-standard approaches. In the end, the team added a pre-loader that acts as a wrapper for Linux, which led to the OS booting on the M1 processor.
The team did not have an interface cable for the M1 Mac and had to find an alternate input route. Out of the three options — Bluetooth, the USB Host, or the xHCI USB host on PCIe — they chose the USB host and had to interact with a chip on I2C.
After they had a proper USB connection they could connect a keyboard, mouse, and flash drive. This opened up the possibility for running a normal desktop Linux distribution.