Single address space operating system?

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
wyattmich61
Posts: 2
Joined: Thu Jul 08, 2021 3:37 am

Single address space operating system?

Post by wyattmich61 »

Hello,
I've lurked on this forum for quite some time but today I've decided to post my first question(s). First: does anyone here have a design that does not utilize hardware memory protection but instead utilizes software/language based memory protection?

I've attached links to two research papers, a GitHub repo, and a powerpoint presentation that go into deeper detail of this concept. For further reading, I've also included a link to the GitHub repo for the WASM linux kernel project.

Nebulet's design appears to be the most practical of the three as it uses the WASM VM/Sandbox as opposed to the .NET CLR or the Java VM, which are of course limited in their usages outside of Microsoft's managed languages/Java. From my understanding web assembly can be outputted from almost any language so long as a backend is written for the libraries used by the host language.

It appears that by foregoing the context switching and memory protection entirely, you can implement a microkernel design that is potentially much faster than a monolithic one. The security is achieved by sandboxing each process inside of the VM. The main drawback of Singularity and JX appears to be the lack of compatibility with existing software. You can compile most anything to WASM (unreal engine was ported), while the same is not true for CLR and the JVM. You couldn't even port a unix shell to the JVM, it doesn't even support chdir().

Now to my other questions: Is there an inherent design flaw that I am missing? Something that would completely prevent this from being practical? Is it unreasonable to run in Ring 0 with only a VM between sensitive system data and malicious software? If it's safe for web hosts to instill this level of trusts in VM's, why not an OS?

I would also like to mention that I am by no means a software engineer or professional of any sort. I would say that this is too large of a project for one hobbyist to attempt but Nebulet was written as a GSOC project.

Thanks,
Mike

Link is to a research paper describing the design of Microsoft's Singularity project:
https://www.microsoft.com/en-us/researc ... 05-135.pdf

Link to the research paper describing the design of the JX Operating system:
https://citeseerx.ist.psu.edu/viewdoc/d ... 1&type=pdf

Link to the slideshow that gives a visual representation of the JX OS design:
https://www4.cs.fau.de/Projects/JX/publ ... slides.pdf

Link to the Nebulet GitHub repo:
https://github.com/nebulet/nebulet

Link to the Linux WASM GitHub repo:
https://github.com/wasmerio/kernel-wasm
moonchild
Member
Member
Posts: 73
Joined: Wed Apr 01, 2020 4:59 pm
Libera.chat IRC: moon-child

Re: Single address space operating system?

Post by moonchild »

The closest we've gotten to a good sasos in recent times is probably hydros. My OS has similar aspirations, and I am aware of at least a couple of other people who are also working on things; but all are nascent.
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Single address space operating system?

Post by iansjack »

I'd say that the closest to a good SASOS is IBM i (AKA OS/400) where the single address space extends to secondary storage. Although, to be fair, it doesn't really have an address space in the sense that we normally understand it.
thewrongchristian
Member
Member
Posts: 426
Joined: Tue Apr 03, 2018 2:44 am

Re: Single address space operating system?

Post by thewrongchristian »

wyattmich61 wrote: Link to the research paper describing the design of the JX Operating system:
https://citeseerx.ist.psu.edu/viewdoc/d ... 1&type=pdf

Link to the slideshow that gives a visual representation of the JX OS design:
https://www4.cs.fau.de/Projects/JX/publ ... slides.pdf
I had an interest in this as well, and bought "Inside the JavaOS operating system". A copy can be borrowed and read from the internet archive:

https://archive.org/details/insidejavaosoper00saul

I think JX was heavily inspired by JavaOS.

The problem with any OS that implements a VM for "user space" is that you're limited to applications that use that VM, which takes out a whole boat load of available applications.

JavaOS was ahead of its time, and probably too slow to be practical (predated good JIT), and its a bit niche considering you can achieve almost the same results by running a regular user space JVM on a regular OS instance. It can even be the only user process running.

So, all in all, I don't see any particular benefits to running the VM in kernel space, though perhaps there is a case for a user space VM with a microkernel to provide the hardware interface.

And I don't see a case for forgoing the memory protection afforded by the kernel/user privilege split. Sandboxes are all well and good, until they're broken. A broken sandbox is much less risky when the VM is a regular user space process.
moonchild
Member
Member
Posts: 73
Joined: Wed Apr 01, 2020 4:59 pm
Libera.chat IRC: moon-child

Re: Single address space operating system?

Post by moonchild »

iansjack wrote:I'd say that the closest to a good SASOS is IBM i (AKA OS/400) where the single address space extends to secondary storage. Although, to be fair, it doesn't really have an address space in the sense that we normally understand it.
Ah, yes, transparent persistence is also highly desirable! I have heard vague rumours about the ibm i, but because it is not publicly available have had no opportunity to check them out.
User avatar
eekee
Member
Member
Posts: 891
Joined: Mon May 22, 2017 5:56 am
Location: Kerbin
Discord: eekee
Contact:

Re: Single address space operating system?

Post by eekee »

wyattmich61 wrote:Hello,
I've lurked on this forum for quite some time but today I've decided to post my first question(s). First: does anyone here have a design that does not utilize hardware memory protection but instead utilizes software/language based memory protection?
Hello! I've thought about this at some length. There are certainly performance gains to be had, but you can lose more than you gain if you bounds-check all array accesses. If I understand right, functional programming techniques may help. In the 90s and prior, Forth was often run as a primitive OS with no hardware or software memory protection. I imagine this is why Forth programmers use a lot of functional programming techniques. (Disclaimer: I don't understand functional programming very well.)

Forth is a bit of a beast, especially as an OS. No memory protection, interactive, variables are normally accessed via pointers, and arrays are just memory regions. It freely lets you do pointer math interactively if you're crazy enough. I am, but I've learned to do it in stages, watching the stack carefully before issuing the final memory-accessing command. I wonder how people coped with multi-user Forth systems! The language is so flexible, they could have restricted fetch, store, move etc. or even overloaded them to bounds-check for particularly troublesome newbies, but I have no idea if they actually did.

Anyway, I'm interested in SASOS and transparent persistence, but I still have a lot to learn, even about Forth itself. (That's my chosen language, just in case it wasn't completely obvious.)

I wonder if Schol-R-Lea will chime in. I thought he wrote some interesting stuff the last time this subject came up.
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
wyattmich61
Posts: 2
Joined: Thu Jul 08, 2021 3:37 am

Re: Single address space operating system?

Post by wyattmich61 »

Thank you everyone for the replies! I wasn't sure what the response would be as sometimes newbie questions get a bit of flack but I think that's usually only when someone copy/pastes the tutorials then comes here and asks you how to code in C ](*,)
thewrongchristian wrote:The problem with any OS that implements a VM for "user space" is that you're limited to applications that use that VM, which limits a whole boat load of available applications.
That is what I have noticed as well, I'll explain further to show you that this shouldn't be a problem. Firstly, I've done further research and decided that even WASM wouldn't be viable as they can change it at any time, it wasn't designed for this purpose. I think the safest way to go about this would be to create a low-level instruction set that can be targeted/emitted by LLVM. Think of it as a virtual architecture; instead of x86, it's your VM's assembly language. This would allow you to port everything over without any weird hacks, everything that is usually binary is bitcode instead. This is different from the JVM/Microsoft's CLR as the software doesn't need to be tied to this VM or any specific programming language. You shouldn't have to modify the source any more than you would porting it to any other OS(e.g changing inline asm blocks). Part of my design philosophy is to make sure that the VM aspect is not noticeable to the user/developer.

Take for example the C standard library ABI. Instead of native binary, the .so/.dll file contains bitcode. When the VM is launched by the kernel, this bitcode library is brought into memory as well. The application we are running can then call on the functions contained in the bitcode just the same as it could if it were calling functions natively on the processor. So, if we call printf, it jumps over to the printf subroutine in the bitcode. As a (very) loose example, it would ask the VM to fire a (native) interrupt to the kernel, which would then verify that the VM requesting this has sufficient permissions and carry out the print to stdout by way of message passing to the VM containing our display driver. Every library would be implemented in this same way. You can then link the software you port with these libraries.

I found a really good blog that walks you through writing your own VM/bitcode:
https://blog.subnetzero.io/post/buildin ... m-part-01/

You should be able to target this bitcode by writing a backend to LLVM, which actually doesn't appear to be overly difficult after reading the docs on how to do so.

TL;DR: Anything that can be compiled by LLVM should be able to run in this VM.
thewrongchristian wrote:And I don't see a case for forgoing the memory protection afforded by the kernel/user privilege split. Sandboxes are all well and good, until they're broken. A broken sandbox is much less risky when the VM is a regular user space process.
This is very true, but nothing is truly safe. The meltdown and spectre exploits can break through the hardware protection. :shock:
thewrongchristian wrote:I think JX was heavily inspired by JavaOS.
I think so too. I didn't mention it because I couldn't find much documentation on it. I scoured the internet but couldn't find a free pdf of that book you linked. Thank you for that!
moonchild wrote:The closest we've gotten to a good sasos in recent times is probably hydros. My OS has similar aspirations, and I am aware of at least a couple of other people who are also working on things; but all are nascent.
That looks similar to singularity and jx. I don't want it to be tied to a specific language or runtime.
iansjack wrote:I'd say that the closest to a good SASOS is IBM i (AKA OS/400) where the single address space extends to secondary storage. Although, to be fair, it doesn't really have an address space in the sense that we normally understand it.
I hadn't seen that one in my research so far. I'll look into it. Thanks :D
eekee wrote:Forth is a bit of a beast, especially as an OS. No memory protection, interactive, variables are normally accessed via pointers, and arrays are just memory regions. It freely lets you do pointer math interactively if you're crazy enough. I am, but I've learned to do it in stages, watching the stack carefully before issuing the final memory-accessing command. I wonder how people coped with multi-user Forth systems! The language is so flexible, they could have restricted fetch, store, move etc. or even overloaded them to bounds-check for particularly troublesome newbies, but I have no idea if they actually did.
That sounds a little rough compared to what I am looking to do. I want each VM to give the running process a virtual address space, similar to what is done by the hardware in a traditional system. I hadn't thought of the performance implications of bounds checking. I figure if a traditional system is using ~400 cycles to implement a system call, we have a little wiggle room.
eekee wrote:Anyway, I'm interested in SASOS and transparent persistence, but I still have a lot to learn, even about Forth itself. (That's my chosen language, just in case it wasn't completely obvious.)
I have a lot to learn tool! I am going to be using Rust. I still have to finish reading the intel manuals, the design and implementation of FreeBSD, and a few others that aren't directly related to SAS computing but are interesting to me. I've been considering following the Minix book but in Rust just to give me some practice writing freestanding code in rust. Not sure if that would help you to learn Forth, I know nothing about it.
User avatar
bloodline
Member
Member
Posts: 264
Joined: Tue Sep 15, 2020 8:07 am
Location: London, UK

Re: Single address space operating system?

Post by bloodline »

Here is a thread I started on the same topic: viewtopic.php?f=15&t=37351

My operating system uses a single address space if you want to play with it, there is a link in my signature :)
CuriOS: A single address space GUI based operating system built upon a fairly pure Microkernel/Nanokernel. Download latest bootable x86 Disk Image: https://github.com/h5n1xp/CuriOS/blob/main/disk.img.zip
Discord:https://discord.gg/zn2vV2Su
User avatar
eekee
Member
Member
Posts: 891
Joined: Mon May 22, 2017 5:56 am
Location: Kerbin
Discord: eekee
Contact:

Re: Single address space operating system?

Post by eekee »

wyattmich61 wrote:
thewrongchristian wrote:The problem with any OS that implements a VM for "user space" is that you're limited to applications that use that VM, which limits a whole boat load of available applications.
That is what I have noticed as well, I'll explain further to show you that this shouldn't be a problem. Firstly, I've done further research and decided that even WASM wouldn't be viable as they can change it at any time, it wasn't designed for this purpose. I think the safest way to go about this would be to create a low-level instruction set that can be targeted/emitted by LLVM. Think of it as a virtual architecture; instead of x86, it's your VM's assembly language. This would allow you to port everything over without any weird hacks, everything that is usually binary is bitcode instead. This is different from the JVM/Microsoft's CLR as the software doesn't need to be tied to this VM or any specific programming language. You shouldn't have to modify the source any more than you would porting it to any other OS(e.g changing inline asm blocks). Part of my design philosophy is to make sure that the VM aspect is not noticeable to the user/developer.

Take for example the C standard library ABI. Instead of native binary, the .so/.dll file contains bitcode. When the VM is launched by the kernel, this bitcode library is brought into memory as well. The application we are running can then call on the functions contained in the bitcode just the same as it could if it were calling functions natively on the processor. So, if we call printf, it jumps over to the printf subroutine in the bitcode. As a (very) loose example, it would ask the VM to fire a (native) interrupt to the kernel, which would then verify that the VM requesting this has sufficient permissions and carry out the print to stdout by way of message passing to the VM containing our display driver. Every library would be implemented in this same way. You can then link the software you port with these libraries.

I found a really good blog that walks you through writing your own VM/bitcode:
https://blog.subnetzero.io/post/buildin ... m-part-01/

You should be able to target this bitcode by writing a backend to LLVM, which actually doesn't appear to be overly difficult after reading the docs on how to do so.

TL;DR: Anything that can be compiled by LLVM should be able to run in this VM.
This is very similar to the intended design of Inferno OS. However, multi-language compilers were in their infancy in those days, (the 90s,) and Inferno ended up with a compiler only for one language, Limbo. Someone's talking about writing a Forth to target its bytecode, but it's been talked about before. Huh... today I learned there was once a Java implementation for it, but it's long gone now. The bytecode is called Dis: Design; Specification. Note that although Dis facilitates multi-threading, the VM only has a single thread of execution regardless of the host's capabilities. Development has been teetering on the edge of limbo for a very long time. (Pun intentional. :p ) That's why I didn't mention it before, but now I know your goals are similar, I thought you might like to look at it. Oh... also note that Inferno relies on the Limbo language for memory safety. I forgot that for a minute.
wyattmich61 wrote:
eekee wrote:Forth is a bit of a beast, especially as an OS. No memory protection, interactive, variables are normally accessed via pointers, and arrays are just memory regions. It freely lets you do pointer math interactively if you're crazy enough. I am, but I've learned to do it in stages, watching the stack carefully before issuing the final memory-accessing command. I wonder how people coped with multi-user Forth systems! The language is so flexible, they could have restricted fetch, store, move etc. or even overloaded them to bounds-check for particularly troublesome newbies, but I have no idea if they actually did.
That sounds a little rough compared to what I am looking to do. I want each VM to give the running process a virtual address space, similar to what is done by the hardware in a traditional system. I hadn't thought of the performance implications of bounds checking. I figure if a traditional system is using ~400 cycles to implement a system call, we have a little wiggle room.
Ah, yes, you want a completely different class of system to me. As for bounds checking, you may be right. Many languages have implemented bounds checking even when computers were much slower.
wyattmich61 wrote:
eekee wrote:Anyway, I'm interested in SASOS and transparent persistence, but I still have a lot to learn, even about Forth itself. (That's my chosen language, just in case it wasn't completely obvious.)
I have a lot to learn tool! I am going to be using Rust. I still have to finish reading the intel manuals, the design and implementation of FreeBSD, and a few others that aren't directly related to SAS computing but are interesting to me. I've been considering following the Minix book but in Rust just to give me some practice writing freestanding code in rust. Not sure if that would help you to learn Forth, I know nothing about it.
Simply practicing is helping me the most. I should alternate practice with reading about good practice in Forth.

Have fun! :D
Kaph — a modular OS intended to be easy and fun to administer and code for.
"May wisdom, fun, and the greater good shine forth in all your work." — Leo Brodie
Post Reply