TLDR: This is a packed file format that can look to the OS as being executable (for Windows/Linux/OSX). The code is x86 and so offers native performance on those processors. On other platforms, an x86 emulator is built in so can't offer native execution speeds.
While neat, its not the "best of all worlds" due to the lack of native code on anything other than x86/x64. Also, claiming "bare metal" is supported is a stretch as you are limited to having no I/O of any form (as there is no platform code).
I'm just one woman. What Cosmopolitan does so far, it does really well. It was only as recently as a few days ago that I got mmap() and malloc() polyfilled on bare metal. It has serial uart i/o. It's going to have e1000/virtio sockets soon. You can help me will that future into existence. I need people who know o/s dev and can help me write code that does things like correctly set up pic controller.
Sorry, wasn't meant as a criticism, just as an explanation because people were assuming magic...
Taking on bare-metal is a significant job much greater than your original task and you may be better targeting something like buildroot instead, after all what is the Linux kernel but a hardware abstraction layer.
How hard could stdio/sockets on metal possibly be? So far bare metal has been a walk in the park. I love the fact that PML4T lets me do things like move memory without copying it. I want to be able to have that power without schlepping in the entire Linux world. I believe it should be possible for programs to be able to boot on metal as just programs which are tiny and auditable. Especially considering everything runs on hypervisors these days, which are in some respects the true operating system. Ring 0 is the new Ring 3. Who among you is willing to accept being pushed to the outer bounds of computing? If MINIX gets to run in Ring -3 then it should at least be easy for our programs to run in Ring0.
Working on one bare metal system is relatively easy as long as you're willing to dive into drivers. Getting 1001 I2C drivers or maybe writing a drivers for tens of different types of flash devices is a different matter.
Your project will quickly become overrun with drivers for literally tens of thousands of devices... then comes maintenance.
Look at the Linux source tree... Good drivers are not trivial either. Simple ones are of course.
Basically, its a time-sink and it doesn't become useful for claiming "portability" until you're approaching the scale of something like Linux.
You're confusing portability with requirements. I'm aware that a long tail exists. Linux is a big tent for that sort of thing. I think that's great. I also want the freedom to live outside that tent during the times when all I need are the other 85% of use cases, which as I've shown, can be easily achieved by just one person. I don't believe that just because I ship actually portable executables that are able to do e1000/virtio that every hardware manufacturer is going to be kicking down my door eager to get support for their silicon merged. Linux is already doing a great job at that and I think Cosmopolitan is complementary.
As someone who knows programming in higher level languages well but has no experience with low level, bare metal, how can I get started with this stuff you're working with?
> So far bare metal has been a walk in the park. I love the fact that PML4T lets me do things like move memory without copying it.
> I believe it should be possible for programs to be able to boot on metal as just programs which are tiny and auditable.
I would love to be able to learn more about this. Maybe even contribute to your project :) perhaps a good way to start would be to address some small tasks you might have laying around?!
That file runs a few hundred lines of old school assembly in order to bring us into the modern era. Towards the end of the file you'll notice it starts calling functions that are written in C which configure memory: https://github.com/jart/cosmopolitan/blob/master/libc/runtim...
After it configures memory, the ape.S file is able to call _start(). It also sets a bit in __hostos so that functions like write() know to use the serial port instead of issuing system calls: https://github.com/jart/cosmopolitan/blob/master/libc/calls/... That's the simplest possible example of a driver with spin locks which uses the x86 IN/OUT instructions.
If you want to take a dive off the deep end right now with Cosmopolitan on metal -- simulated -- then try the following build commands on your Linux terminal:
git clone https://github.com/jart/cosmopolitan
cd cosmopolitan
make -j8 o//examples/hello2.com
qemu-system-x86_64 -m 16 -nographic -fda o//examples/hello2.com
sed -i -e 's/USE_SYMBOL_HACK 0/USE_SYMBOL_HACK 1/' ape/ape.S
make -j8 o//examples/hello2.com o//tool/build/blinkenlights.com
o//tool/build/blinkenlights.com -rt o//examples/hello2.com
While neat, its not the "best of all worlds" due to the lack of native code on anything other than x86/x64. Also, claiming "bare metal" is supported is a stretch as you are limited to having no I/O of any form (as there is no platform code).