This reference seems to have answers to your questions, titled: Linux Kernel Development Second Edition.
The kernel print function,
printk(), behaves almost identically to the C library
printf() function. Indeed, throughout this book we have not made use of any real differences. For most intentions, this is fine;
printk() is simply the name of the kernel's formatted print function. It does have some differences, however.
The Robustness of printk()
One property of
printk() quickly taken for granted is its robustness. The
printk() function is callable from just about anywhere in the kernel at any time. It can be called from interrupt or process context. It can be called while a lock is held. It can be called simultaneously on multiple processors, yet it does not require the caller to hold a lock.
It is a resilient function. This is important because the usefulness of
printk() rests on the fact that it is always there and always works.
The Nonrobustness of printk()
A chink in the armor of
printk()'s robustness does exist. It is unusable before a certain point in the kernel boot process, prior to console initialization. Indeed, if the console is not initialized, where is the output supposed to go?
This is normally not an issue, unless you are debugging issues very early in the boot process (for example, in
setup_arch(), which performs architecture-specific initialization). Such debugging is a challenge to begin with, and the absence of any sort of print method only compounds the problem.
There is some hope, but not a lot. Hardcore architecture hackers use the hardware that does work (say, a serial port) to communicate with the outside world. Trust me this is not fun for most people. Some supported architectures do implement a sane solution, however and others (i386 included) have patches available that also save the day.
The solution is a
printk() variant that can output to the console very early in the boot process:
early_printk(). The behavior is the same as
printk(), only the name and its capability to work earlier are changed. This is not a portable solution, however, because not all supported architectures have such a method implemented. It might become your best friend, though, if it does.
Unless you need to write to the console very early in the boot process, you can rely on
printk() to always work.