What would a rust based OS look like?

With all the drama going on in the linux for rust effort, it made me curious what an OS designed with rust in mind would look like. Rust doesn't have an official stable abi (stabby looks nice), but I assume this problem will be solved eventually.

What benefits might there be over the traditional c os? Obviously security/safety are a huge bonus, but are there features that rust would make practical/possible.

Do you see a path forward with the existing linux project?

Have you checked out https://redox-os.org/? There is also a great series of blog post explaining how to develop an OS in Rust by Philipp Oppermann (who is also a maintainer of the Rust OSDev project), which also can give you an idea on how an OS in Rust could look like: https://os.phil-opp.com/.

6 Likes

the kernel most affect the software developers, but that's usually abstracted away by libraries, such as libc on most unix/posix type systems. for end users, they don't use the "operating system", but rather individual software.

the most well known rust based os is redox:

2 Likes

Well… the way it would be solved would determine how OS would look like.

OS have to provide ABIs to the apps. In some way. And it's not linked to apps statically (that's the difference between OS and firmware).

Means as long as we don't have any Rust-specific stable ABI it's pointless to talk about how OS would look like: today's Rust would have to use C stable ABI as a substitute which means OS would look, essentially, undistinguishable from C OS. Of course there are many such OSes and they are not identical… but Rust wouldn't bring anything “unique Rust” to that area as long as it doesn't have widely acceptable stable ABI.

If, tomorrow, Rust would get some widely accepted stable ABI – that would determine how Rust OS may look like.

No. Rust only protects from accidents and not from intentional abuse. Which means, again, that OS couldn't depend on that – and, again, would be like C-based OS, for that very reason (C based OSes don't ever use C safety features, they use hardware-provided safety features).

1 Like

The design of the operating system is mostly not dependent on the programming language used.
Throwing in tock as another example: GitHub - tock/tock: A secure embedded operating system for microcontrollers

That's not really true, because there isn't such a thing as "C ABI" independent of a specific arch+OS combo. A new [Rust] OS could very well define a new ABI, not based on anything GCC can support today.

1 Like

Yes, but they all are based on C. If you look on the most common one System V ABI you would find out that it defines the way processes are handled and created, how memory is managed and so on.

Arch-specific ABIs add additional instructions that describe how to pass arguments and handle different kinds of data structures, etc.

And all other stuff is shoehorned, somehow, into that world.

One example: proper API for async – most contemporary OSes don't support it. Can Rust OS add it? Sure, it can… but only by going down to assembler level because Rust, in the absence of stable ABI couldn't support it.

Would Rust with a stable ABI be able to provide it? Who knows: this would rely, very much, on how said stable ABI would look like.

Tell that to the designers of Inferno or Singularity. They'll have a good laugh.

The only reason OSes are so similar today is because they all are built around C ABI.

Other possibilities exist, but as long as Rust wouldn't have it's own stable ABI any Rust would follow in the same beaten road.

Whether it's good or bad is an interesting, but separate, debate.

1 Like

...until it doesn't. Meet WASM, where rustc defined its own repr "C" ABI and then clang defines it otherwise. Now we're fixing both of them.

Do we even have an OS where WASM is used as system-level ABI? I know a guy who was trying to pull that off and very much have given up.

Sure, by adding pile of kludges it's possible to run Forth (two-stack architecture) on top of OS with a C ABI, or Scheme with call/cc (where there are no call stack, but instead a call tree… with tracing GC handling stack allocations, too) or any number of other weird architectures. Including WASM (which is pretty weird architecture in its own right an not every-well aligned with C or Rust).

But all our OSes are build around C ABI. On a very fundamental level: single stack, synchronous syscalls and so on. Just read again about PC loser-ing in the original “The Rise of Worse is Better” paper!

Can we create a different implementation of Rust that wouldn't be tied to these basics C ABI, as it's basis?

Well… maybe, but that's not even in the discussions, currently!

1 Like

I don't understand. As far as I can tell operating systems typically provide their services via sys calls which are implemented via software interrupts or sys call instructions etc. The OS specifies where parameters in such sys calls and how results are returned, which is all totally independent of how any language does things. Sys calls get made with assembler, after all even C has no syntax or semantics for generating software interrupts and such.

Also it's not clear to me how a stable ABI dictates what the OS looks like.

Indeed. But protecting against all those accidents prevents a lot of bugs and many of those bugs cause security issues. I would say yes, Rust would help with security. That is a big reason why many are developing use of Rust within the Linux kernel.

Every language was created keeping in mind a sort of applications it will be used for. C was created keeping OS in mind. Rust was created for a different purpose. Sure, OS can be written in Rust and even Python, but efforts to make it so, won't be valuable.However creation basic OS utilities, Rust fits very well.

I don't think comparing Rust and Python this way is appropriate.

Python is a dynamically type language that requires an interpreter to run it which typically requires an OS to run.

Rust compiles to real executable instructions. Just like C. You can put that binary in the memory of a machine and boot into it directly. Give or take a hand full of assembler instructions at reset. Just like C.

I see no reason an OS in Rust would not be would not valuable. Just like C.

I would be curious to see how you can write an OS in Rust without a single ‘unsafe’ section. But as only you started using it, it won't give you much advantages over C. However you code will become more cumbersome. Trust me.

Most OSes only specify the interface with libc in terms of the C ABI. They don't specify the syscall interface. Linux is the major exception and even Linux specifies things like ioctls and iovecs for readv/writev in terms of C structs.

1 Like

I beg to differ. If the OS interface were a C ABI we would not need libc in-between our applications and the OS.

I beg to differ again. The OS has a sys cal interface, that libc talks to. A prime directive of Linux is not to break "user space" That is to say it defines that sys call interface.

Indeed. Because C can describe such things. No reason Rust cannot interface to that.

Yes, but even that convention is tied to the structure of the languages that are supposed to be used with said OS. What you describe is syncronous was if calling the OS kernel. But asynchronous one can also exists. And there are more exotic ways, too (I gave the links).

But most importantly: most OSes describe it's ABI in terms of C ABI.

Not just the OS, but also an instruction set. Why do you think things like PCMPISTRI were added to SSE4.2? Why do you think modern CPUs have stack (except for Z/Architecture?).

It's a bit of two-way street, of course: C was designed to match PDP-11 and then modern OS and hardware was made to match C… OS can be easily changed, but some decisions would stay even with “native RUst OS”, because they are embedded in the hardware, at that stage.

Rust would help with security, indeed, but as long as API is expressed in terms of extern C it wouldn't make OS fundamentally different.

The question whether is should is a good one… and one I have no answer for.

This is strange request. It makes as much sense as request to write OS in C without a single asm block.

Rust have unsafe for a reason, in fact it's precisely because Rust have unsafe we may even talk about writing OS in Rust.

Most other “safe” languages couldn't run on bare metal. Rust can.

libc is not “in-between”. It's part of OS. And it's specifically that part that provides stable ABI on most OSes. Linux is rare exception and is only acts like that for a historical reason.

Take Windows e.g.: do syscalls exist there? Yes. Can you use them? No. They change numbering and list of arguments regularly and applications couldn't use them, for this reason. They are calling NTDLL.DLL and it's ABI is very much specified in terms of C ABI.

And dynamic loader is part of OS kernel and couldn't be changed (we had separate thread about that).

On the majority of OSes it's an implementation detail.

Yes. Linux is a weirdo. Very popular, but weirdo. And even Linux is shaped, to a large degree, by the C ABI.

It can, but as long as Rust doesn't have any other ABI to “interface with” it's pointless to ask how Rust may change OS space.

For all practical purposes, from the app development POV Rust is “extremely fancy version of C” for it have no way to express anything by C API to them.

On basically every Unix libc is a part of the OS and developed in lockstep with the kernel. Only Linux maintains libc implementations separately from the kernel, hence requires a stable syscall abi. For example OpenBSD is literally preventing you from invoking any syscall outside of libc and crashes your application when you try anyway.

1 Like

Ah OK. I was neglecting the difference between OS and kernel.

libc confuses me. On the one hand it is the interface to the kernel such that it can do file and other I/O and whatever. On the other hand it is the implementation of the C standard library. Or at least part of. These seem like different things to me.

I don't know why Rust or any other language needs libc. Where is the librust that basically does that kernel interface?

1 Like

Because that's the only supported way of accessing kernel facilities on most OSes.

Also: if you want to load shared libraries (and many want to have that ability) then you have to use libc even on Linux because there that's implemented in libc, not in kernel (like, e.g., on Windows).

Why would you need it and what would attempt to achieve with it?

Really? I wonder how Golang does without it.