Every rustc version is bootstrapped using the previous version. For example rustc 1.44.0 is bootstrapped using rustc 1.43.0. This is the same way that C/C++ compilers are bootstrapped using previous versions of themselves.
"written in OCaml" may not means what you think. Say for Java, the javac, Java compiler, is written in Java. But the JVM is mostly written in C. What does the Java is written in?
Rust uses LLVM for code optimization, so there's some C/C++ involved. However, Rust uses LLVM only because it's a very useful back-end, not because it needs C. The Rust-specific parts are not written in C, and never were.
There are also other ways to run Rust like miri and cranelift back-end, so theoretically you can run Rust using 100% Rust compiler with a Rust back-end.
However, if you'd like to read sources of a Rust compiler written in C, there is an alternative Rust implementation written in C++:
The language that a compiler is written in had no impact on whether the code it compiles can communicate directly with the kernel, the hardware, or anything else. Compiled native code is just a series of instructions and data that the hardware executes. The compiler just transforms your code into that form. You could write a compiler in bash if you put your mind to it.
This is true for rustc specifically, but note that in general this does not hold: if I write a compiler for a new language in Java, there's no efficient way to communicate with the kernel, because JNI is not particularly efficient. So while it would technically still be possible, you would have a serious incentive to not do that, neither in the compiler nor in the language itself.
The language that a compiler is written in is not, in general, the same as the language output by the compiler. The efficiency of JNI only matters if the compiler is producing JVM bytecode, but it’s entirely possible to write a compiler in Java that translates Rust (or Python, or anything else) into x86-64 assembly.
FWIW rust code doesn't generally communicate with the kernel directly. Just like C code, it goes through the C library (which can be glibc, or something else like musl). Its mechanism for calling C functions is just as direct and efficient as that of C itself (no JNI or other abstraction) so this is not a problem for performance.