Even if your embedded development is targeting a hosted platform with libstd available, whether you link libc will depend on whether you use libc. Thanks to its stable syscall ABI, you don't have to link anything on Linux. But most other similarly situated operating systems require you to link something, whether it be USER32.DLL/KERNEL32.DLL on Windows, libSystem*.dylib on macOS, or yes, libc*.so on (most of?) the BSDs and other UNIX systems. And when libc is not required by the platform, but you do need some of its functionality (either out of convenience or cross-platform compatibility), you can statically link it (including MSVCRT on Windows).
Especially when the "Rust culture" suggests building safe abstractions on top of unsafe building blocks, which tends to keep the unsafe code pretty well-contained to a small section of the codebase. There's plenty of Rust frameworks for microcontroller programming (embassy, etc.) that don't involve much if any unsafe Rust at all.
Kernel is about 3% unsafe code last I checked, which was just a few months ago.
Had no issues using DMA or anything else.
https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html : "You can take five actions in unsafe Rust that you can’t in safe Rust .. it’s important to understand that unsafe doesn’t turn off the borrow checker or disable any other of Rust’s safety checks: if you use a reference in unsafe code, it will still be checked .. by requiring these five unsafe operations to be inside blocks annotated with unsafe you’ll know that any errors related to memory safety must be within an unsafe block. Keep unsafe blocks small; you’ll be thankful later when you investigate memory bugs."
There is some rust code out there that is more than 50% unsafe though.