An immutable VM?
My two days old article An immutable operating system sparked lots of interest, closing in on 60 000 page views now. I had totally not expected that, especially considering the post was mostly a brain dump, that I didn't advertise anywhere. The Github repo has over 150 watchers, and the link there was tossed into the last paragraph, with no skimmability in mind. People aren't supposed to have an attention span on the internet, and I thought it was impossible that anyone would actually read (or even skim) a ivory tower architecture wall of text post with no graphs. This interest is a blessing and a curse. It is great to see that other people has similar ideas and thoughts, but I definitely feel a pressure to write some useful code, pronto.
The current status of the project is that I've fiddled a bit with EFI boot loading, and only recently realizing I was making my own boot loader. The goal of using EFI specifically was that apparently that allowed me to boot straight into plain C code, without the dull 16 bit then 32 bit then 64 bit then protected mode assembly sit-ups. At least that was my impression, after reading Booting to Rust. But when the
efi_main is called, you still have to perform what EFI calls
ExitBootServices (and the companion,
SetVirtualMemoryMap). The whole point of targetting EFI was to avoid meddling with irrelevant OS stuffs. Can you spot the failure?
After a tonne of helpful comments on Hacker News, I'm considering writing a VM first. The VM can be written to rely as little as possible on the OS services. For example, I can (JVM style) malloc up a GB of continous memory, and write my own memory allocation and GC on top of that. With the right amount of dicipline, it should be possible to write it so that the code is flexible enough to not depend on a Linux run-time.
The goal would be to get started on the interesting bits, such as no-synchronization heap defragmentation, noop process forking, and so on. The more I can scope it down, the better. The endgame is to provide enough interesting code for some benchmarks and perhaps a conference presentation, running on bare metal is not a requirement for this. Then, if the project at that point ends up looking useful and/or interesting, hopefully some contributors will appear, so that I don't have to learn/do the OS lowlevel stuff such as mapping up which part of memory that can be used for allocation, figuring out where in memory the OS should load, how to set up pages in the most efficient way, and so on.
Another interesting approach, also mentioned on HN, is to consider the whole project a minix module. Minix is apparently flexible enough (unsurprisingly, since it's all about modularity) so that I could add my own process type to the OS. That would allow for an interesting mix on immutable and traditional processes, yielding the best of both worlds. This thought isn't as intriguing to me as running on bare metal. But I will keep this in mind, so that the various garbage collectors and process mechanisms are flexible enough to be able to be ported to something like minix in the future.
On osdev, the super-awesome operating system development community, it was suggested to look into multiboot. Apparently, this gets you straight into x86_64 protected mode, and GRUB (and others) supports booting this way. I'll spend the evening looking into that. If it turns out to be easy, I might as well run on bare metal. If not, I'll start writing my own immutable-oriented allocator and GC, on top of a blob of Linux malloc-ed memory.
Questions or comments?