But yeah, I think for some projects rust brings you a great type system, a gross syntax, and very little additional safety. But OTOH, on those projects writing rust will be not that different than writing C. Either language will still let you forget to sanitize a length value from an external struct that is put into a DMA engine. And either language will let you create a dangerous_u32 type that needs to be sanitized before your routines write it into a peripheral. But rust’s probably would be a little more ergonomic for the programmers, a little harder to use improperly, and involve pressing every punctuation mark on your keyboard.
Why exactly? Once you write an abstraction on top of the raw addresses for configuring the hardware (usually already provided by a library) you don't need to use unsafe at all. One of the first things you do in C is write macros for all the addresses you use, writing safe wrappers isn't that much more complex than that.
The safe interface you can then use without fearing memory corruption or having to audit that code for unsafety. Any safe code is pretty much only logic errors.
But it allows you to for example to dereference raw pointers (and by proxy, allows pointer math).
A lot of unsafe functions become available, like unguarded array access (ie, you can go out of bounds of an array) but you have to explicitly do that.
I would think some of it safety, like strong type checking. But, you're right in that this isn't the primary use case of Rust.