I work on firmware and kernel-level code, in pure Rust, at my job. We don't do malloc at all.
One of the key features Rust enables is that you can build safe abstractions on top of unsafe things. Another key feature is that those abstractions often mean compile-time, but not run-time, cost.
If you build the right abstractions, you can minimize the amount of unsafe code pretty dramatically. I don't have numbers handy for our codebase (and it's not open source yet, but will be eventually), but as an example, the Redox documentation (a Rust-based kernel that is, uh... linked... below) says: https://doc.redox-os.org/book/ch01-07-why-rust.html#unsafes
> A quick grep gives us some stats: the kernel has about 300 invocations of unsafe in about 16,000 lines of code overall. Every one of these is carefully audited to ensure correctness.
The advantage here is that, if and when there are bugs in this code, you only have to look at the modules containing those unsafe invocations, rather than the entire codebase.
There are also other advantages to the Rust language that make it worthwhile too, regardless of safety percentage, but it is true that this is often people's first concerns. The code that landed in linux-next has a lot of unsafe in it, because it is specifically trying to build out the proper abstractions here. The idea is that drivers built on top of this code will not need nearly as much, generally.