搜索
首页系统教程LINUXLinux内核中的调试输出函数:printk详解

Linux内核中的调试输出函数:printk详解

Feb 14, 2024 pm 08:33 PM
linuxlinux教程linux系统linux命令外壳脚本嵌入式linuxlinux入门linux学习

printk是Linux内核中最常用的调试函数之一,它用来向内核缓冲区或控制台输出调试信息,如变量的值,函数的执行流程,错误的原因等。printk的优点是简单易用,不需要额外的设备或驱动。printk的实现涉及到内核缓冲区,日志等级,格式化字符串等概念。在本文中,我们将介绍Linux内核调试技术之printk的原理和方法,并举例说明它们的使用方法和注意事项。

Linux内核中的调试输出函数:printk详解

1、简介(基于s3c2440 linux)

在内核调试技术之中,最简单的就是printk的使用了,它的用法和C语言应用程序中的printf使用类似,在应用程序中依靠的是stdio.h中的库,而在linux内核中没有这个库,所以在linux内核中,使用这个printk就要对内核的实现有一定的了解。

printf和printk的区别:printk会在开头处加上””样式的字符,N的范围是0~7,表示这个信息的级别。

当printk(“”……);中的n

在内核文件中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 (includelinux) 定义了0~7这8个级别的名称

#define   KERN_EMERG   ""    /* system is unusable */
#define    KERN_ALERT    ""  
  /* action must be taken immediately */
#define    KERN_CRIT     ""    /* critical
 conditions */
#define    KERN_ERR      ""    /* error conditions */
#define   
 KERN_WARNING  ""    /* warning conditions */
#define    KERN_NOTICE   ""  
  /* normal but significant condition*/
#define    KERN_INFO     ""   
 /* informational*/
#define    KERN_DEBUG    ""    /* 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

#``# 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)................................

还可以使用 cat /proc/kmsg& 后台运行,实时打印出调试信息。在②中,__FILE__, FUNCTION, __LINE__分别对应的是那个文件,那个函数,第几行。非常实用。

# cat /proc/kmsg&``# ./firstdrvtest on``/work/LinuxDrives/20.printk_debug/first_drv.c
 first_drv_open 23``/work/LinuxDrives/20.printk_debug/first_drv.c first_drv_open 25``
/work/LinuxDrives/20.printk_debug/first_drv.c first_drv_open 27``# ./firstdrvtest off`
`/work/LinuxDrives/20.printk_debug/first_drv.c first_drv_open 23``/work/LinuxDrives/
20.printk_debug/first_drv.c first_drv_open 25``/work/LinuxDrives/20.printk_debug
/first_drv.c first_drv_open 27

5、串口与printk函数的关系:

printk
    vprintk
        vscnprintf //先把输出信息放入临时BUFFER
                // Copy the output into log_buf.
                // 把临时BUFFER里的数据稍作处理,再写入log_buf
                // 比如printk("abc")会得到"abc", 再写入log_buf
                // 可以用dmesg命令把log_buf里的数据打印出来重现内核的输出信息

        // 调用硬件的write函数输出
        release_console_sem    
            call_console_drivers
          //从log_buf得到数据,算出打印级别
                _call_console_drivers
                    if ((msg_log_level write //con是console_drivers链表中的项,对用具体的输出函

数 在drives/serial/s3c2410.c中查看

在该函数中注册一个console结构体
static void s3c24xx_serial_console_write(struct console *co, const char *s,
unsigned int count)
{
uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar);
}

串口输出函数,会调用s3c24xx_serial_console_putchar函数

static int s3c24xx_serial_initconsole(void)
{
    ...........................
    register_console(&s3c24xx_serial_console);
    return 0;
}
static struct console s3c24xx_serial_console =
{
.name = S3C24XX_SERIAL_NAME,//这个宏被定义为:TTYSAC
.device = uart_console_device, //init进程,用户程序打开/dev/console的时候会调用
.flags = CON_PRINTBUFFER,//打印还没有初始化化console前保存在log_buf里面的数据
.index = -1,//选择那个串口,由uboot中的命令决定
.write = s3c24xx_serial_console_write,//控制台输出函数
.setup = s3c24xx_serial_console_setup //串口设置函数
}; 

这个函数和硬件相关,读取寄存器,看数据是否被发送完成,最后将数据一个字节一个字节的写入寄存器,s3c2440的串口控制器会自动把数据发送出去

static void s3c24xx_serial_console_putchar(struct uart_port *port, int ch)

{
unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON);
while (!s3c24xx_serial_console_txrdy(port, ufcon))
barrier();
wr_regb(cons_uart, S3C2410_UTXH, ch);
}

uboot的console=ttySAC0如果在linux中被识别出来是串口0的,在/kernel/printk.c中有一下代码,

__setup("console=", console_setup);

static int __init console_setup(char *str)
{
........
  add_preferred_console(name, idx, options);
} 

内核开始执行时,会发现“console=…”的命令行参数时候,就会调用console_setup函数进行数据解析,对于命令行参数”console=ttySAC0″,会解析出:设备名(name)为ttySAC,索引index为0,这些信息被保存在类型为console_cmdline、名称为console_cmdline的全局数组中(注意:数组名和数组的类型相同)

在后面的register_console(&s3c24xx_serial_console);的时候,会将s3c24xx_serial_console结构和console_cmdline数组中的设备进行比较。

①解析出来的name为S3C24XX_SERIAL_NAME 既“ttySAC”,而console_cmdline中的命令中的name也为“ttySAC”

②s3c24xx_serial_console结构体中的索引index为-1,表示使用命令行参数“console=ttySAC0”中的索引,index = 0

通过本文,我们了解了Linux内核调试技术之printk的原理和方法,它们可以用来实现对内核的调试和输出。我们应该根据实际需求选择合适的方法,并遵循一些基本原则,如使用正确的日志等级,使用正确的格式化字符串,使用正确的输出函数等。printk是Linux内核中最简单而有效的调试函数之一,它可以实现对内核的反馈和监控,也可以提升内核的可维护性和可扩展性。希望本文能够对你有所帮助和启发。

以上是Linux内核中的调试输出函数:printk详解的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:良许Linux教程网。如有侵权,请联系admin@php.cn删除
Linux系统管理员的主要任务是什么?Linux系统管理员的主要任务是什么?Apr 19, 2025 am 12:23 AM

Linux系统管理员的主要任务包括系统监控与性能调优、用户管理、软件包管理、安全管理与备份、故障排查与解决、性能优化与最佳实践。1.使用top、htop等工具监控系统性能,并进行调优。2.通过useradd等命令管理用户账户和权限。3.利用apt、yum管理软件包,确保系统更新和安全。4.配置防火墙、监控日志、进行数据备份以确保系统安全。5.通过日志分析和工具使用进行故障排查和解决。6.优化内核参数和应用配置,遵循最佳实践提升系统性能和稳定性。

很难学习Linux吗?很难学习Linux吗?Apr 18, 2025 am 12:23 AM

学习Linux并不难。1.Linux是一个开源操作系统,基于Unix,广泛应用于服务器、嵌入式系统和个人电脑。2.理解文件系统和权限管理是关键,文件系统是层次化的,权限包括读、写和执行。3.包管理系统如apt和dnf使得软件管理方便。4.进程管理通过ps和top命令实现。5.从基本命令如mkdir、cd、touch和nano开始学习,再尝试高级用法如shell脚本和文本处理。6.常见错误如权限问题可以通过sudo和chmod解决。7.性能优化建议包括使用htop监控资源、清理不必要文件和使用sy

Linux管理员的薪水是多少?Linux管理员的薪水是多少?Apr 17, 2025 am 12:24 AM

Linux管理员的平均年薪在美国为75,000至95,000美元,欧洲为40,000至60,000欧元。提升薪资可以通过:1.持续学习新技术,如云计算和容器技术;2.积累项目经验并建立Portfolio;3.建立职业网络,拓展人脉。

Linux的主要目的是什么?Linux的主要目的是什么?Apr 16, 2025 am 12:19 AM

Linux的主要用途包括:1.服务器操作系统,2.嵌入式系统,3.桌面操作系统,4.开发和测试环境。Linux在这些领域表现出色,提供了稳定性、安全性和高效的开发工具。

互联网在Linux上运行吗?互联网在Linux上运行吗?Apr 14, 2025 am 12:03 AM

互联网运行不依赖单一操作系统,但Linux在其中扮演重要角色。Linux广泛应用于服务器和网络设备,因其稳定性、安全性和可扩展性受欢迎。

Linux操作是什么?Linux操作是什么?Apr 13, 2025 am 12:20 AM

Linux操作系统的核心是其命令行界面,通过命令行可以执行各种操作。1.文件和目录操作使用ls、cd、mkdir、rm等命令管理文件和目录。2.用户和权限管理通过useradd、passwd、chmod等命令确保系统安全和资源分配。3.进程管理使用ps、kill等命令监控和控制系统进程。4.网络操作包括ping、ifconfig、ssh等命令配置和管理网络连接。5.系统监控和维护通过top、df、du等命令了解系统运行状态和资源使用情况。

使用Linux别名提高自定义命令快捷方式的生产率使用Linux别名提高自定义命令快捷方式的生产率Apr 12, 2025 am 11:43 AM

介绍 Linux是一个强大的操作系统,由于其灵活性和效率,开发人员,系统管理员和电源用户都喜欢。但是,经常使用长而复杂的命令可能是乏味的

Linux实际上有什么好处?Linux实际上有什么好处?Apr 12, 2025 am 12:20 AM

Linux适用于服务器、开发环境和嵌入式系统。1.作为服务器操作系统,Linux稳定高效,常用于部署高并发应用。2.作为开发环境,Linux提供高效的命令行工具和包管理系统,提升开发效率。3.在嵌入式系统中,Linux轻量且可定制,适合资源有限的环境。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境