当前位置:网站首页>[21天学习挑战赛——内核笔记](四)——内核常见调试手段(printf、dump_stack、devmem)
[21天学习挑战赛——内核笔记](四)——内核常见调试手段(printf、dump_stack、devmem)
2022-08-09 04:25:00 【光追雨】
活动地址:CSDN21天学习挑战赛
学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您:
想系统/深入学习某技术知识点…
一个人摸索学习很难坚持,想组团高效学习…
想写博客但无从下手,急需写作干货注入能量…
热爱写作,愿意让自己成为更好的人…
…
一、内核调试——printk

printk在内核源码中用来记录日志信息的函数,只能在内核源码范围内使用。用法和printf非常相似
printk函数主要做两件事情:第一件就是将信息记录到log中,而第二件事就是调用控制台驱动来将信息输出。
1.日志级别
printk相比printf来说还多了个:日志级别的设置,用来控制printk打印的这条信息是否在终端上显示的,当日志级别的数值小于控制台级别时,printk要打印的信息才会在控制台打印出来,否则不会显示在控制台!
在我们内核中一共有8种级别,他们分别为
#define KERN_EMERG "<0>" /* system is unusable */
#define KERN_ALERT "<1>" /* action must be taken immediately */
#define KERN_CRIT "<2>" /* critical conditions */
#define KERN_ERR "<3>" /* error conditions */
#define KERN_WARNING "<4>" /* warning conditions */
#define KERN_NOTICE "<5>" /* normal but significant condition */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */
2.控制台等级
#define MINIMUM_CONSOLE_LOGLEVEL 1 /*可以使用的最小日志级别*/
#define DEFAULT_CONSOLE_LOGLEVEL 7 /*比KERN_DEBUG 更重要的消息都被打印*/
#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
int console_printk[4] = {
DEFAULT_CONSOLE_LOGLEVEL,/*控制台日志级别,优先级高于该值的消息将在控制台显示*/
/*默认消息日志级别,printk没定义优先级时,打印这个优先级以上的消息*/
DEFAULT_MESSAGE_LOGLEVEL,
/*最小控制台日志级别,控制台日志级别可被设置的最小值(最高优先级)*/
MINIMUM_CONSOLE_LOGLEVEL,
DEFAULT_CONSOLE_LOGLEVEL,/* 默认的控制台日志级别*/
};
二、动态打印
在系统运行时候,动态打印可以由系统维护者动态打开内核子系统的打印,可以有选择性地打开某些模块的打印,而printk是 全局的,只能设置打印等级。要使用动态打印,必须在内核配置时打开CONFIG_ DYNAMIC_ _DEBUG宏。 .

p:打开动态打印语句。.
f:打印函数名
l:打印行号
m:打印模块名字
t:打印线程ID
2.1 dynamic动态打印转为printk正常打印.

三、dump_stack
对于大型驱动,想要知道某个回调函数由谁调用,非常困难。到底有没有办法知道呢?回答是肯定的,通过内核提供的接口dump_stack()可以满足要求。其实能够想到使用dump_stack()来跟踪,是根据当内核发生panic时候,也会主动调用该接口,所以我们可以在调试过程中主动调用该接口来进行测试。
四、devmem
在Linux开发中着实用到的调试工具并不是很多。devmem的方式是提供给驱动开发人员,在应用层能够侦测内存地址中的数据变化,以此来检测驱动中对内存或者相关配置的正确性验证。是应用程序通过mmap函数实现对/dev/mem驱动中mmap方法的使用,映射了设备的内存到用户空间,实现对这些物理地址的读写操作。
memdev:直接读写内存。
使用方法
devmem的使用方式:
语法: devmem ADDRESS [WIDTH [VALUE]]
ADDRESS :要直接读写的地址
WIDTH :指定读写资料的位数(8/16/32…
VALUE :要写入的资料
读
读32位: devmem 0x98000000
读16位: devmem 0x98000000 16
读8位: devmem 0x98000000 8
写
写32位: devmem 0x98000000 32 0x12345678
写16位: devmem 0x98000000 16 0x1234
写8位: devmem 0x98000000 8 0x12
参考文章:
RK3399平台开发系列讲解(内核调试篇)常用Linux内核调试手段介绍 - 视频介绍
Linux调试之(一)内核动态打印
dump_stack()使用方法
嵌入式devmem命令
边栏推荐
猜你喜欢
随机推荐
I.MX6U-ALPHA开发板(串口实验)
【OpenCV】-查找并绘制轮廓
Ali YunTianChi competition problem (machine learning) - O2O coupons prediction (complete code)
761. 特殊的二进制序列(分治)
Construction and practice of full stack code test coverage and use case discovery system
【二叉树】重建二叉树
阿里云天池大赛赛题(深度学习)——视频增强(完整代码)
Query the size of the total points obtained in a certain time period to sort
自动化测试的生命周期是什么?
2分钟,带你走完企业经营分析全流程,更有通用分析框架直接套用
sklearn(一)
【Pyspark】udf使用入门
Detailed explanation of Oracle's windowing function
HyperLynx(四)差分传输线模型
Device Reliability vs. Temperature
337. 打家劫舍 III
2022年低压电工练习题及模拟考试
提升用户体验,给你的模态弹窗加个小细节
【周赛复盘】力扣第 305 场单周赛
NanoDet代码逐行精读与修改(三)辅助训练模块AGM








