0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux内核基础:动态输出使用

麦辣鸡腿堡 来源:嵌入式Linux充电站 作者:Vincent 2023-09-27 15:51 次阅读

动态输出使用

打开svcsock.c文件中所有的动态输出语句

# echo 'file svcsock.c +p' > /sys/kernel/debug/dynamic_debug/control

打开usbcore模块中所有的动态输出语句

# echo 'module usbcore +p' > /sys/kernel/debug/dynamic_debug/control

打开svc_process()函数中所有的动态输出语句

# echo 'func svc_process() +p' > /sys/kernel/debug/dynamic_debug/control

打开文件路径包含usb的文件里所有的动态输出语句

# echo -n '*usb* +p' > /sys/kernel/debug/dynamic_debug/control

打开系统所有的动态输出语句

# echo -n '+p' > /sys/kernel/debug/dynamic_debug/control

上面是打开动态输出语句的例子,除了能输出pr_debug()/dev_dbg()函数中定义的输出信息外,还能输出一些额外信息,如函数名、行号、模块名字以及线程ID等

  • p:打开动态输出语句
  • f:输出函数名
  • l:输出行号
  • m:输出模块名字
  • t:输出线程ID

另外,还可以在各个子系统的Makefile中添加ccflags来打开动态输出语句

< ../Makefile >

ccflags-y += -DDEBUG
ccflags-y += -DVERBOSE_DEBUG

实际案例

例如在一个led驱动中的open()、write()等函数开头添加一句pr_debug("%s entern",
**func **** ** );

#include < linux/module.h >
#include < linux/fs.h >
#include < linux/errno.h >
#include < linux/miscdevice.h >
#include < linux/kernel.h >
#include < linux/major.h >
#include < linux/mutex.h >
#include < linux/proc_fs.h >
#include < linux/seq_file.h >
#include < linux/stat.h >
#include < linux/init.h >
#include < linux/device.h >
#include < linux/tty.h >
#include < linux/kmod.h >
#include < linux/gfp.h >

static int major = 0;
static char kernel_buf[1024];
static struct class *hello_class;

#define MIN(a, b) (a < b ? a : b)

static ssize_t hello_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
 int err;
 pr_debug("%s entern", __func__);

 err = copy_to_user(buf, kernel_buf, MIN(1024, size));
 return MIN(1024, size);
}

static ssize_t hello_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
{
 int err;
 pr_debug("%s entern", __func__);
 err = copy_from_user(kernel_buf, buf, MIN(1024, size));
 return MIN(1024, size);
}

static int hello_drv_open (struct inode *node, struct file *file)
{
 pr_debug("%s entern", __func__);
 return 0;
}

static int hello_drv_close (struct inode *node, struct file *file)
{
 pr_debug("%s entern", __func__);
 return 0;
}

/* 2. 定义自己的file_operations结构体                                              */
static struct file_operations hello_drv = {
 .owner  = THIS_MODULE,
 .open    = hello_drv_open,
 .read    = hello_drv_read,
 .write   = hello_drv_write,
 .release = hello_drv_close,
};

static int __init hello_init(void)
{
 int err;
 
 pr_debug("%s entern", __func__);
 major = register_chrdev(0, "hello", &hello_drv);  /* /dev/hello */

 hello_class = class_create(THIS_MODULE, "hello_class");
 err = PTR_ERR(hello_class);
 if (IS_ERR(hello_class)) {
  unregister_chrdev(major, "hello");
  return -1;
 }
 
 device_create(hello_class, NULL, MKDEV(major, 0), NULL, "hello"); /* /dev/hello */
 
 return 0;
}

static void __exit hello_exit(void)
{
 pr_debug("%s entern", __func__);
 device_destroy(hello_class, MKDEV(major, 0));
 class_destroy(hello_class);
 unregister_chrdev(major, "hello");
}

module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");

为了方面查看,先清除内核输出:

# dmesg -c

然后加载驱动,执行dmesg查看是否有打印:

# insmod hello_drv.ko
# dmesg

图片

此时没有pr_debug()的打印。这时再使用动态输出打开hello_drv模块的动态输出:

# echo 'module hello_drv +p' > /sys/kernel/debug/dynamic_debug/control

然后执行该驱动的应用层程序,使其调用到驱动的open、write、close函数,从而执行pr_debug():

# ./hello_drv_test -w 10

再查看demsg内容:

图片

可以看到,当打开了hello_drv模块的动态输出后,驱动中的pr_debug()语句就可以正常打印了。

再看看debugfs的control节点:

# cat /sys/kernel/debug/dynamic_debug/control

图片

control节点记录了刚刚执行pr_debug()时的文件名、所在行号、模块名、函数名和输出语句(p表示动态输出的语句)。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内核
    +关注

    关注

    3

    文章

    1309

    浏览量

    39862
  • 驱动
    +关注

    关注

    11

    文章

    1718

    浏览量

    84357
  • Linux
    +关注

    关注

    87

    文章

    10992

    浏览量

    206744
  • 输出
    +关注

    关注

    0

    文章

    88

    浏览量

    21578
收藏 人收藏

    评论

    相关推荐

    Linux内核学习笔记:动态输出调试

    上篇说到printk调试,但printk是全局的,只能设置输出等级。而动态输出可以动态选择打开某个内核子系统的
    发表于 06-01 15:16 326次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b>学习笔记:<b class='flag-5'>动态</b><b class='flag-5'>输出</b>调试

    嵌入式Linux系统中内核抽象的动态扩展技术

    扩展性的意义。然后,讨论目前几种主要的核心动态扩展技术,以及各种技术在嵌入式系统上的优缺点。最后,分析嵌入式Linux动态扩展性研究所面临的挑战和发展趋势。 1、几种主要的内核
    发表于 10-26 09:22

    嵌入式Linux系统中内核抽象的动态扩展技术

    扩展性的意义。然后,讨论目前几种主要的核心动态扩展技术,以及各种技术在嵌入式系统上的优缺点。最后,分析嵌入式Linux动态扩展性研究所面临的挑战和发展趋势。 1、几种主要的内核
    发表于 10-28 09:53

    嵌入式Linux系统中内核抽象的动态扩展技术

    嵌入式Linux系统中内核抽象的动态扩展技术随着嵌入式技术的快速发展和嵌入式设备的普及,嵌入式应用发展的一个关键趋势是从静态的、固定的系统功能到动态的、可扩展的系统功能。首先,介绍嵌入
    发表于 04-04 17:12

    Linux嵌入式系统中内核技术的可动态拓展技术有哪些

    值后要重新编译内核,对普通用户而言难以实现。通信的发展使得嵌入式操作系统的动态扩展成为可能,可以在远程控制的基础上增加嵌入式系统的灵活性,延长嵌入式系统的寿命;同时,由于嵌入式Linux的应用日益广泛
    发表于 08-06 06:39

    Linux内核教程

    本章学习目标掌握LINUX内核版本的含义理解并掌握进程的概念掌握管道的概念及实现了解内核的数据结构了解LINUX内核的算法掌握
    发表于 04-10 16:59 0次下载

    动态安装的Linux设备驱动程序

    为了增跟内核的灵活性和为了方便,设各驱动程序应被设计为一个可动态安装的内核模块。于是,一个典型的Linux设备驱动程序应包含如下几部分代码:
    发表于 04-04 10:56 896次阅读

    如何配置和使用Linux内核printk功能

    了解如何配置和使用Linux内核printk功能,包括其动态调试功能。 这样可以选择性地打印调试消息,而无需重新编译内核
    的头像 发表于 11-27 06:40 2879次阅读

    linux内核是什么_linux内核学习路线

    Linux内核是一个操作系统(OS)内核,本质上定义为类Unix。它用于不同的操作系统,主要是以不同的Linux发行版的形式。Linux
    发表于 09-16 15:49 2388次阅读

    linux内核参数设置_linux内核的功能有哪些

    本文主要阐述了linux内核参数设置及linux内核的功能。
    发表于 09-17 14:40 1222次阅读
    <b class='flag-5'>linux</b><b class='flag-5'>内核</b>参数设置_<b class='flag-5'>linux</b><b class='flag-5'>内核</b>的功能有哪些

    Linux 5.10.5内核正式发布

    1月6日,Linux基金会宣布,Linux 5.10.5内核正式发布,所有5.10内核系列的用户都必须升级。
    的头像 发表于 01-07 14:36 2379次阅读

    Linux内核】从小小的宏定义窥探Linux内核的精妙设计

    Linux内核】从小小的宏定义窥探Linux内核的精妙设计
    的头像 发表于 08-31 13:30 1649次阅读

    使用动态输出打印内核的DEBUG信息

    printk()是很多嵌入式开发者喜欢用的调试手段之一,但是,使用printk()每次都要重新编译内核,很不方便。使用动态输出在不需要重新编译内核的情况下,方便的打印出
    的头像 发表于 01-06 10:46 576次阅读

    推挽输出能当电源输出使用吗

    推挽输出能当电源输出使用吗  推挽输出是一种重要的电子元件,能够在电路中起到不可或缺的作用。其主要作用是将低电平信号转化为高电平信号,并可直接驱动负载,是一种常用的放大器电路。 在一些应用场
    的头像 发表于 08-31 10:24 672次阅读

    Linux内核动态输出调试

    动态输出可以动态选择打开某个内核子系统的输出,可以有选择性地打开某些模块的输出。 配置
    的头像 发表于 09-27 15:45 309次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b><b class='flag-5'>动态</b><b class='flag-5'>输出</b>调试