blog/_posts/2021-11-30-arm-x86-compatibility.md

94 lines
5.2 KiB
Markdown

---
layout: post
title: "Moving Away From The x86"
tags: tech x86 arm kernel bsd
---
The world seems to be slowly distancing itself from The x86 in favor of less insane architectures
like ARM and, in some cases, even RISC-V.
Naturally, as someone who has experienced what systems programming on The x86 is like themself
lately, i welcome this shift with open arms (believe me, you really *do not* want to bootstrap an
Intel processor).
However, this does not mean we aren't going to run into major issues.
TL;DR: It would be super cool to have an ARM daughter board that pops into one of your x86 tower's
PCIe slots, and use kernel magic to connect the two for native binary compatibility with multiple
architectures.
## How We Are Currently Handling It
A lot of software is just straight up not available on those platforms at the moment, and some of
it never will be, especially the proprietary pieces.
Major software companies typically respond to this by pushing application development towards
interpreted languages like, in the case of Microsoft, C#.
Or they are Apple who, very much in line their tradition, went full bonkers and made
[Rosetta 2](https://en.wikipedia.org/wiki/Rosetta_%28software%29),
an x86 to ARM recompiler.
Now, the Open Source community isn't nearly affected as much by all of this.
Most software that is written in languages that produce native binaries can just be compiled for
whatever architecture you desire.
And by the nature of being open source, those that can't can at least be adopted by the community.
Not to mention that popular open source kernels, most notably Linux, have been ported to just
about anything with a processor.
## Lame!
The two corporate solutions have problems.
Both come with a performance penalty because of the recompilation overhead
(JIT in the case of C#, AOT for Rosetta).
Also, i don't find them particularly cool or exciting.
You know what would be super cool and exciting, though?
Throwing hardware at the problem!
Design a daughter board with an ARM processor that you can stick into one of your existing x86
tower's PCI Express slots and boom, you're done!
This is also what Apple did way back in 1995 with the
[Power Macintosh 6100/66](https://www.youtube.com/watch?v=9UclHrIIaYA)
by the way, so we know that at least in theory it could work as a viable product.
Now, of course it isn't quite *that* easy, because you will also need at the very least a kernel
that plays along with it.
## Introducing GayBSD
If you follow me in the [Fediverse](https://notbird.site/@fef) or on
[Bird Site](https://twitter.com/libfef),
you might have already gotten wind of that thing currently working on called GayBSD
(actually, besides rants about The x86, it's almost exclusively what i post about these days).
It is basically a microkernel that, except for its libc and probably its network stack once that
becomes a thing, is written completely from scratch.
As the BSD in its name suggests, it is supposed to be a BSD adjacent kernel, and i am in fact aiming
for ABI compatibility to FreeBSD in the end.
I was already playing with the thought of making it not only a microkernel but also a distributed
one, and this seems like the ideal use case: native binary compatibility on multiple architectures!
The project is still *extremely* young; as a matter of fact, i haven't even reached user space yet.
So, i have decided to take the opportunity and leave the core design open to such an extension.
It shouldn't even be *that* much extra work, since the nature of being a microkernel requires some
form of abstract IPC protocol anyway.
But how would this be implemented in practice?
My thought is to handle it kind of similar to the way FreeBSD does ABI compatibility to Linux and
other kernels.
You have a `/compat` directory that essentially contains system roots for the respective native
kernel and architecture (e.g. `/compat/x86-freebsd` for x86 FreeBSD binaries), and when you
`execve` something the kernel automatically `chroot`s into the respective directory first.
The directories inside the sysroot that are supposed to be identical on all architectures (like,
pretty much anything besides program binaries) can just be bindings to the actual system root.
This leaves us with only one problem: shared memory.
If an ARM program wants to do IPC with an x86 daemon by writing data to shared memory, there might
be a mismatch between the data structure on x86 and ARM.
I don't expect this to be a major problem in most cases, because C's fundamental data types are
(as far as i know) the same length on both platforms, but there might still be architecture specific
quirks in individual programs.
You probably have to try before you can tell for sure.
Another, rather obscure situation would be if the daemon was a JIT compiler, in which case the only
solution would of course be spawning an entirely new daemon for that specific architecture.
## Conclusion
In case you haven't noticed, this idea hasn't exactly gotten a lot of time to mature.
Yet.
But i find it a quite interesting concept and hope you do, too.
If this post got you excited, you are welcome to contribute to GayBSD!
The source is available at <https://git.bsd.gay/os/kern.git>.
Just contact me through one of the means in the footer below if you would like to know more.