What you need for OS or embedded development is a language that doesn't get in your way. C doesn't get in your way. C is the first language that both stayed out of your way and also provided reasonable productivity features (over BCPL, B, and assembly).
It was only recently that people have figured out how to come close to a "safe" language that doesn't get in your way.
Here is a test case: grab an ARM Cortex-Mx processor. Boot, configure the I/O matrix, and set up, oh say, the counter/timer peripherals for PWM motor control and quadrature decode. If you can do that without a trip to an "unsafe" language, that is a worthy accomplishment for your safe language.
Another test case might be doing page swapping and page-table updates on a virtual memory subsystem on a multi-core CPU without a trip to an unsafe language.
I guess a more direct answer to your question is that when you get down to the hardware, you have to deal with weirdo bit fields, volatile hardware registers, strange read/write ordering requirements, interlocks, and even some totally non-interlockable volatile stuff. C can do it (although I admit it uses language features not everyone sees every day).