5 ms·
This is so cool. Particularly enjoyed: In Fomos, an app is really just a function. There is nothing else ! This is a huge claim. An executable for a Unix
by keyle 3y ago
This is so cool.
Particularly enjoyed:
In Fomos, an app is really just a function. There is nothing else ! This is a huge claim. An executable for a Unix or Windows OS is extremely complex compared to a freestanding function.
I can't even begin to imagine how cool a kernel would be written this way.
Correct me if I'm wrong, but I think this is how smalltalk/squeak works?
I hope the author continues with this project. File system, task manager, safe memory stacks, nice resource sharing, ...
... and of course, running DOOM as a minimum proof of concept requirement! /s.
- nnx 3y agoWhat’s the difference in practice compared to every other OS where app is just a “int main() { … }” function?
- mepian 3y agoMake two apps A and B with their respective main() functions. Add some function foo() to app A. Now try to call A's foo() from B's main(). How many hoops do you need to jump through in every other OS to do this?
- xcdzvyn 3y agoThe amount of (wonderfully) horrible doors this opens is awesome.
- duped 3y agoNone, because this exists outside the scope of an operating system. This is the domain of an executable/linkage format and language compiler.
- wyldfire 3y agoMaybe the complexity lies in that possessive qualifier "A's foo()" - if this foo() can manipulate the callee state in some other virtual memory domain then it might not be sufficient to link against it in B's application.
- Karellen 3y agoNot many hoops, why? /* Create function pointer of appropriate type, initialised. */ int(*foo)(int, int) = NULL; int main() { void * ha; if ((ha = dlopen("A", RTLD_LAZY|RTLD_NODELETE)) != NULL) { foo = dlsym(ha, "foo"); dlclose(ha); } /* if "foo" is non-NULL you can call it now. */ ...
- mepian 3y agoIf you control the development of both A and B apps, then not so many. But generally you are not expected to load symbols from another application, you are expected to either use various IPC mechanisms or load symbols from a shared library instead of touching another application at all.
- ben-schaaf 3y agoI'd suggest reading the linked readme, it does a great job explaining the differences. In other operating systems apps do dynamic linking & syscalls. Those don't exist in Fomos.
- jmull 3y agoIn a regular OS there would be a bunch of implicit things provided by the OS that the app can access, while in this OS those things are explicit in the context. But I don’t think that’s really that significant… you could, e.g., enumerate all the implicit things the OS provides, express them in a structure, and now you’ve got your explicit context. The “fomos” context is only as simple as it is because the OS provides a small number of simple things. Expand those to full OS capabilities and the context will get full OS complex. The odd thing about this “OS” is that a running app is just the start function called repeatedly in a loop. This makes one app call a single coherent slice of app execution. That’s kind of interesting, but makes this pretty limited. E.g., it looks like apps are entirely cooperative. It’s maybe more of a cooperative execution environment. Maybe it would be good for some embedded uses?
- lostmsu 3y agoSeems similar to Singularity https://en.wikipedia.org/wiki/Singularity_%28operating_system%29 https://en.wikipedia.org/wiki/Singularity_%28operating_syste...
- benj111 3y agoMy takeaway was that compared to a dynamically linked binary, you don't need to literally patch it to get the correct addresses. So you get the benefits of simplicity of a static binary and the size benefit of a dynamically linked binary. Well that's the way I understood it anyway.
- aleph_minus_one 3y ago> What’s the difference in practice compared to every other OS where app is just a “int main() { … }” function? Your premise is wrong: in, say, Windows or GNU/Linux an application is, say, a PE/COFF or ELF executable, both non-trivial file formats. The int main(...) function in C is just a very leaky abstraction of all this.
- optymizer 3y agoAs opposed to what? Code that can be directly loaded into memory with no headers? That's how .COM files worked. There is no such thing as "program is just a function" unless it's compiled with the OS, like on some microcontrollers. For programs residing on storage, the OS needs a way to load them into memory along with its resources which means it needs to read some kind of format, even if it's trivial.
- aleph_minus_one 3y agoBut you can separate the file format of the executable from the loading process, i.e. implement "doing what the OS loader does" on your own. This way, you can define your completely own executable format instead of being forced to use the one that your OS wants you to use, or even decide that it doesn't have to be a file format (e.g. stream the data from a network stream).
- DSMan195276 3y agoI think you're making a wrong assumption about how this OS works, its programs are still loaded from ELF executables, the parser is here: https://github.com/Ruddle/Fomos/blob/91cf732f173a01cdec3df438617c87b6dd8dcf8e/bootloader/kernel/src/app.rs#L70 https://github.com/Ruddle/Fomos/blob/91cf732f173a01cdec3df43... The "app is a function" distinction is simply about the `Context` struct passed it, otherwise it loads and runs executables as expected (load ELf memory segments in, jump to entrypoint) Edit: I guess I'd also add that on Linux or other OSs it's possible to construct and run process completely from memory with no on-disk executable file. JIT compilers do effectively this, the produce the executable code completely in memory and run it.
- mepian 3y ago>Correct me if I'm wrong, but I think this is how smalltalk/squeak works? In Smalltalk those would be classes' methods rather than freestanding functions, but yes: all objects within the image directly send messages to each other, i.e. invoke each other's methods. Lisp machine operating systems are somewhat closer, since initially they had no object system and used freestanding functions calling each other, though later they became generic functions specialized to their arguments' classes.
- leowbattle 3y agoReminds me of TempleOS, where all programs run in the same address space. Is this the same concept here?
- pclmulqdq 3y agoIronically, there are so many pointers at this point that OSes often now do use a single address space for every program (with escape hatches in case you need aliasing). Virtual memory and vtables are now more about access control than about managing the scarcity of pointers.
- pitust2 3y agoCan you provide any citations for this (extraordinary, if true) claim? My knowledge of operating systems (which is based on experience in designing toy ones, but also studying other operating systems) suggests this is not the case on at least windows, macOS and linux. Feel free to correct me if I am wrong however!
- lispm 3y agoFlavors was used on the Lisp Machine to implement much of the OS since around 1980: https://apps.dtic.mil/sti/tr/pdf/ADA095523.pdf https://apps.dtic.mil/sti/tr/pdf/ADA095523.pdf
- shrubble 3y agoOne thing that appears to me would be that you could still 'pipe' output from one command to another, BUT the data would not be copied from one part of the pipeline to another. I would imagine it could greatly speed up composable things like that...
- keyle 3y agoWell it would have to be for memory safety purposes, unless it would specifically be designed to allow siblings application to share the memo... Ugh that would lead to a very unsafe system and that would defeat the purpose of writing safer code in Rust!
- DougBTX 3y agoFWIW, it is possible to pipe data faster than memcpy: https://codegolf.stackexchange.com/a/236630 https://codegolf.stackexchange.com/a/236630
- im_down_w_otp 3y agoRun old school classic MacOS.
- Animats 3y agoOh, no, you're right. That's classic MacOS development. It calls you for each event, and you can't block. It sucked.
- im_down_w_otp 3y agoIt was fun sometimes to “recover” a crashed environment by going into the hardware interrupt console and forcing the program counter to the entry point address of the Finder and then hoping for the best with your corrupted machine state.
- progval 3y agoThis seems to match the definition of a unikernel. Here is another one in Rust: https://github.com/hermit-os/hermit-rs https://github.com/hermit-os/hermit-rs
- rewmie 3y ago> *In Fomos, an app is really just a function. There is nothing else ! This is a huge claim.* To me this just screams the curse of greenfield development, where the architects are yet to discover what led other OSes to require all things they missed.
- yencabulator 3y agoMy expectation: Either Fomos has no security boundaries, or the security boundary looks a lot like syscalls...