Building XNU for macOS 11.2 (Intel and Apple Silicon)
kernelshaman.blogspot.com
kernelshaman.blogspot.com
From Marcan (who is porting Linux to the M1)
> Wait no, hold on, WTF. They do supoprt M1. Just not in source code. They freaking bundled some .a files with uncensored binaries of the parts of xnu that need to support M1.
More details here:
https://twitter.com/marcan42/status/1355907973776723971
While the binaries aren't quite as nice as source, its a good basis for reverse engineering some of the M1 specific code needed.
It is quite evident at this stage that this is somehow related to ARM. They must not like Apple adding nonstandard extensions to the ISA, and they want them to hide them all.
The good news is we don't have to care, and the (accidentally or not) "APSL" blob release gives everyone license to reverse engineer them, since it's not under an EULA.
Regardless, you can't put the cat back in the bag.
They can use it to see how it was done and create an alternate implementation without using any of the original code/ binaries. Worse case, they can build a model of what is done and describe that to a third party who has never had access to the code in question. Essentially forming an information firewall.
The amount of stuff released was shrinking by the release so did they cancel the 1.0 and 1.1 license or do they just pretend it didn’t happen? This is a 4.4BSD so there was the shadow of the AT&T vs CSRG/BSDi
I’ve received no CDL...
Still to be done:
- GPU drivers
- Wifi/ network drivers
- Power management
- Getting the GUI online
- Audio
- Bluetooth
- Webcam
Extra credit: - Fingerprint scanner (This may never be possible due to Secure Enclave)
- Neural Engine support
- ??? other M1 extensionsOur kernel has simplefb support too, literally all you need to do is write 5 lines of devicetree properties to get that to work - zero patches needed to the upstream simplefb driver. Here is the code in our bootloader that takes the Apple framebuffer information and stuffs it in the DT for Linux to use it:
https://github.com/AsahiLinux/m1n1/blob/main/src/kboot.c#L59
That's literally all you need to get "graphics".
I was actually planning on doing exactly the demo that they did since December, with a simplefb "full Ubuntu desktop" and everything else running off of USB, for the clickbait, because it's flashy even though it's a minimal amount of work, but with a clear disclaimer that it's a tech demo and there is a lot of work left to do. It certainly brings in the news. However, it is not a "fully usable Linux desktop".
FWIW: WiFi is Broadcom FullMAC (existing Linux driver) with some patches. Ethernet is a Broadcom chip over PCIe (once you have PCIe up, the driver is there). USB is DWC3 (existing Linux driver) with just an Apple PHY adaptation layer. Storage is NVMe with Apple hacks and a horrible (definitely not upstreamable) hack Corellium wrote to fake a PCIe bus because the Linux NVMe driver assumes PCIe. Please don't assume they are cranking out bespoke drivers every other day; most of their work is simple drivers and patches to existing ones. There is certainly work involved in figuring out all these Apple oddities, but these aren't new drivers.
I fully intend to support the SEP in our kernel once we get that far, with Touch ID for Linux log-in/unlock and also things like storing and using SSH keys within the SEP (think built-in YubiKey). Lots of reversing to be done, but all of this is in scope for our project. Drop by our IRC if you'd like to help out :)
The GPU is probably going to be the monster here, unless you have found that it bears similarly to something else?
And Bluetooth. Bluetooth is always a joke.
Alyssa already got her first triangle rendered the other day (from macOS, but without using any macOS Metal frameworks):
https://rosenzweig.io/blog/asahi-gpu-part-2.html
Kernel work is blocked on the lower levels of the kernel being solid first, but I'll be jumping on that as soon as I can.
Bluetooth is just Broadcom again. I think it's the usual UART HCI stuff? I saw a Corellium patch fly by to their UART driver related to that I think, adding hardware flow control support? That driver is a waste of time; I don't know why but Corellium are writing bespoke drivers for some (simple) hardware that already has near-compatible Linux drivers (PASemi I2C is another one). I already added M1 support to the Samsung UART driver in Linux in ~200 lines of patch, and that has more features that Corellium's bespoke >600 line driver. It seems in general they're happy to waste time on code and approaches that will never make it to upstream Linux without a complete rewrite/rethink... which speaks about their approach to this.
A separate I2C driver was done because the PA Semi one is polled, not interrupt-driven.
Polling to wait on a slow bus such as I2C is brutal. And we don't know if the original PA Semi hardware even supports being interrupt-driven (in the same way?).
As such the drivers don't even have much in common here.
That's what they aren't doing. Talking to anyone.
I'm pretty sure the graphics support is frame buffer only at this point though.
We are also documenting the hardware here: https://github.com/AsahiLinux/docs/wiki
I don't know what Corellium's goal is, since it isn't clear what they get out of this as a company other than PR, nor have they interacted with the open source community in any way whatsoever to date (I publicly invited them to our IRC channels and they've yet to show up), nor attempted to upstream any of their work (a third party has and that didn't go so well for the first version). They seem to be going for the tech demos and PR angle, judging by their actions and codebase so far :)
E.g I spent most of Saturday debugging the source of L2 memory subsystem bus error exceptions in our bootloader, m1n1. Corellium's codebase and preloader just turns off reporting those errors entirely, all the way into Linux. There are very, very different approaches going on here.
FWIW, Corellium had been developing their kernel in secret for A14 devices (that's the extremely similar iPhone version of the M1) for months now, plus had previous versions for older Apple SoCs, so it's not like they did this in two weeks; rather that they are currently piecewise releasing and adapting code they've had for a while and developed on jailbroken devices, while we/Asahi Linux started from scratch mid-January when Apple finally published the tools to run your own kernels on M1 Macs.
I'm happy to pull any drivers they develop and release that are clean and upstreamable, but we're working step by step and I'm not in a race with them; we're in this for the long run and I want to make sure anything we work on is the right way of doing things.
We're also working on GPU acceleration, which is a hard requirement for a usable desktop, and which as far as I know Corellium have nothing on. Alyssa is working on the userspace side already; I'll jump on the kernel side as soon as the necessary kernel dependencies are in.
I'm currently writing a quick start guide to help other kernel devs with interest get started with development, and in the coming weeks I will be taking some time to develop an open hardware design for a serial debug cable for these machines, and building some prototypes to send to other kernel devs to help bootstrap community members who want to help. Today I'm also working on using one M1 machine as a serial terminal for another, with a standard type C cable (it should be possible AIUI, but I need to reverse engineer some details to get the right commands sent to the Type C controller) - not the cheapest solution but certainly the lowest effort one right now, if you have the money for two M1 boxes.
Like a 1/3 speed M1 simulator that runs on a 28 core x86 Mac Pro.
In all the ways of bringing up software/OS's on a platform, there's always someone in the core team who goes for the "write a simulator, and use that to bootstrap the software for the hardware" path.
I guess I care less about a microkernel's advantages for kernel development, than it having non-broken IPC :P
XNU has two sets of syscalls – Mach syscalls (negative syscall numbers) and BSD syscalls (positive syscall numbers). The Mach ones expose the classic Mach "microkernely" API, and the BSD ones provide the traditional POSIX API
The term "syscall" is a bit ambiguous – sometimes it is said that the BSD side has syscalls but the Mach side has traps, other times it is said that BSD syscalls and Mach traps are the two different types of XNU syscalls.
Definitely the BSD syscalls include a bunch invented by Apple themselves (not inherited from *BSD), and I think the same is the case for the Mach traps as well
It was a massive chore to get Darwin 0.1 to build for x86 but it’s possible. And there is 2 things only available as a binary blob, the intel PCMCIA code was never released nor the EISA/PCI adaption layer.
I have some qemu images here:
In those days there was a bit more optimism about such things but it was sort of like "why not just use Linux"? I think, iirc from reading tech news back then, there were also complaints about the quality and quantity of what Apple was releasing in source form.
| Xmxinx means XNU is not Xinu
| Xmxinx means Xinu is not XNU