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.
> 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...
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.
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?
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.
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.
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.
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.
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.
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):
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]]?
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.
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()
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.