马哥近期因为有一些需求需要在kernel中进行相关的调试验证,因为kernel开发相比fw开发还是有一些差别,所以这里记录一下kernel开发的一些调试追踪技巧差异。
kernel中加入相关日志打印调试:
如何在kernel中打印日志,类似android.util.Log一样
// 1. 直接用 printk
#include<linux/printk.h> printk(KERN_ERR "something wrong\n"); // 2. pr_xxx 宏 (不需要 dev,自动加模块名)
pr_info("power key pressed\n"); // 输出: <6>qpnp-power-on: power key pressed pr_err("something failed\n"); pr_debug("debug info\n"); // 3. dev_xxx (需要 dev)
dev_info(dev, "power key pressed\n"); dev_err(dev, "something failed\n"); dev_dbg(dev, "debug info\n"); 抓取方式:logcat -b all 或者logcat -b kernel
kernel中加入相关的堆栈打印
如何在kernel中追踪一些方法的调用栈,可以和我们framework堆栈追踪一样简单?
#include<linux/printk.h> //引入头文件 dump_stack();可以看看下面是power键案例
0 0 I Call trace: 0 0 I : [<000000004d1d622f>] dump_backtrace+0x0/0x41c 0 0 I : [<00000000422c8119>] show_stack+0x14/0x1c 0 0 I : [<00000000d01c0dc6>] dump_stack+0xc4/0xfc 0 0 I : [<00000000554b8d0a>] qpnp_kpdpwr_irq+0x34/0x1b8 0 0 I : [<0000000053294c6d>] __handle_irq_event_percpu+0x10c/0x2a4 0 0 I : [<000000000f0fb616>] handle_irq_event+0x54/0xc0 0 0 I : [<000000003d3e783c>] handle_edge_irq+0xc8/0x188 0 0 I : [<00000000c64e8964>] generic_handle_irq+0x24/0x3c 0 0 I : [<00000000463cc320>] periph_interrupt+0x74/0x114 0 0 I : [<000000003078d434>] pmic_arb_chained_irq+0x13c/0x228 0 0 I : [<00000000b02011aa>] __handle_domain_irq+0x7c/0xbc 0 0 I : [<000000001323b657>] gic_handle_irq+0xf8/0x198 0 0 I : Exception stack(0xffffff8e6f203d00 to 0xffffff8e6f203e30) 0 0 I 3d00 : fffffff70b947632 00000000000001c0 0000000000000001 0000000000000001 0 0 I 3d20 : 00000008f46b85f0 0000000000000001 00000000000006a0 0000000001312d00 0 0 I 3d40 : 0000000000000000 0000000000000001 0018701a7711de00 0000000034155555 0 0 I 3d60 : 0000000000000018 0000000000001b0a 0000000000000000 000000000000009c 0 0 I 3d80 : 0000000000049959 00000000000003d1 0000000000000004 0000000000000000 0 0 I 3da0 : ffffffc26c1b6018 ffffff8e6ec9ba90 000000340e8ca000 ffffff8e6f330000 0 0 I 3dc0 : 0000000000000000 000000000000003b ffffff8e6ec9ba48 ffffffc27d565a50 0 0 I 3de0 : ffffff8e6f221900 ffffff8e6f203e40 ffffff8e6d957ec4 ffffff8e6f203e30 0 0 I 3e00 : ffffff8e6d957f00 00000000a0c00145 000000340e8ca000 ffffff8e6ec9ba90 0 0 I 3e20 : ffffffffffffffff 0000000000000000 0 0 I : [<00000000a7ce830f>] el1_irq+0xe8/0x18c 0 0 I : [<000000001cdfc47a>] lpm_cpuidle_enter+0x46c/0x4b0 0 0 I : [<0000000029da8379>] cpuidle_enter_state+0x1ac/0x31c 0 0 I : [<0000000093efd304>] cpuidle_enter+0x18/0x20 0 0 I : [<00000000a609a1d9>] cpu_startup_entry+0x164/0x1f4 0 0 I : [<0000000021dd2f61>] rest_init+0x7c/0x88 0 0 I : [<000000005a292c16>] start_kernel+0x440/0x4c0 0 0 I : [<00000000e3d213b3>] __primary_switched+0x64/0x90kernel中添加相关的perfetto的trace
+++ b/drivers/input/evdev.c@@ -26,6 +26,7 @@#include<linux/major.h>#include<linux/device.h>#include<linux/cdev.h>+#include<trace/events/input.h>#include"input-compat.h"enum evdev_clock_type {@@ -306,6 +307,8 @@ staticvoidevdev_events(struct input_handle *handle, struct evdev_client *client;ktime_t ev_time[EV_CLK_MAX];+ INPUT_ATRACE_BEGIN("evdev_deliver");+ ev_time[EV_CLK_MONO] = ktime_get(); ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]); ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO],@@ -322,6 +325,8 @@ staticvoid evdev_events(struct input_handle *handle, evdev_pass_values(client, vals, count, ev_time); rcu_read_unlock();++ INPUT_ATRACE_END("evdev_deliver"); }主要就是 1、#include相关的头文件 <trace/events/input.h>
2、INPUT_ATRACE_BEGIN("evdev_deliver");
实际上最后也是调用trace_tracing_mark_write kernel/xiaomi/sdm710/include/trace/events/input.h
/* * Convenience wrappers — use these in driver code. * * Usage in ISR: * INPUT_ATRACE_BEGIN("input_irq"); * ... handle interrupt, call input_report_* / input_sync ... * INPUT_ATRACE_END("input_irq"); */#define INPUT_ATRACE_BEGIN(name) \ trace_tracing_mark_write(current->tgid, name, 1)#define INPUT_ATRACE_END(name) \ trace_tracing_mark_write(current->tgid, name, 0)添加相关的log
编译命令kernel相关img的:
make bootimage重启进入fastboot模式
adb reboot bootloader
刷入对应的boot.img
fastboot flash boot out/target/product/grus/boot.imgSending 'boot' (131072 KB) OKAY [ 2.997s]Writing 'boot' OKAY [ 0.640s]Finished. Total time: 3.734s然后再进行重启:
fastboot rebootRebooting OKAY [ 0.000s]Finished. Total time: 0.401s更多vip面试定制指导上岸fw工程师服务,课程优惠购买成为vip学员进入vip群,积极讨论各种行业难点痛点疑难问题,答疑服务等。
请联系马哥微信:

夜雨聆风