38、Linux内核调试与开发指南

Linux内核调试与开发指南

1. 看门狗设备的用户空间管理

1.1 看门狗sysfs接口

看门狗框架允许通过sysfs接口从用户空间管理看门狗设备。前提是内核中启用了 CONFIG_WATCHDOG_SYSFS 配置选项,根目录为 /sys/class/watchdogX/ ,其中 X 是系统中看门狗设备的索引。每个看门狗目录包含以下属性:
| 属性 | 描述 |
| ---- | ---- |
| nowayout | 若设备支持 nowayout 特性则返回1,否则返回0 |
| status | 相当于 WDIOC_GETSTATUS ioctl,报告看门狗的内部状态位 |
| timeleft | 相当于 WDIOC_GETTIMELEFT ioctl,返回看门狗重置系统前剩余的时间(秒) |
| timeout | 显示当前编程的超时值 |
| identity | 包含看门狗设备的标识字符串 |
| bootstatus | 相当于 WDIOC_GETBOOTSTATUS ioctl,指示系统重置是否由看门狗设备引起 |
| state | 显示看门狗设备的活动/非活动状态 |

1.2 预超时事件处理

可以通过sysfs设置调节器(governor),调节器是一种策略管理器,根据外部参数采取特定操作。有热调节器、CPUFreq调节器和看门狗调节器,每个调节器在各自的驱动中实现。

查看可用的调节器:

# cat /sys/class/watchdog/watchdog0/pretimeout_available_governors
noop panic

检查是否可以选择预超时调节器:

# cat /sys/class/watchdog/watchdog0/pretimeout_governor
panic
# echo -n noop > /sys/class/watchdog/watchdog0/pretimeout_governor
# cat /sys/class/watchdog/watchdog0/pretimeout_governor
noop

检查预超时值:

# cat /sys/class/watchdog/watchdog0/pretimeout
10

2. Linux内核发布过程

2.1 内核发布类型

根据Linux内核发布模型,有三种活跃的内核发布类型:主线(mainline)、稳定版(stable release)和长期支持版(Long-Term Support,LTS)。
- 主线内核 :由子系统维护者收集和准备错误修复和新特性,提交给Linus Torvalds,包含在他的主线Linux树(即主Git仓库)中,所有稳定版都源于此。
- 稳定版内核 :基于主线内核发布,在新内核版本发布前,会通过发布候选标签提交给社区,开发者测试和完善新特性并反馈。Linus根据反馈决定最终版本是否发布,稳定版为 vX.Y 版本。
- 长期支持版内核 :为需要长期稳定性的系统提供支持。

2.2 内核发布流程

graph LR
    A[子系统维护者收集特性和修复] --> B[提交给Linus Torvalds]
    B --> C[Linus将其纳入主线Linux树]
    C --> D[发布候选版本供社区测试]
    D --> E{Linus决定是否发布最终版本}
    E -- 是 --> F[发布稳定版内核]
    E -- 否 --> D
    F --> G[稳定版内核进入linux - stable树]
    G --> H[可接收错误修复]

新主线内核通常每2 - 3个月发布一次,稳定版内核基于主线内核发布,错误修复需要先合并到主线树,再反向移植到稳定版。

2.3 相关链接

3. Linux内核开发调试技巧

3.1 消息打印

在Linux内核开发中,消息打印和日志记录是常用的调试方法。 printk() 函数是内核消息打印的事实标准函数,类似于C库中的 printf() ,但有日志级别概念。

printk(<LOG_LEVEL> " printf like formatted message\n" );

其中 <LOG_LEVEL> 是 include/linux/kern_levels.h 中定义的八种日志级别之一,用于指定错误消息的严重程度。

3.2 内核日志级别

日志级别 定义 描述
KERN_EMERG “0” 紧急消息,系统即将崩溃或不稳定
KERN_ALERT “1” 发生严重情况,需立即采取行动
KERN_CRIT “2” 关键情况,如严重的硬件/软件故障
KERN_ERR “3” 错误条件,常用于驱动程序指示硬件问题或与子系统交互失败
KERN_WARNING “4” 警告消息,本身不严重,但可能表示存在问题
KERN_NOTICE “5” 无严重问题,但值得关注,常用于报告安全事件
KERN_INFO “6” 信息性消息,如驱动初始化时的启动信息
KERN_DEBUG “7” 调试目的,仅在启用 DEBUG 内核选项时有效

若未指定日志级别,默认使用 DEFAULT_MESSAGE_LOGLEVEL (通常为 KERN_WARNING ),可通过 CONFIG_DEFAULT_MESSAGE_LOGLEVEL 内核配置选项设置。

3.3 消息显示控制

内核通过比较消息的日志级别和 console_loglevel 内核变量来决定是否立即将消息显示给用户。

查看当前 console_loglevel :

$ cat /proc/sys/kernel/printk
4    4    1    7

第一个整数是当前控制台日志级别,第二个是默认值,第三个是可设置的最小控制台日志级别,第四个是启动时的默认控制台日志级别。

更改当前 console_loglevel :

# echo 8 > /proc/sys/kernel/printk

也可以使用 dmesg 命令:

# dmesg -n 5

还可以在启动时使用 loglevel 启动参数指定。

3.4 内核日志缓冲区

内核消息会记录在一个固定大小的循环缓冲区中。可以通过 LOG_BUF_SHIFT 选项在编译时设置缓冲区大小,也可以在启动时使用 log_buf_len 参数设置,例如 log_buf_len=1M (仅接受2的幂值)。

3.5 添加时间信息

通过启用 CONFIG_PRINTK_TIME 选项,可以为打印的消息添加时间信息。启用后,每个日志消息前会有时间戳:

$ dmesg
[…]
[    1.260037] loop: module loaded
[    1.260194] libphy: Fixed MDIO Bus: probed
[…]

可以在运行时通过以下命令控制时间戳的显示:

# echo 1 >/sys/module/printk/parameters/time
# cat /sys/module/printk/parameters/time
Y

4. Linux内核追踪与性能分析

4.1 Ftrace简介

Ftrace是Linux内核内部的追踪工具,可用于测量中断处理时间、跟踪耗时函数、计算高优先级任务激活时间、跟踪上下文切换等。

要支持Ftrace,需要启用以下内核选项:
- CONFIG_FUNCTION_TRACER
- CONFIG_FUNCTION_GRAPH_TRACER
- CONFIG_STACK_TRACER
- CONFIG_DYNAMIC_FTRACE

这些选项依赖于架构支持追踪特性,即启用 CONFIG_HAVE_FUNCTION_TRACER 、 CONFIG_HAVE_DYNAMIC_FTRACE 和 CONFIG_HAVE_FUNCTION_GRAPH_TRACER 选项。

挂载 tracefs 目录:

# mount -t tracefs nodev /sys/kernel/debug/tracing

4.2 可用追踪器

通过以下命令查看可用的追踪器:

# cat /sys/kernel/debug/tracing/available_tracers
blk function_graph wakeup_dl wakeup_rt wakeup irqsoff function nop

各追踪器特点如下:
| 追踪器 | 描述 |
| ---- | ---- |
| function | 无参数的函数调用追踪器 |
| function_graph | 带子调用的函数调用追踪器 |
| blk | 与块设备I/O操作相关的调用和事件追踪器 |
| mmiotrace | 内存映射I/O操作追踪器 |
| irqsoff | 追踪禁用中断的区域并保存最长延迟的追踪记录 |
| preemptoff | 追踪并记录禁用抢占的时间 |
| preemtirqsoff | 追踪并记录禁用中断和/或抢占的最长时间 |
| wakeup | 追踪并记录最高优先级任务唤醒后调度的最大延迟 |
| wakeup_rt | 追踪并记录实时任务唤醒后调度的最大延迟 |
| nop | 最简单的追踪器,仅显示 trace_printk() 调用的输出 |

4.3 函数追踪器

使用函数追踪器的测试脚本:

# cd /sys/kernel/debug/tracing
# echo function > current_tracer
# echo 1 > tracing_on
# sleep 1
# echo 0 > tracing_on
# less trace

执行该脚本后,输出包含进程名、进程ID、CPU编号、函数开始时间、被追踪函数名和调用它的父函数名等信息。

4.4 函数图追踪器

函数图追踪器比函数追踪器更详细,能显示每个函数的入口和出口点,可追踪带子调用的函数并测量执行时间。

测试脚本:

# cd /sys/kernel/debug/tracing
# echo function_graph > current_tracer
# echo 1 > tracing_on
# sleep 1
# echo 0 > tracing_on
# less trace

输出中, DURATION 显示函数运行时间, + 表示函数执行时间超过10微秒, ! 表示超过100微秒。

4.5 函数过滤

可以使用过滤器选择要追踪的函数,减少追踪开销。

只追踪 kfree 函数:

# echo kfree > set_ftrace_filter

禁用过滤器:

# echo  > set_ftrace_filter

排除 kfree 函数:

# echo kfree > set_ftrace_notrace

还可以使用 set_ftrace_pid 工具追踪特定进程调用的函数。

4.6 追踪事件

4.6.1 追踪点

追踪点是触发系统事件的特殊代码插入点,分为动态和静态两种。静态追踪点不影响系统,仅在被检测函数末尾添加函数调用的几个字节和在单独部分添加数据结构;动态追踪点在执行相关代码片段时调用追踪函数,追踪数据写入环形缓冲区。

4.6.2 查看可用事件
# cat /sys/kernel/debug/tracing/available_events
mac80211:drv_return_void
mac80211:drv_return_int
[…]

更结构化的列表:

# ls /sys/kernel/debug/tracing/events
block         gpio          napi          regmap     syscalls
cfg80211      header_event  net           regulator   task
[…]
4.6.3 追踪hrtimer相关函数
# cd /sys/kernel/debug/tracing/
# echo 0 > tracing_on
# echo > trace
# echo nop > current_tracer
# echo 1 > events/timer/enable
# echo 1 > tracing_on;
# sleep 1;
# echo 0 > tracing_on;
# echo 0 > events/timer/enable
# less trace

4.7 追踪特定进程

要追踪特定进程调用的内核函数,可以将 set_ftrace_pid 变量设置为该进程的PID。如果进程未运行,可以使用包装脚本:

#!/bin/sh
echo $$ > /debug/tracing/set_ftrace_pid
# [can set other filtering here]
echo function_graph > /debug/tracing/current_tracer
exec $*

假设脚本名为 trace_process.sh ,使用示例:

./trace_process.sh some_command

通过以上方法,可以更有效地进行Linux内核的开发和调试工作。

5. 总结与应用建议

5.1 核心要点总结

  • 看门狗设备管理 :通过sysfs接口可在用户空间对看门狗设备进行管理,包括检查设备特性、状态、超时值等,还能处理预超时事件,设置相应的调节器。
  • 内核发布过程 :Linux内核有主线、稳定版和长期支持版三种发布类型,发布过程涉及子系统维护者收集特性、提交给Linus Torvalds、社区测试反馈等环节,稳定版内核可接收反向移植的错误修复。
  • 内核开发调试 :使用 printk() 函数进行消息打印,有八种日志级别可用于区分消息严重程度。可通过 console_loglevel 控制消息显示,还能调整内核日志缓冲区大小和添加时间信息。
  • 内核追踪与性能分析 :Ftrace是强大的内核内部追踪工具,有多种追踪器可供选择,能对函数调用、事件等进行追踪,还可使用过滤器和追踪特定进程。

5.2 应用建议

5.2.1 看门狗设备应用
  • 当需要确保系统的可靠性时,可利用看门狗设备的特性。例如,在嵌入式系统中,设置合适的超时值,定期喂狗,防止系统因异常而崩溃。
  • 对于预超时事件,可以根据实际需求选择合适的调节器,如在关键任务系统中,可选择 panic 调节器,在系统即将超时前采取紧急措施。
5.2.2 内核开发调试应用
  • 在开发新的内核模块或驱动时,使用 pr_*() 系列宏进行消息打印,方便调试和日志记录。
  • 当遇到难以定位的问题时,可通过调整 console_loglevel 显示更多的日志信息,也可启用 CONFIG_PRINTK_TIME 添加时间信息,辅助分析问题。
5.2.3 内核追踪与性能分析应用
  • 在优化系统性能时,使用Ftrace的不同追踪器来分析系统瓶颈。例如,使用 function_graph 追踪器找出耗时较长的函数,进行针对性优化。
  • 当需要追踪特定进程的内核函数调用时,使用 set_ftrace_pid 工具,减少无关信息的干扰。

5.3 未来展望

随着Linux内核的不断发展,调试和追踪工具也会不断完善。未来可能会有更高效、更强大的工具出现,帮助开发者更轻松地进行内核开发和调试。同时,对于内核的安全性和稳定性要求也会越来越高,相关的技术和方法也会不断演进。

6. 常见问题解答

6.1 看门狗设备相关问题

6.1.1 如何判断看门狗设备是否支持 nowayout 特性?

可以通过查看 /sys/class/watchdog/watchdogX/nowayout 文件的值,若为1则支持,为0则不支持。

6.1.2 预超时调节器设置失败怎么办?

首先检查文件权限,确保有足够的权限进行写入操作。然后检查输入的调节器名称是否正确,是否在 pretimeout_available_governors 列表中。

6.2 内核发布与开发相关问题

6.2.1 如何获取最新的内核版本?

可以访问 https://www.kernel.org/ 下载内核存档,也可以关注 https://www.kernel.org/category/releases.html 获取最新LTS内核版本及其支持时间线。

6.2.2 为什么有些日志消息在控制台不显示?

这可能是因为消息的日志级别低于 console_loglevel 的值。可以通过 cat /proc/sys/kernel/printk 查看当前 console_loglevel ,并根据需要进行调整。

6.3 内核追踪与性能分析相关问题

6.3.1 Ftrace追踪数据丢失怎么办?

可以尝试增大内核日志缓冲区的大小,通过 log_buf_len 参数在启动时设置。同时,检查系统资源是否充足,避免因资源不足导致数据丢失。

6.3.2 如何选择合适的Ftrace追踪器?

根据具体的需求选择。如果只需要追踪函数调用,可选择 function 追踪器;如果需要查看函数的子调用和执行时间,可选择 function_graph 追踪器;如果关注系统的延迟问题,可选择 irqsoff 、 preemptoff 等延迟追踪器。

7. 总结

本文详细介绍了Linux内核调试与开发的相关知识,包括看门狗设备的用户空间管理、内核发布过程、开发调试技巧以及内核追踪与性能分析等方面。通过对这些知识的学习和应用,开发者可以更高效地进行Linux内核的开发和调试,提高系统的可靠性和性能。同时,我们也给出了常见问题的解答和应用建议,希望能对读者有所帮助。

以下是一个总结性的mermaid流程图,展示整个Linux内核开发调试的流程:

graph LR
    A[看门狗设备管理] --> B[内核发布与获取]
    B --> C[内核开发调试]
    C --> D[内核追踪与性能分析]
    D --> E[问题解决与优化]
    E --> A

这个流程图表明,在Linux内核开发过程中,各个环节是相互关联、循环迭代的。从看门狗设备的管理确保系统可靠性,到获取合适的内核版本进行开发,再到使用调试技巧和追踪工具解决问题和优化性能,最后又回到看门狗设备管理等环节,不断提升系统的质量。

相关推荐

Linux内核开发学习路线与实战指南

操作系统作为计算机系统的核心,其内核开发涉及进程调度、内存管理和设备驱动等关键技术。Linux内核采用模块化设计,通过系统调用与用户态交互,其源码结构包含arch、drivers、fs等关键目录。掌握内核开发需要深入理解C语言和系统编程,使用QEMU和GDB搭建调试环境。内核模块开发、字符设备驱动编写以及sysfs接口实现是常见的工程实践场景。通过ftrace和perf工具进行性能分析,结合KASLR和SELinux等安全机制,可以构建稳定高效的内核系统。本文以Linux 6.18 LTS为例,详解内核学习

weixin_33416697的博客 268

38、基于KGDB的ARM目标系统与内核调试指南

本文详细介绍了如何使用KGDB对基于ARM架构的目标系统进行内核和内核模块的调试。内容涵盖测试目标系统的搭建、KGDB调试环境的配置、内核调试方法、内核模块调试技巧,以及调试模块初始化函数的挑战与解决方案。通过QEMU模拟器和交叉编译工具链,开发者可以深入分析内核运行状态,设置断点、单步执行代码、查看变量值,从而高效定位和解决内核相关问题。文章还提供了详细的调试流程图和实用的GDB命令,帮助读者掌握KGDB调试的核心技能。

e1f2g的博客 78

38、Linux内核开发与调试全攻略

本文全面介绍了Linux内核开发与调试的核心技术,涵盖看门狗设备的用户空间操作、内核发布流程(主线/稳定/LTS版本)、开发技巧(如printk日志级别和pr_fmt宏)、以及使用ftrace进行函数跟踪、事件监控和性能分析的方法。同时提供了内核模块开发示例、常见问题解决方案,并展望了智能化调试、多核并行调试等未来趋势,是深入掌握Linux内核开发的实用指南。

alice7model的博客 119

强化学习-----DQN(Deep Q-network)

DQN(Deep Q-Network)是一种基于深度学习和强化学习的算法,由DeepMind提出,用于解决离散动作空间下的马尔科夫决策过程(MDP)问题。它是首个成功将深度学习应用于解决强化学习任务的算法之一。DQN,即深度Q网络(Deep Q-network),是指基于深度学习的Q-Learing算法。那什么是Q-leaning?可以看上一篇文章Q-learning是一种经典的强化学习算法,用于解决马尔可夫决策过程(Markov Decision Process,MDP)中的控制问题。

qq_74722169的博客 2万+

【数字电源/MATLAB+PLECS】如何进行 Buck 数字电源仿真(二)PLECS 搭建开环 Buck 功率级

本文介绍了如何在PLECS中搭建开环Buck功率级模型,验证数字电源设计的基本思路。重点内容包括: 明确开发顺序:先开环验证功率级,再闭环设计控制器 搭建关键组件:输入电源、PWM模块、MOSFET开关、续流二极管、LC滤波电路及负载 设置初始参数:24V输入、12V输出、200kHz开关频率、22μH电感、100μF电容 测量关键波形:MOSFET Vds验证开关动作、电感电流纹波和输出电压稳态值 提供完整仿真模型和GitHub资源,便于读者复现验证 文章强调通过开环测试先确保功率级正确性,为后续闭环控制

weixin_43234123的博客 1227

别再纠结选哪个向量库了!我用Spring AI + Redis Stack 7.2,5分钟搞定企业知识库RAG原型

本文介绍了如何利用Spring AI和Redis Stack 7.2快速构建企业级RAG应用,解决向量数据库选型难题。Redis Stack 7.2集成了RediSearch模块,支持向量相似性搜索,具备高性能、低成本、零学习成本等优势,特别适合中小团队快速搭建知识库系统。通过实战代码示例,展示了从环境准备到核心功能实现的完整流程。

weixin_29061041的博客 275

SAP MM自动化进阶:STO交货单自动创建的配置与优化

本文深入解析了SAP MM模块中实现公司间库存调拨订单(STO)交货单自动创建的完整配置流程与优化策略。通过激活自动交货与绑定发货点两大核心配置,打通自动化链路。重点探讨了如何集成ATP可用性检查以智能处理库存不足等异常场景,确保自动化流程的可靠性与业务贴合度,并提供了进阶监控与问题排查方法,助力企业显著提升供应链效率。

weixin_29206669的博客 126

TenserRt平台SMOKE 3D目标检测部署完整教程:从理论到实践

本教程详细介绍了在RK3588平台上部署SMOKE 3D目标检测模型的完整流程。SMOKE是一种创新的单阶段单目3D检测方法,通过关键点估计直接预测3D目标信息,有效解决了深度信息缺失等挑战。文章从理论基础出发,解析了SMOKE的核心算法和网络架构,包括DLA-34主干网络和关键点中心化策略。同时提供了详细的Docker环境配置、模型导出到ONNX格式的实践指南,以及TensorRT引擎构建和性能优化的关键技术要点。该教程为开发者在嵌入式平台上实现高效3D目标检测提供了完整的技术参考。

LXY_LOVE36的博客 373

ImportError: DLL load failed while importing _pydantic_core: 找不到指定的程序对应解决方案

本文主要介绍了ImportError: DLL load failed while importing _pydantic_core: 找不到指定的程序对应解决方案,希望能对使用Python的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 19万+

2 君正底层API接口的封装1

君正的IPC芯片主要有T31、T40、T41等型号,每个型号的API接口大部分是相同的,但也存在一些不一致和差异化的地方。为了屏蔽不同芯片型号之间的差异,我们需要基于一个公共基类进行封装。在封装之前,我们需要定义自己的错误码和数据结构,用于屏蔽不同君正芯片的实现细节。为了确保整个IPC库使用统一的错误码,我们在HP_MPPErrorCode.h文件中专门定义了以下错误码。错误码囊括了参数错误、内存错误、溢出错误、不支持、密码错误、非法数据等各种异常情况。

hope_wisdom的技术博客 1592

56、Cortex - M33处理器浮点单元(FPU)的使用与优化

本文详细介绍了Cortex-M33处理器浮点单元(FPU)的使用与优化方法,涵盖单双精度浮点计算的选择、编译器命令行配置、ABI模式对比、特殊FPU模式设置(如Flush-to-Zero、Default NaN)、浮点异常处理机制以及FPU电源管理策略。结合代码示例和流程图,提供了在不同应用场景下的最佳实践建议,并总结了常见问题及解决方案,帮助开发者提升嵌入式系统中浮点运算的性能、精度与能效。

bread的博客 155

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

上一篇: 16、树莓派文件处理与libc库的使用
下一篇: 37、老年人与数字应用:WhatsApp及压力监测应用的使用洞察
人间清醒863
博客等级 码龄3年 33粉丝 1544原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值