Linux调试之(一)内核动态打印

文章目录

    • Linux动态打印的两种方式
    • 一、驱动使用module_param_named方法**
      • 1.驱动添加代码:
      • 2.打开动态打印
    • 二、系统动态打印
    • 【1】配置Kconfig
    • 【2】配置Makefile
    • 【3】配置内核,使支持动态调试
    • 【4】编译加载
    • 【5】控制端动态修改打印级别
      • (1)修改系统的打印级别
      • (2)修改局部动态打印

Linux动态打印的两种方式

https://blog.csdn.net/u010481276/article/details/50896520

一、驱动使用module_param_named方法**

  原型:module_param_named(name, variable, type, perm);
其中name是外部可见的参数名,variable是源文件内部的全局变量名。而module_param通过
module_param_named实现,此时name与variable相同。该方法可以使模块源文件内部的变量
名与外部的参数名有不同的名字

1.驱动添加代码:

static int dbg_enable = 0;
module_param_named(dbg_level, dbg_enable, int, 0644);
#define sensor_printk(args...) \
do { \
if (dbg_enable) { \
pr_info(args); \
} \
} while (0)#ifdef pr_debug
#undef pr_debug
#define pr_debug(fmt,...) printk(KERN_INFO"%s:%s :%d\n "fmt, __FILE__ , __FUNCTION__ , __LINE__ , ##__VA_ARGS__)
#else
#define pr_debug(fmt, ...)     printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
#endif
(1) VA_ARGS 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。宏前面  加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的”,”去掉的作用,否则会编译出错, 你可以试试。 
(2) FILE 宏在预编译时会替换成当前的源文件名 
(3) LINE宏在预编译时会替换成当前的行号 
(4) FUNCTION宏在预编译时会替换成当前的函数名称

2.打开动态打印

 echo 1 >  /sys/module/hello/parameters/dbg_enable

二、系统动态打印

【1】配置Kconfig

http://blog.chinaunix.net/uid-20746260-id-3044842.html
添加要调试驱动模块的DEBUG选项如driver/char目录下Kconfig中添加如下代码:

config MY_KEY	//该部分配置驱动是否编译进内核/编译为内核模块/不编译
  tristate "Key driver for FriendlyARM Tiny6410 development boards"
  depends on CPU_S3C6410
  default m
  help
   this is buttons driver, add by Jason

config MY_KEY_DEBUG	//该部分是调试时添加,配置是否打印调试信息,如果不需要可不添加
  bool "Support MY_KEY DEBUG"
  help
   this is DEBUG function, add by Jason
depends on MY_KEY

【2】配置Makefile

https://blog.csdn.net/SoaringLee_fighting/article/details/79676261
(1)makefile 添加编译支持驱动模块

EXTRA_CFLAGS += -DDEBUG 如在driver/char目录下的Makefile中添加如下代码: 	
obj-$(CONFIG_MY_KEY)        += my_key.o
ifeq ($(CONFIG_MY_KEY_DEBUG), y)            	//判断是否调试驱动
EXTRA_CFLAGS += -DDEBUG
endif

(2)文件加define DEBUG,在include之前
打开pr_debug的打印,修改打印级别:kernel/printk/printk.c

#define DEFAULT_CONSOLE_LOGLEVEL 8 /* anything MORE serious than KERN_DEBUG */

 在include/linux/printk.h中打开宏,则系统增加全局pr_debug打印  
 #define DEBUG

【3】配置内核,使支持动态调试

(1)打开dyanmic printk开关

$: make menuconfig
Kernel hacking  --->
	[*] Tracers  --->
		[*] Trace max stack
	[*] Enable dynamic printk() support  Kernel                                                           	                        	

(2)def_config中需要打开以下两个宏

CONFIG_DEBUG_FS=y
CONFIG_DYNAMIC_DEBUG=y  

(3)配置CONFG使能
在文件系统中生成如下节点:

/sys/kernel/debug/dynamic_debug/control      

【4】编译加载

如果驱动选择的是动态加载,则重新编译模块(make modules);否则,重新编译内核(make uImage -j4)
如果驱动选择的是动态加载,则传
.ko文件到板子的文件系统;否则,重烧内核。
*****

【5】控制端动态修改打印级别

(1)修改系统的打印级别

//查看控制台debug级别
cat >  /proc/sys/kernel/printk 
1 4 7 2
//控制台debug消息显示级别7-->8,可以打印printk(DEBUG ...)                                                                                                                                                                                                   
cat  "8" > /proc/sys/kernel/printk    
//修改printk对应的打印级别
echo 1  4  1 7 > /proc/sys/kernel/printk  

(2)修改局部动态打印

查看支持的动态调试选项:

/sys/kernel/debug/dynamic_debug # cat control 
# filename:lineno [module]function flags format
init/main.c:712 [main]initcall_blacklist =p "blacklisting initcall %s\012"
init/main.c:736 [main]initcall_blacklisted =p "initcall %s blacklisted\012"
init/initramfs.c:483 [initramfs]unpack_to_rootfs =_ "Detected %s compressed data\012"
 蓝绿色部分是pr_debug,就可以在配置内核时通过选择或取消DEBUG选项,控制调试信息开
 关;很显然使用pr_debug().pr_info(), pr_err()等pr_xxx()家族打印函数。

需要打印时(即动态调试), 在命令行输入以下命令
包含func_name1和func_name2中的所有的pr_xxx()调试信息都可输出到内核日志里:

echo "func func_name1 +p" >> /sys/kernel/debug/dynamic_debug/control
echo "func func_name2 +p" >> /sys/kernel/debug/dynamic_debug/control

打开整个文件(即编译之前对应的源文件)的动态调试日志:

echo -n 'file xxx.c +p' >> /sys/kernel/debug/dynamic_debug/control

打开整个模块的动态调试日志:

echo "module module_name +p" > /dynamic_debug/control

关闭的话:

echo "module module_name -p" > /dynamic_debug/control

你可能感兴趣的:(LINUX,内核驱动,Linux动态打印)