Writing an OS in Rust, Second Edition
os.phil-opp.com
os.phil-opp.com
I am extremely excited by this work. One of the hardest parts of hacking on a hobby OS is the environment. My own project has been hampered for nearly a year because I switched to Windows and couldn’t get the tooling working. (A combination of my lack of Windows knowledge and a lack of desire to spend random Saturdays figuring out obscure toolchain issues.) And that’s with rustc already being a cross compiler.
This now means that, with Rust, getting going on any platform Rust supports is now trivial. It’s quite exciting.
My first instinct was to partition and whack on a Linux distribution. But I chose to just leave it alone. I don't want to enamour my Mrs with a bootloader again. Despite the simplicity, the typical UI for a bootloader intimidates non-techies.
So I tried writing some code on Windows, using PowerShell as a terminal. How hard could it be? I've done it before. Well, PowerShell is a big leap over CMD. But it just wasn't unix.
I remember one specific example. I wanted to pipe a list of URLs to a program. Easy enough in a unix shell. In power shell it's something like
Get-Contents <path> | <program>
That's a trivial example but when you're doing real work how burdensome does that base verbosity become?I know there's this Linux in Windows stuff and Cygwin but really, for real work, I'll just use a *nix.
My real work doesn't have much to do with running shell commands, rather using graphical tools and making use of REPLs for scripting.
My workflow happens to use shell. Trying to use the same workflow, or modified, creates too much friction on Windows. It felt sluggish.
For example, "Get-Content" is aliased to "cat", and "type", which is the old DOS equivalent of cat, and "gc". And of course you can add your own aliases. But you're right, it isn't the core-utils you're used to from UNIX, it's better. So much goddamned better. It aught to be, it was developed with 30+ years of hindsight.
[0]http://ilovepowershell.com/2011/11/03/list-of-top-powershell...
Besides, 99% of my tooling is cross platform anyway. The only thing materially different is PowerShell, and they’ve added bash aliases. The hardest part of transitioning has been using -Fo instead of -f, as -f is ambiguous. git, vim, rustc/cargo, and Firefox are all identical.
Oh, so the pain here: the pain happens because most instructions “cheat” and use elf binaries for the kernel. So your “cross compile to my kernel” is “compile for the host”, since the host and target are the same. Windows means you actually have to cross compile. The situation would be the exact same if Windows formats were the defaults, but most hobby OS devs seem to work on UNIX, so culturally it just isn’t there. So this isn’t a direct flaw of Windows itself, but more of a social issue.
Being a developer is not a synonym for UNIX-like experience.
Developing on Windows is similar to Xerox PARC workflows, made mainstream by MacOS, Atari, Amiga, Oberon, and naturally Windows.
For any developer using Java, .NET, Delphi, C++ (VC++ / C++ Builder), Windows is pretty good developer workstation.
Which isn't to say the Windows development environment is great, but it at best isn't any worse.
When I had to dig into the structure of Windows for a project, I came away with the opposite conclusion. The Windows core APIs are beautiful. They're entirely different from those in Unix, and come from a parallel tradition.
The Windows environment was frustrating, but that was mostly because I've got decades of Unix experience (read: reflexes for working around Unix frustrations). Fortunately I had lots of ex-Microsoft colleagues around me and they were able to quickly unblock me.
I don’t know anything about how it’s written, I’m not sure if this is a deliberate design choice or just legacy.
I had a question about the section "A Freestanding Rust Binary" specifically the the "start attribute" section. The author states:
"The ! return type means that the function is diverging, i.e. not allowed to ever return. This is required because the entry point is not called by any function, but invoked directly by the operating system or bootloader. So instead of returning, the entry point should e.g. invoke the exit system call of the operating system."
Is this explicitly "diverging" marking a Rust specific bit of housekeeping? For instance I wasn't aware of any parallel in the C runtime but maybe someone could shed some light on this?
! is mostly useful when composing with other things, as it unifies with any type. return, break, continue, all have the type !. There’s an example of this being useful in the guessing game chapter of the book, I’d link you but I’m on mobile.
So in this context, since you never really call this function directly, it’s return type isn’t super relevant.
I'm curious if you might have any recommendations for a "gentle" introduction to the Rust type system.
What languages do you code in normally? I could also give you a short summary.
void myexit(int c) __attribute__ ((noreturn));One problem to me is drivers, drivers, drivers. Linux has a bunch of 'em. Other operating systems, not so much.
I can't see how this can be seen as a real OS.
Redox (https://github.com/redox-os/redox) is a Rust OS project that's aiming to actually be a usable consumer OS.
First, people need to learn how to write OSes, even if that is all they do with it.
Second, the only way to prove there are better ways to go beyond UNIX is to write other OSes, since many in IT only believe when seeing and sometimes not even when it is shown running on front of them.
I remember Linux being able to use DOS drivers for NICs back in the day, or something similar.
As an example:
// This:
ptr::read(self.ptr.offset(idx as isize))
// Becomes this:
self.ptr.add(idx).read()
This will be in stable Rust on May 10.