1、简介(基于s3c2440 linux)
在内核调试技术之中,最简单的就是printk的使用了,它的用法和C语言应用程序中的printf使用类似,在应用程序中依靠的是stdio.h中的库,而在linux内核中没有这个库,所以在linux内核中,使用这个printk就要对内核的实现有一定的了解。
printf和printk的区别:printk会在开头处加上"<N>"样式的字符,N的范围是0~7,表示这个信息的级别。
当printk("<n>"......);中的n < console_loglevel 时候,这个信息才能被打印出来。
在内核文件中Printk.c (kernel) 中初始化这个console_loglevel 的级别为7.
/* printk's without a loglevel use this.. */ #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ /* We show everything that is MORE important than this.. */ #define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */ #define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */int console_printk[4] = { DEFAULT_CONSOLE_LOGLEVEL, /* console_loglevel */ DEFAULT_MESSAGE_LOGLEVEL, /* default_message_loglevel */ MINIMUM_CONSOLE_LOGLEVEL, /* minimum_console_loglevel */ DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ };
2、通过命令cat /proc/sys/kernel/printk查看等级配置:# cat /proc/sys/kernel/printk
7 4 1 7
其中的 7 4 1 7,分别对应与:console_loglevel、default_message_loglevel、minimum_console_loglevel、default_console_loglevel
3、修改等级配置:#echo "1 4 1 7">/proc/sys/kernel/printk 改变这四个值,当被console_loglevel设置为1的时候,所有的调试信息都会被打印出来。
4、printk函数记录的名称及使用在内核文件:Kernel.h (include\linux) 定义了0~7这8个级别的名称
#define KERN_EMERG "<0>" /* system is unusable */ #define KERN_ALERT "<1>" /* action must be taken immediately */ #define KERN_CRIT "<2>" /* critical conditions */ #define KERN_ERR "<3>" /* error conditions */ #define KERN_WARNING "<4>" /* warning conditions */ #define KERN_NOTICE "<5>" /* normal but significant condition*/ #define KERN_INFO "<6>" /* informational*/ #define KERN_DEBUG "<7>" /* debug-level messages */ #define console_loglevel (console_printk[0]) #define default_message_loglevel (console_printk[1]) #define minimum_console_loglevel (console_printk[2]) #define default_console_loglevel (console_printk[3])
使用printk:
① printk(KERN_WARNING"there is a warning here!\n");//注意,中间没有逗号间隔。
② printk(KERN_DEBUG"%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
在①和②中,我们需要查看缓冲区log_buf中的数据,才能看到打印出来的信息。需要使用命令 #dmesg
1 2 3 4 5 6 7 8 9 10 11 12
# # dmesg Linux version 2.6.22.6 (book@book-desktop) (gcc version 3.4.5) #19 Thu Dec 8 14:06:03 CST 2016 CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177 Machine: SMDK2440 Memory policy: ECC disabled, Data cache writeback On node 0 totalpages: 16384 DMA zone: 128 pages used for memmap DMA zone: 0 pages reserved DMA zone: 16256 pages, LIFO batch:3 Normal zone: 0 pages used for memmap CPU S3C2440A (id 0x32440001)<br>................................
还可以使用 cat /proc/kmsg& 后台运行,实时打印出调试信息。在②中,__FILE__, __FUNCTION__, __LINE__分别对应的是那个文件,那个函数,第几行。非常实用。
1 2 3 4 5 6 7 8 9
# cat /proc/kmsg& # ./firstdrvtest on <7>/work/LinuxDrives/20.printk_debug/first_drv.c first_drv_open 23 <7>/work/LinuxDrives/20.printk_debug/first_drv.c first_drv_open 25 <7>/work/LinuxDrives/20.printk_debug/first_drv.c first_drv_open 27 # ./firstdrvtest off <7>/work/LinuxDrives/20.printk_debug/first_drv.c first_drv_open 23 <7>/work/LinuxDrives/20.printk_debug/first_drv.c first_drv_open 25 <7>/work/LinuxDrives/20.printk_debug/first_drv.c first_drv_open 27
5、串口与printk函数的关系: