There is already plenty of literature in this subject, I just thought I would throw in my vote.
Currently I am building a pair of kernel tools. As i have learned, debugging more complex kernel modules could be considered an art of it's own. A rather large and fuzzy section of my code is causing a hard lock of my entire test system. Unfortunately because this is a hard lock (entire kernel is in an corrupted and unrecoverable state) none of my debugging output makes it to the daemons responsible for displaying them before the entire system grinds to a screeching halt.
After some googling I came to the conclusion that I needed an external logging mechanism, a highly-recommended one being to use a null-modem serial cable and tell the test kernel to output all messages to the serial port as well. Long story short, after a trip to The Source, about 4 hours of troubleshooting and $30 later my dev machine was inexplicably still not outputting system logs.
Shortly before giving up for the day, I found several articles about a kernel module called "netconsole". This module basically works very low in the network card driver stack to spew kernel message out onto the network via UDP. After less than 30 minutes I had this tool working beautifully and identified the line of code causing the lockup.
There are several tutorials on how to use this so I wont get too into it, but essentially I only had to do three simple steps.