Hacker News new | past | comments | ask | show | jobs | submit login
Writing an OS in Rust, Second Edition (phil-opp.com)
160 points by aarestad on March 10, 2018 | hide | past | favorite | 40 comments



https://os.phil-opp.com/news/2018-03-09-pure-rust/ provides a lot more context here.

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.


Windows in general is not developer-friendly environment. While it provides great experience for usual user, it seriously lacks the inner beauty of any *nix system, which is itself a developer environment as a whole.


I’m a lifelong Mac/Unix user. It’s completely fine. I find that most people who say this just expect it to be a UNIX, and don’t take it on its own merits.

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.


thank you


> it seriously lacks the inner beauty of any *nix system

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.


What about the Windows API do you think is beautiful? Because the insane types (LPCTSTR & LPDWORD), inconsistent handling of strings and function suffixes (A vs W) is enough for me to think it is ugly. And that's just scratching the surface...


That is just scratching the surface. The system of kernel object handles is lovely.


In my experience anyone claiming this is just a UNIX developer so used to UNIX's problems that they not only don't even see them anymore, they think they're actually features.

Which isn't to say the Windows development environment is great, but it at best isn't any worse.


Windows has been developer friendly to anyone that embraces Xerox PARC vision what computers are supposed to look like.

Being a developer is not a synonym for UNIX-like experience.


I'm confused and intrigued by this comment. I complete agree that Unix is not at all axiomatic, but also think that Windows is a pain to develop for. clarify?


Windows is only a pain to develop for when approaching it with UNIX expectations.

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.


I found this. I use a Mac at work but I've got a laptop with Windows on it.

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.


Powershell makes liberal use of aliasing[0] for when you'rehacking at the commandline as opposed to writing a script (where the verbosity is actually a good idea). Also, it has tab complete for cmdlets, variables, and even switches.

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...


Point taken. I'll have a look at the list you've linked to and try again. Thank you for clearing up my ignorance :)


Tab complete is a thing. I haven’t found it to be as significant as I expected.


The meaning of real work is very subjective.

My real work doesn't have much to do with running shell commands, rather using graphical tools and making use of REPLs for scripting.


Of course. I'm not saying that people who don't use shell don't do real work.

My workflow happens to use shell. Trying to use the same workflow, or modified, creates too much friction on Windows. It felt sluggish.


Faire enough.


One has to wonder why a toolchain must be so complicated that someone has to spend entire weekends getting it to work. Why is development like this in 2018?


Well, the tools aren’t from 2018. gcc is quite old. In order to set it up, you need to compile it and ld for the targets you want to compile to, rather than a single binary that knows how to compile/link all targets, like rustc/lld.

I don’t know anything about how it’s written, I’m not sure if this is a deliberate design choice or just legacy.


Yeah I really wonder about the origin of these awful hardcoded target platforms is. Fun fact, however, is that BFD ld and gold can both be compiled supporting all platforms.


What a great book!

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?


It’s part of the Rust typesystem, yes. It’s not the end of the world in this case if you don’t use it, but it’s the correct thing to do.

! 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 see, so its "best practices", the code would still compile without that. Thanks.

I'm curious if you might have any recommendations for a "gentle" introduction to the Rust type system.


It’s not only about the type system, but the book is pretty gentle. It only lightly covers the more advanced stuff, and leaves a few things out, which are in the Nomicon.

What languages do you code in normally? I could also give you a short summary.


My languages are generally Python, Golang, Java. Cheers.


Cool :) so, the Java will give you a nice introduction to generics. Rust’s are a bit stronger, and generally don’t do type erasure. I think given your background, you should read the generics chapter of the book, and then maybe poke at error handling, with Option and Result. These will show you how rust differs from Go; they have almost identical error handling stories, but the generics plus enums mean they feel very different. From there, traits are kinda like Java interfaces, but on steroids, and Trait objects do type erasure like Java does. That’d give you a decent starting place, and you can branch out from there.


Thanks for the detailed response and suggested approach, I appreciate it. Working my way through the Nomicon looks like a nice goal. Cheers.


You’re welcome, and good luck! If you run into problems, please don’t hesitate to jump on IRC or the users forum, we love answering questions.


There's a GCC extension that also allows to mark C/C++ functions as `noreturn` (in C, it's a compiler-specific attribute, not a part of the language, unlike Rust):

    void myexit(int c) __attribute__ ((noreturn));


Actually, `noreturn` is a standard part of c[1]. Can just specify as _Noreturn, or include a header that aliases it directly to noreturn. Don't know about c++, but it probably has it as [[noreturn]]?

1: http://en.cppreference.com/w/c/language/_Noreturn


I've seen a series of these types of articles, and I'm not sure if they're trying to make the next linux or doing it for fun.

One problem to me is drivers, drivers, drivers. Linux has a bunch of 'em. Other operating systems, not so much.


This particular series is more of a toy OS for learning purposes (and through which they can teach things). At least, that's my impression of it.

Redox (https://github.com/redox-os/redox) is a Rust OS project that's aiming to actually be a usable consumer OS.


We don't need a Linux mono-culture.

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 think the point of this is to teach how to write embedded / bare-metal software.

I can't see how this can be seen as a real OS.


A compatibility layer for e.g. Linux drivers to run inside a new OS is not unthinkable.

I remember Linux being able to use DOS drivers for NICs back in the day, or something similar.


If you’re targeting xen, you don’t need so many.


Even targeting hardware, it's not as bad as people make it out to be, provided you scope platform support and features appropriately. For a lot of hardware you can get 80% of the utility with 20% of the code, and no new OS jumps out of the gate with version 1.0 supporting every device on the planet.


That was interesting. I found the headstands necessary to write to a raw address a bit taxing. In C you'd just use the `volatile` keyword. But being able to localize unsafe code is a big win.


Worth noting that, as of a week ago in nightly, there are new convenience methods on unsafe pointers to make using them a bit more ergonomic (though unsafe operations will still require the `unsafe` keyword, of course). Here's the document describing the new changes: https://github.com/Gankro/rfcs/blob/0048bf68c56dd25cd2afed77...

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.




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: