Live data from Hacker News

Making a RISC-V Operating System Using Rust

web.eecs.utk.edu

31–40 of 47 posts

Re: Making a RISC-V Operating System Using Rust

#31
post #14
post #8

I really really like the first sentence > RISC-V ("risk five") and the Rust programming language both start with an R, so naturally they fit together

When RISC-V inevitably renames itself CISC-V, then what language would naturally fit together? And don't say cobol.

Well it would be "less risk", maybe even "riskless" so I guess you'd need a new language named "restless"?

Re: Making a RISC-V Operating System Using Rust

#32
post #14
post #8

I really really like the first sentence > RISC-V ("risk five") and the Rust programming language both start with an R, so naturally they fit together

When RISC-V inevitably renames itself CISC-V, then what language would naturally fit together? And don't say cobol.

V

https://vlang.io/

You could vlog about it.

Re: Making a RISC-V Operating System Using Rust

#34

Rust is build around the expectation that allocations happen automatically and can never fail. I’m curious to see how they deal with this in a kernel...

The Rust standard library is. The Rust Core library (the far more minimal library that gets used when you mark a crate as #![no_std]) does not. That's how the other "OS in Rust" and "allocator in Rust" projects work.

Well, this OS in Rust project simply commits the same sins as the standard library by using a custom allocation routine that panics on allocation failure: https://os.phil-opp.com/heap-allocation/#allocations-in-rust

Saying that Rust the language doesn't require a non-failing allocator misses the point--the ergonomics of the language make dealing with allocation failure difficult; sufficiently difficult that none of the projects I've seen actually bother attempting it.

See https://cs.brown.edu/research/pubs/theses/ugrad/2015/light.a..., which explains idiomatic Rust instructs developers to return by value, relying on caller assignment to types like Box (which uses exchange_malloc under the hood), to handle heap allocation. Basically, the strategy for dynamic object management in Rust is predicated on hidden heap allocations.

So of course it's not necessary. But good luck writing an entire operating system otherwise. Even Redox OS doesn't bother trying to fight the language in this regard: https://gitlab.redox-os.org/redox-os/slab_allocator/blob/mas...

Re: Making a RISC-V Operating System Using Rust

#36
post #34

Earlier quoted context omitted.

The Rust standard library is. The Rust Core library (the far more minimal library that gets used when you mark a crate as #![no_std]) does not. That's how the other "OS in Rust" and "allocator in Rust" projects work.

Well, this OS in Rust project simply commits the same sins as the standard library by using a custom allocation routine that panics on allocation failure: https://os.phil-opp.com/heap-allocation/#allocations-in-rust Saying that Rust the language doesn't require a non-failing allocator misses the point--the ergonomics of the language make dealing with allocation failure difficult; sufficiently difficult that none of t…

> the ergonomics of the language make dealing with allocation failure difficult; sufficiently difficult that none of the projects I've seen actually bother attempting it.

Honest question: what languages make this ergonomic and can you share any projects that handle this gracefully?

Re: Making a RISC-V Operating System Using Rust

#37

Rust is build around the expectation that allocations happen automatically and can never fail. I’m curious to see how they deal with this in a kernel...

You deal with this in a Rust kernel in exactly the same way you deal with it in a C kernel: by using different APIs for allocation.

Linux doesn't use malloc; a Rust kernel need not use Box::new either.

Re: Making a RISC-V Operating System Using Rust

#38
post #22

Rust is build around the expectation that allocations happen automatically and can never fail. I’m curious to see how they deal with this in a kernel...

Try harder: https://doc.rust-lang.org/std/alloc/trait.GlobalAlloc.html#t... You can implement your own global allocator, use an existing crate, or (in the case of user applications) use the system's. That is for the stdlib level, not even core...

Nope, the GP is still correct. If your custom allocator fails, anything created with Box::new or similar will panic.

Re: Making a RISC-V Operating System Using Rust

#39
post #34

Earlier quoted context omitted.

Well, this OS in Rust project simply commits the same sins as the standard library by using a custom allocation routine that panics on allocation failure: https://os.phil-opp.com/heap-allocation/#allocations-in-rust Saying that Rust the language doesn't require a non-failing allocator misses the point--the ergonomics of the language make dealing with allocation failure difficult; sufficiently difficult that none of t…

> the ergonomics of the language make dealing with allocation failure difficult; sufficiently difficult that none of the projects I've seen actually bother attempting it. Honest question: what languages make this ergonomic and can you share any projects that handle this gracefully?

Off-hand I don't know of any that make this ergonomic, at least none that don't make use of exceptions. Rust isn't unique in this regard.

What makes it a potential impediment in Rust is that the constraints and burdens of the borrow checker are offset by mechanisms like Box. The fact that all the extant examples choose the convenience of Box over handling OOM, even in situations where not handling OOM is obviously a deal breaker for production systems, speaks volumes about the significance of the problem and how the language shapes people's choices. Async/await is in the same boat--technically doesn't require a non-failing heap allocation, but who's going to bother making it work? You technically don't need async/await to do asynchronous programming, either, but the whole point was that this is the type of thing that needs to be addressed by the core language with some primitive (i.e. generators) that does the heavy lifting and which can be built upon.

I don't know enough Rust to know how easy it would be to create a Box-like implementation that rewrites the AST to automatically propagate allocation failure via the idiomatic Result protocol. But that seems roughly what the proper solution might look like in Rust; either that or finally getting over the anxiety and aversion about exceptions.

Lua handles OOM quite well. Lua doesn't have try/catch, just "protected calls" which are not as light-weight as regular function calls. (A pcall initializes a recovery point with _setjmp.) In Lua you tend to use protected calls at, effectively, transactional boundaries--the points in your call graph where you're willing and able to rollback application state for non-specific, otherwise unrecoverable errors. AFAIU you could technically do the same in Rust, except Rust makes unwinding optional at compile-time[1], so it's not the kind of thing people will make a habit of deliberately designing for in their libraries. Which makes me think the likely solution for Rust, if any, is to permit libraries to opt-in to OOM recovery with an allocator pragma that does something like the Result propagation mentioned above.

[1] Lua is GC'd. The cost of running destructors outside the normal call/return protocol is fixed and independent of whether an application uses protected calls.

Re: Making a RISC-V Operating System Using Rust

#40

Amazing tutorial, and really exciting for RISC-V. I hope he creates a patreon or some other donation platform, as it must take some time to write this up. I'm sure some people would be willing to send a bit his way.

Done! Thanks for the suggestion. The Patreon link is at the top of the blog.
Post reply on HN