printk打印时间在sleep之后不继续,反映不出休眠时间的问题

本文介绍了时间单位的换算及内核中时间记录的方法,详细解释了如何通过宏do_div进行时间转换,并讨论了在suspend及resume状态下printk_clock()函数的表现。考虑到jiffies值的变化,提出了修正休眠唤醒时时间显示的方案。

1秒=1000毫秒 1毫秒=1000微秒 1微秒=1000纳秒
此处读取的是ns,
t = printk_clock();
nanosec_rem = do_div(t, 1000000000);
对于do_div()是一个宏,t现在是整数部分,返回值nanosec_rem是余数部分
tlen = sprintf(tbuf,"<%c>[%5lu.%06lu] ",loglev_char,(unsigned long)t,nanosec_rem/1000);
此处nanosec_rem/1000取到的是微妙。
对于suspend以及resume,printk_clock()是基于cpu调度实现的,如果suspend之后cpu不再调度,所以值不变,由于timekeep的framework的机制,会自动唤醒之后修改jiffies的值,可以考虑用jiffies的值来修正休眠唤醒printk打印时间的问题

在Linux内核开发和调试过程中,`printk()` 是一个非常重要的调试工具,用于将信息打印到内核日志中。如果遇到 `printk` 打印日志的问题,可能涉及多个层面的原因。以下是一些常见的排查方向和解决方法。 ### 1. 检查日志级别设置 `printk` 的输出受到日志级别的限制。内核维护了一个控制台日志级别(console log level),只有优先级高于该值的消息才会被打印到控制台。默认情况下,这个值是 `4`(即 `KERN_WARNING`)。 可以通过以下方式查看当前的控制台日志级别: ```bash cat /proc/sys/kernel/printk ``` 输出的四个数字分别表示: - 控制台日志级别 - 默认消息日志级别 - 最低允许的控制台日志级别 - 默认控制台日志级别 要临时提升控制台日志级别以显示更多输出,可以执行: ```bash echo 8 > /proc/sys/kernel/printk ``` 这会将控制台日志级别设为 `KERN_DEBUG` 级别,确保所有 `printk` 输出都能被显示[^2]。 --- ### 2. 检查控制台设备是否正常工作 有时问题不出在 `printk` 本身,而是控制台设备未正确配置或未启用。例如,在嵌入式系统中,串口控制台可能没有正确初始化。 可以通过以下方式确认当前使用的控制台设备: ```bash dmesg | grep -i console ``` 或者检查启动参数中的 `console=` 设置是否正确。例如: ``` console=ttyS0,115200n8 ``` 如果使用的是虚拟终端(如 QEMU 或桌面环境),请确保图形终端或串口终端已正确连接并运行。 --- ### 3. 使用 `dmesg` 查看内核日志缓冲区 即使控制台没有输出,`printk` 的消息仍然会被写入内核的日志环形缓冲区中。可以通过 `dmesg` 命令查看这些信息: ```bash dmesg ``` 还可以通过过滤关键字来查找特定日志: ```bash dmesg | grep -i your_keyword ``` 这种方式适用于控制台输出受限或无法直接观察的情况[^1]。 --- ### 4. 动态调试功能 Linux 内核支持动态调试(Dynamic Debug),可以通过 `dynamic_debug` 子系统启用或禁用特定模块或函数的日志输出。这对于调试 `printk` 本身或追踪特定代码路径非常有用。 启用动态调试的方法如下: ```bash mount -t debugfs none /sys/kernel/debug echo -n 'file your_file.c +p' > /sys/kernel/debug/dynamic_debug/control ``` 其中 `your_file.c` 是你想调试的源文件名。此操作将启用该文件中所有 `pr_debug()` 和 `dev_dbg()` 的输出[^1]。 --- ### 5. 检查 `printk` 调用是否被优化掉 在某些编译条件下,尤其是开启了 `CONFIG_PRINTK` 选项未定义时,`printk` 可能会被完全移除。此外,如果调用了 `printk(KERN_DEBUG ...)`,而当前日志级别大于 `KERN_DEBUG`,则该语句会被编译进内核。 确保内核配置中启用了以下选项: ``` CONFIG_PRINTK=y CONFIG_DEBUG_KERNEL=y CONFIG_DYNAMIC_DEBUG=y ``` 可以在 `.config` 文件中检查这些配置项是否存在并启用。 --- ### 6. 检查内核崩溃或 OOPs 是否影响了日志输出 如果系统发生了内核 OOPs 或 panic,可能导致 `printk` 无法正常输出后续日志。此时应检查 `dmesg` 输出是否有异常记录: ```bash dmesg | grep -i oops ``` 一旦发现 OOPs,需要分析其堆栈信息、寄存器状态以及出错地址,结合 `System.map` 文件进行符号解析和定位错误源头[^4]。 --- ### 7. 替代方案:使用 `early_printk` 在某些早期启动阶段(如引导加载程序与内核切换期间),标准 `printk` 可能尚未初始化。此时可以启用 `CONFIG_EARLY_PRINTK` 配置项,以提供更早的日志输出能力。 在内核命令行中添加: ``` earlyprintk ``` 或者针对特定平台(如 ARM): ``` earlyprintk=uart8250,io,0x3f8 ``` 这样可以在内核启动早期阶段就输出调试信息,帮助诊断 `printk` 失效的问题。 --- ### 示例:修改 printk 日志级别并查看日志 ```bash # 查看当前 printk 设置 cat /proc/sys/kernel/printk # 修改控制台日志级别为 KERN_DEBUG echo 8 > /proc/sys/kernel/printk # 查看 dmesg 缓冲区内容 dmesg | tail -20 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值