I've spent a decent chunk of time using Linux as a daily driver; and tinkering in Linux; but I've no official programming experience, and before this I'd never compiled a Linux kernel. I went into it with the expectation that it would be fun and that I wouldn't end up with a completely working system. There's good documentation on the Asahi Linux github, although I still stumbled a few times; and there is very friendly support on the Asahi Linux IRC channels.
Asahi Linux is a group of open-source folk porting Linux to the M1 Macs. There's also a commercial affair called Corellium who've done something similar and have instructions here - https://www.corellium.com/blog/linux-m1 - I didn't try their way; not for any particular reason except a vague loyalty to open source; but maybe it would have been the easier way. Whilst Corellium have tweeted their support for Asahi I don't know how friendly the relations between the two are.
My instructions are based on the equipment that I had to hand (in particular that I only had one M1 Mac that I could play with); I'm sure they're not the easiest way to do this. I've written it for the benefit of my own learning; and when the Asahi team get to the point of writing documentation for non-technical folk it gives them some idea of the level of step by step simplicity a non developer requires to do this!
What you need to do this the way I did:
- a Macbook Pro that you don't mind losing all your data from;
- an amd64 VM to compile the kernel, m1n1, and connect to the macbook pro from. You'll need to have let your VM software know that you want a physical USB port to be connected to the VM
- an arm64 VM to tweak the root file system with
- an USB drive
- a USBC (male) to USB3 (male) cable to make a serial connection from the VM to the MBP
- a USBC (male) to USB 3 (female) convertor, to connect to a USB hub
- a USB hub
- a USB keyboard
- a USB ethernet dongle
The first few steps were erasing my MBP and setting up the partitions on the hard disk.
As per here
As per here
but
- I had already created a admin login on an otherwise empty system, so when choosing to install OS on the 'Linux' directory it asked me to confirm the owner of that directory was me
The partitioning commands turned out exactly the same as directed even though it the instructions say they might change
Starting from a Debian 11 netinst base system from here
Install sudo then
sudo apt install git
sudo apt install gcc-aarch64-linux-gnu
sudo apt install device-tree-compiler
sudo apt install graphicsmagick-imagemagick-compat
sudo apt install build-essential
sudo apt install python3-venv python3-pip
sudo pip3 install pyserial construct serial.tool
and then
git clone --recursive https://github.com/AsahiLinux/m1n1.git
cd m1n1
make
...and then in the ./build directory a file called m1n1.macho will have appeared. This is what you use for the next stage.
Took less long than the initial apple indication. Went through the various setups
That's a very scary disclaimer you've got to agree to.
I got confused that I needed to set up a serial connection first and went a bit all over the place, before realising that the instructions there are for transferring m1n1 over the network. Following those instructions went perfectly. When you reboot your Mac, hold the power buttong and select the drive marked 'linux', and your computer will boot to a Asahi linux screen; where it is waiting for the next stage.
Back in your VM, you're now going to download and 'build' a linux kernel - this is the core of the linux operating system, that m1n1 is going to feed to your Mac to take you into the land of Linux.
Now, getting a kernel that works with the M1 is a continual process of development that the Asahi team are working on; and the likelihood is you're going to be trying a few different kernels as they add more functionality to each one. So you'll be repeating this process a few times; and learning about how git holds different versions of a file system and how to access them.
First download the dependecies you need to build a kernel
sudo apt-get build-dep linux
sudo apt install gcc-aarch64-linux-gnu # For reasons beyond my paygrade you need to do this agian
And then use git to get the kernel you need. Hunting around on the forums for who has the latest working kernel is part of the fun; but as of time of writing it was:
git clone https://github.com/mu-one/linux # this might take some time
git checkout 20211013 # this takes a particular version of where this kernel was at and readjusts all the files to that point
wget https://ab34.de/u/0001-compile-fixes.patch
patch -p1 -i 0001-compile-fixes.patch
wget https://rosenzweig.io/.config
And now we build the kernel
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- oldconfig # This asks you a lot of questions and I just took the default answer to them all
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j24 Image.gz dtbs # Adjust the number after j to the number of cores in your machine. This will take some time.
This generates two of the three things you're going to need to send to your Mac to get started - the kernel image (in the folder ../linux/arch/arm64/boot/Image.gz) and the device-tree (in the folder ./arch/arm64/boot/dts/apple/t8103-j274.dtb)
The third thing you're going to need is a root file system - this is the files that linux will first have access to when it's booted, including networking files and stalwarts like apt
. I tried and failed with a few options here - there are initrd debian install file systems that are small enough to send over the serial port in the next step, but I couldn't get them to work; so instead I ended up downloading one from debian to put on a USB stick
However, the tricky thing here is that this root file system needs a root password set, and the only way I could work out how to do that was to create a separate VM running on arm64. This requires a bit of proxmox kung-fu that is documented here
So in your arm64 VM:
wget https://rootfs.debian.net/bookworm-arm64-networking-20210914.tar.gzi
tar -zxvf bookworm-arm64-networking-20210914.tar.gz
echo 'root:[your password here]' | /usr/sbin/chroot ./tmpdir /usr/sbin/chpasswd
cd tmpdir
tar -czvf bookworm-arm64-networking-20210914-new.tar.gz .
Now format a USB stick and create an ext4 filesystem on it; and copy the filesystem to the usb stick.
sudo tar -xsvf bookworm-arm64-networking-20210914-andrew.tar.gz -C /mnt # Presuming you've mounted the USB stick partition at /mnt
Connect your USB hub to your Mac with the network cable, USB stick, and keyboard connected to the front USB port, and the serial cable from the VM machine connected to the back USB port. Reboot, as the Mac only picks up that these things are connected on reboot.
If you lsusb
on your VM you should see a device that looks like Generic m1n1 uartproxy 7a29455
- which is great, it means the VM can see the m1n1 bootloader on your Mac.
Now we're ready to go. While in the m1n1 directory run the following command. Adjust the root= part to whichever partition on your USB drive it was.:
M1N1DEVICE=/dev/ttyACM0 sudo ./proxyclient/tools/linux.py -b 'net.iframes=0 rw root=/dev/sda2 rootwait rootfstype=ext4' ../linux/arch/arm64/boot/Image.gz ../linux/arch/arm64/boot/dts/apple/t8103-j274.dtb
And if all is going well you should be looking at a login prompt on your Mac; with a USB keyboard that works; and when you login a live internet connection!
Work out which partition is the 'LR' partition and then sudo mkfs.ext4 /dev/nvme0n1p5
if that's the right partition.
Mount it and copy the file system across:
sudo mount /dev/nvme0n1p5 /mnt
cp -ax / /mnt
And then reboot from your VM again using the above instructions, but this time pointing it towards the SSD drive
M1N1DEVICE=/dev/ttyACM0 sudo ./proxyclient/tools/linux.py -b 'net.iframes=0 rw root=/dev/nvme0n1p5 rootwait rootfstype=ext4' ../linux/arch/arm64/boot/Image.gz ../linux/arch/arm64/boot/dts/apple/t8103-j274.dtb