News for hackers. Stuff that matters.
Re:Hobby x86 kernel written with Zig by simias on Monday January 06, 2020 @10:25AM (#21969767)
It's true that for bare metal programming Rust is quite far from 1.0. You can't even do inline assembly in stable rust...

Arbitrary sized integers do sound very convenient, although I guess the counterargument would be that they simply can't map to machine types so you'll have to have magic behind the scenes which may not make complete sense in low level languages. Still, C has bitfields in structs which are sort of the same thing so why not.

Pointer handling however I'm not sold on. I'd argue that the very cumbersome pointer handling in Rust is a feature, not a bug. It's explicitly discouraged, and for good reasons. Map your pointer into a clean and safe reference, slice or wrapper object ASAP and leave raw pointers to the messy details of C FFIs and ultra low-level code. If you end up having to mess with raw pointers everywhere in your codebase you're doing it wrong, as far as Rust is concerned.

I think this is reasonable even for kernel code. After all typically you wouldn't dereference register pointers directly in C code because of volatility issues and making it obvious that you're accessing hardware and not RAM (readl/writel or similar), so having a safe wrapper adds no overhead in my experience.

Re:Hobby x86 kernel written with Zig by jackhalford on Monday January 06, 2020 @10:57AM (#21970079)
Ok maybe I was user pointers wrong in Rust. And I must confess that I never really understood lifetimes either, however

* I don't think that low level code needs to be "messy", and

* I don't think that adding an abstraction on top solves anything complexity wise.

For memory paging I used to have a whole library in Rust that handled hierarchy of page tables with very abstract pagetable classes and interfaces [0]. Now I just have 80 lines of zig that handles everything [1]. I much prefer the latter.

> I think this is reasonable even for kernel code.

It's not, for some of the reasons that Linus doesn't want C++ code in the kernel [2]

[0] https://github.com/gz/rust-x86/blob/28d5839933973e0b639ef354...

[1] https://git.sr.ht/~jzck/kernel/tree/master/src/arch/x86/pagi...

[2] https://yarchive.net/comp/linux/c++.html

Re:Hobby x86 kernel written with Zig by CDSlice on Monday January 06, 2020 @12:10PM (#21970829)
The Rust code you wrote seems to be extremely heavy on boilerplate. A couple of macros could have drastically reduced the line count.

I don't think what Linus wrote in 2004 on C++ has much relevance for 2020 Rust, especially for a new kernel that doesn't have a ton of contributors. Most of his complaints seem to be on how C++ abstractions can make it hard to review unknown code and how 2004 C++ code bases often had extremely messy code. Rust IMO doesn't suffer from those problems near as much as 2004 C++ did.

Also, Google is using Rust for part of their new Fuchsia kernel so at least they think Rust has something good to offer kernel dev.

Re:Hobby x86 kernel written with Zig by roblabla on Monday January 06, 2020 @12:29PM (#21971007)
Small nitpick: Google isn't using Rust for the Fuchsia kernel. The kernel, Zircon, is written entirely in C and is based on Little Kernel. Google is using Rust for some userspace drivers (Fuchsia being a micro-kernel).
Re:Hobby x86 kernel written with Zig by loeg on Monday January 06, 2020 @05:57PM (#21974442)
> The kernel, Zircon, is written entirely in C

No, it's written in C++[1]. They're very different languages.

That said, Google seems to think C++ has something to offer to all kinds of development. It seems to work for them, but they are a heavily C++ shop. I wouldn't read too much out of their use of C++ anywhere; it'd be more surprising and interesting to see them use anything else.

[1]: https://fuchsia.googlesource.com/fuchsia/+/master/zircon/ker...

Re:Hobby x86 kernel written with Zig by roblabla on Monday January 06, 2020 @06:31PM (#21974766)
Oh that's interesting. Zircon is based on LK[0] which is in C, which is why I thought it was still written in C. I wonder how much is left of the original LK code then.

[0]: https://fuchsia.dev/fuchsia-src/concepts/kernel/zx_and_lk

Re:Hobby x86 kernel written with Zig by loeg on Tuesday January 07, 2020 @01:22AM (#21977458)
Interesting, I didn't know about LK. Thanks for sharing :-).
Re:Hobby x86 kernel written with Zig by nickpsecurity on Monday January 06, 2020 @02:07PM (#21972046)
You might find it helpful to look at Redox OS and Tock to see how they're handling kernel development in Rust. May or may not be easier than what you described.

https://www.redox-os.org/

https://www.tockos.org/

Re:Hobby x86 kernel written with Zig by pcwalton on Monday January 06, 2020 @11:26AM (#21970367)
The problem with C-style bitfield values/arbitrary-sized integers is that they don't have addresses, so you can't take references to them. This means that you need special cases everywhere, and it increases the complexity of the language a lot. In Rust, integers often have methods that take self by reference, which demands an actual address. For these reasons, in Rust I think it's better that arbitrarily-sized integers aren't first class. They're never really first class anyway.
Re:Hobby x86 kernel written with Zig by AndyKelley on Monday January 06, 2020 @12:58PM (#21971288)
In Zig they do; here is an example: https://clbin.com/HlJ0X

Output:

    Test [1/1] test "bit field access"...
    *align(:3:1) u3
    All 1 tests passed.
Zig's pointer type has optional metadata to describe alignment, sub-byte offset, and SIMD vector element index. This generally makes things just work, and you'll get a compile error if you expected an unadorned aligned pointer. If I were to swap:

    - fn deref(ptr: var) u3 {
    + fn deref(ptr: *u3) u3 {
Then I'd get:

    test.zig:13:23: error: expected type '*u3', found '*align(:3:1) u3'
        assert(deref(&data.b) == 2);
                          ^
Re:Hobby x86 kernel written with Zig by simias on Monday January 06, 2020 @03:34PM (#21972986)
How do you deal with atomicity though? A big deal in Rust is that you can only have one mutable reference to an object at any given time which prevents all sorts of aliasing issues, but here if you have two mutable fat pointers, one to and and one to b, and you attempt to write them without synchronization you're going to have a big problem, won't you?

This is the main risk with bitfields in C, it makes reads and writes that appear to be independent actually access the same memory cell behind the scenes. I'm not convinced by the idea of adding even more magic on top of it to be honest, it is true that packing and unpacking bitfields is annoying and requires some boilerplate but in the end that is how it the hardware does it anyway.

Re:Hobby x86 kernel written with Zig by AndyKelley on Monday January 06, 2020 @04:40PM (#21973670)
The builtin functions for atomic operations provided by the language do not allow unaligned pointers, so it would be a compile error.
Re:Hobby x86 kernel written with Zig by zozbot234 on Monday January 06, 2020 @10:59AM (#21970100)
I don't think bitfields are even that portable in C? You end up with a weird mix of bit-endianness and byte-endianness issues. The best approach AFAICT, if you need to model a binary format with arbitrary-sized integers, is to keep the binary structure opaque and have a function to "unpack" it to a record of machine-native types. Modern compilers can easily optimize the resulting code into shifts+bit operations, and it is a reasonably foolproof approach.