The reason drivers and firmware are mostly written in C or ASM is independent of the actual runtime libraries. If you could imagine this imaginary driver written in C here
#include <stdio.h>
#define OS_VER 5.10
#define DRIVER_VER "1.2.3"
int drivermain (driverstructinfo ** dsi) {
if ((* dsi) -> version> OS_VER) {
(* dsi) -> InitDriver ();
printf ("FooBar Driver Loaded \ n");
printf ("Version:% s", DRIVER_VER);
(* dsi) -> Dispatch = fooDispatch;
} else {
(* dsi) -> Exit (0);
}
}
void fooDispatch (driverstructinfo * dsi) {
printf ("Dispatched% d \ n", dsi-> GetDispatchId ());
}
Please note that during compilation / link, it will be necessary to insert and link the runtime library support, it will not work, since the runtime (that is, when the operating system is at the boot / initialization stage) is not fully installed and therefore will not there’s no clue about how printf , and it will probably sound the death ring of the operating system (kernel panic for Linux, blue screen for Windows), since there is no link to how to execute the function.
To deliver in another way, with the driver, this driver code has the right to execute the code together with the kernel code that will use the same space, ring0 is the ultimate privilege of code execution (all instructions are allowed), ring3 is where the front part of the operating room the system works (limited execution privilege), in other words, the code ring3 cannot have a command reserved for ring0, the kernel will kill the code, catching it, as if to say: "Hey, you do not have the privilege to test the domain ring0.
Another reason it is written in assembler is mainly related to the size of the code and the source speed, it could be, say, a serial port driver, where the input / output is “critical” for a function with respect to time, latency, and buffering.
Most device drivers (in the case of Windows) will have a special compiler combination ( WinDDK ) that can use C code but is not related to the usual standard C runtime libraries.
There is one toolkit that can help you create a driver in Visual Studio, VisualDDK . By all means, creating a driver is not for the faint of heart, you will get activity caused by stress, looking at blue screens, kernel panic and wonder why, debugging drivers, and so on.
The debugging side is more complicated, the ring0 code is not easily accessible by the ring3 code, since the doors to it are closed, through the door of the kernel trap (due to the lack of a better word) and, if you politely ask, the door still remains closed when the kernel delegates the task to the handler living on ring0 executes it, any results are returned back to ring3 code, and the door is still closed. This is a similar concept of how userland code can execute privileged code on ring0.
In addition, this privileged code can easily spoil the kernel memory space and damage something, hence the kernel panic / bluescreens ...
Hope this helps.