운영체제/리눅스
[리눅스 커널 디버깅] 3. rpi_debugfs (rpi4 6.6.x)
IT 기술자
2025. 4. 25. 11:00
"디버깅을 통해 배우는 리눅스 커널의 구조와 원리" 책의 "3.1.2 디버깅과 코드 학습 능력"에서 소개하는 rpi_debugfs를 실습했다 .
rpi_debugfs.c 드라이버 파일 작성을 작성하여 디버깅 옵션을 준다.
rpi_debugfs.c 파일을 생성한다.
6.6.x 버전의 커널 소스에서 linux/sub_def.h 파일을 include 하면 빌드 에러가 발생하므로 주석처리한다.
root@raspberrypi:/project/linuxSrc # vi linux/drivers/soc/bcm/rpi_debugfs.c
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
//#include <linux/reboot.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/memblock.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/cpu.h>
#include <linux/delay.h>
#include <asm/setup.h>
#include <linux/input.h>
#include <linux/debugfs.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
//#include <linux/slub_def.h>
#include <linux/uaccess.h>
#include <asm/memory.h>
uint32_t raspbian_debug_state = 0x1000;
static struct dentry *rpi_kernel_debug_debugfs_root;
static int rpi_kernel_debug_stat_get(void *data, u64 *val)
{
printk("===[%s][L:%d][val:%d]===\n", __func__, __LINE__, raspbian_debug_state);
*val = raspbian_debug_state;
return 0;
}
static int rpi_kernel_debug_stat_set(void *data, u64 val)
{
raspbian_debug_state = (uint32_t)val;
printk("[raspbian] [%s][L:%d], raspbian_debug_state[%lu],value[%lu]===\n",
__func__, __LINE__, (long unsigned int)raspbian_debug_state, (long unsigned int)val);
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(rpi_kernel_debug_stat_fops, rpi_kernel_debug_stat_get, rpi_kernel_debug_stat_set, "%llu\n");
static int rpi_kernel_debug_debugfs_driver_probe(struct platform_device *pdev)
{
printk("===[%s][L:%d]===\n", __func__, __LINE__);
return 0;
}
static struct platform_driver rpi_kernel_debug_debugfs_driver = {
.probe = rpi_kernel_debug_debugfs_driver_probe,
.driver = {
.owner = THIS_MODULE,
.name = "rpi_debug",
},
};
static int __init rpi_kernel_debug_debugfs_init(void)
{
printk("===[%s][L:%d]===\n", __func__, __LINE__);
rpi_kernel_debug_debugfs_root = debugfs_create_dir("rpi_debug", NULL);
debugfs_create_file("val", S_IRUGO, rpi_kernel_debug_debugfs_root, NULL, &rpi_kernel_debug_stat_fops);
return platform_driver_register(&rpi_kernel_debug_debugfs_driver);
}
late_initcall(rpi_kernel_debug_debugfs_init);
MODULE_DESCRIPTION("raspberrypi debug interface driver");
MODULE_AUTHOR("Austin Kim <austindh.kim@gmail.com>");
MODULE_LICENSE("GPL");
Makefile 파일 수정
2행 "obj-y += rpi_debugfs.o"를 추가한다.
root@raspberrypi:/project/linuxSrc # vi linux/drivers/soc/bcm/Makefile
1 # SPDX-License-Identifier: GPL-2.0-only
2 obj-y += rpi_debugfs.o
3 obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/
빌드 -> 인스톨
커널 이미지에 포함되었는지 확인
root@raspberrypi:/project/linuxSrc # ls /sys/kernel/debug/rpi_debug/
val
rpi_debugfs 전역변수 값 확인
root@raspberrypi:/project/linuxSrc # cat /sys/kernel/debug/rpi_debug/val
4096
rpi_debugfs 전역변수 값 수정
root@raspberrypi:/project/linuxSrc # echo 825 > /sys/kernel/debug/rpi_debug/val
root@raspberrypi:/project/linuxSrc # cat /sys/kernel/debug/rpi_debug/val
825
rpi_get_interrupt_info 함수 호출을 raspbian_debug_state 값이 825일 때 실행되게 수정한다.
raspbian_debug_state 외부 변수를 선언하고, 변수가 825일 때 함수 진입
root@raspberrypi:/project/linuxSrc # vi linux/kernel/irq/proc.c
474 extern uint32_t raspbian_debug_state;
543 if (825 == raspbian_debug_state && action)
544 rpi_get_interrupt_info(action);
수정된 내용 확인
linux 디렉터리에서 확인
root@raspberrypi:/project/linuxSrc/linux # git diff
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 623b8136e..8758d3d48 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -456,6 +456,22 @@ int __weak arch_show_interrupts(struct seq_file *p, int prec)
#ifndef ACTUAL_NR_IRQS
# define ACTUAL_NR_IRQS nr_irqs
#endif
+noinline __attribute__((__used__)) void rpi_get_interrupt_info(struct irqaction *action_p)
+{
+ unsigned int irq_num = action_p->irq;
+ void *irq_handler = NULL;
+
+ if (action_p->handler) {
+ irq_handler = (void*)action_p->handler;
+ }
+
+ if (irq_handler) {
+ trace_printk("[%s] %d: %s, irq_handler: %pS \n",
+ current->comm, irq_num, action_p->name, irq_handler);
+ }
+}
+
+extern uint32_t raspbian_debug_state;
int show_interrupts(struct seq_file *p, void *v)
{
@@ -523,6 +539,10 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "-%-8s", desc->name);
action = desc->action;
+
+ if (825 == raspbian_debug_state && action)
+ rpi_get_interrupt_info(action);
+
if (action) {
seq_printf(p, " %s", action->name);
while ((action = action->next) != NULL)
빌드 -> 인스톨
rpi_debugfs 전역변수 값 확인
부팅시 4096으로 초기화된다.
root@raspberrypi:/project/linuxSrc # cat /sys/kernel/debug/rpi_debug/val
4096
1. ftrace On
2. 함수를 호출하는 명령 실행
3. ftrace Off
irq_get_interrupt_info 함수 호출 로그 확인
root@raspberrypi:/project/linuxSrc # egrep -nr rpi_get_interrupt_info ftrace_log.c
root@raspberrypi:/project/linuxSrc #
rip_degugfs 전역변수를 825로 설정
root@raspberrypi:/project/linuxSrc # echo 825 > /sys/kernel/debug/rpi_debug/val
root@raspberrypi:/project/linuxSrc # cat /sys/kernel/debug/rpi_debug/val
825
1. ftrace On
2. 함수를 호출하는 명령 실행
3. ftrace Off
irq_get_interrupt_info 함수 호출 로그 확인
root@raspberrypi:/project/linuxSrc # egrep -nr rpi_get_interrupt_info ftrace_log.c
17388: cat-835 [002] d..1. 718.675230: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17390: => rpi_get_interrupt_info+0x8/0x58
17403: cat-835 [002] d..1. 718.675246: rpi_get_interrupt_info+0x10/0x58: [cat] 9: vgic, irq_handler: vgic_maintenance_handler+0x0/0x18
17404: cat-835 [002] d..1. 718.675259: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17406: => rpi_get_interrupt_info+0x8/0x58
17419: cat-835 [002] d..1. 718.675265: rpi_get_interrupt_info+0x10/0x58: [cat] 11: arch_timer, irq_handler: arch_timer_handler_phys+0x0/0x58
17420: cat-835 [002] d..1. 718.675274: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17422: => rpi_get_interrupt_info+0x8/0x58
17435: cat-835 [002] d..1. 718.675280: rpi_get_interrupt_info+0x10/0x58: [cat] 12: kvm guest vtimer, irq_handler: kvm_arch_timer_handler+0x0/0xf0
17436: cat-835 [002] d..1. 718.675289: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17438: => rpi_get_interrupt_info+0x8/0x58
17451: cat-835 [002] d..1. 718.675294: rpi_get_interrupt_info+0x10/0x58: [cat] 14: fe00b880.mailbox, irq_handler: bcm2835_mbox_irq+0x0/0xc0
17452: cat-835 [002] d..1. 718.675303: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17454: => rpi_get_interrupt_info+0x8/0x58
17467: cat-835 [002] d..1. 718.675308: rpi_get_interrupt_info+0x10/0x58: [cat] 15: DMA IRQ, irq_handler: bcm2835_dma_callback+0x0/0x1d0
17468: cat-835 [002] d..1. 718.675319: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17470: => rpi_get_interrupt_info+0x8/0x58
17483: cat-835 [002] d..1. 718.675324: rpi_get_interrupt_info+0x10/0x58: [cat] 21: DMA IRQ, irq_handler: bcm2835_dma_callback+0x0/0x1d0
17484: cat-835 [002] d..1. 718.675331: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17486: => rpi_get_interrupt_info+0x8/0x58
17499: cat-835 [002] d..1. 718.675335: rpi_get_interrupt_info+0x10/0x58: [cat] 22: DMA IRQ, irq_handler: bcm2835_dma_callback+0x0/0x1d0
17500: cat-835 [002] d..1. 718.675346: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17502: => rpi_get_interrupt_info+0x8/0x58
17515: cat-835 [002] d..1. 718.675351: rpi_get_interrupt_info+0x10/0x58: [cat] 27: PCIe PME, irq_handler: pcie_pme_irq+0x0/0xe8
17516: cat-835 [002] d..1. 718.675360: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17518: => rpi_get_interrupt_info+0x8/0x58
17531: cat-835 [002] d..1. 718.675365: rpi_get_interrupt_info+0x10/0x58: [cat] 28: eth0, irq_handler: bcmgenet_isr0+0x0/0x190
17532: cat-835 [002] d..1. 718.675372: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17534: => rpi_get_interrupt_info+0x8/0x58
17547: cat-835 [002] d..1. 718.675377: rpi_get_interrupt_info+0x10/0x58: [cat] 29: eth0, irq_handler: bcmgenet_isr1+0x0/0x158
17548: cat-835 [002] d..1. 718.675386: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17550: => rpi_get_interrupt_info+0x8/0x58
17563: cat-835 [002] d..1. 718.675394: rpi_get_interrupt_info+0x10/0x58: [cat] 30: xhci_hcd, irq_handler: xhci_msi_irq+0x0/0x30
17564: cat-835 [002] d..1. 718.675402: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17566: => rpi_get_interrupt_info+0x8/0x58
17579: cat-835 [002] d..1. 718.675407: rpi_get_interrupt_info+0x10/0x58: [cat] 31: VCHIQ doorbell, irq_handler: vchiq_doorbell_irq+0x0/0x60
17580: cat-835 [002] d..1. 718.675414: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17582: => rpi_get_interrupt_info+0x8/0x58
17595: cat-835 [002] d..1. 718.675419: rpi_get_interrupt_info+0x10/0x58: [cat] 32: arm-pmu, irq_handler: armpmu_dispatch_irq+0x0/0x80
17596: cat-835 [002] d..1. 718.675426: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17598: => rpi_get_interrupt_info+0x8/0x58
17611: cat-835 [002] d..1. 718.675430: rpi_get_interrupt_info+0x10/0x58: [cat] 33: arm-pmu, irq_handler: armpmu_dispatch_irq+0x0/0x80
17612: cat-835 [002] d..1. 718.675436: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17614: => rpi_get_interrupt_info+0x8/0x58
17627: cat-835 [002] d..1. 718.675441: rpi_get_interrupt_info+0x10/0x58: [cat] 34: arm-pmu, irq_handler: armpmu_dispatch_irq+0x0/0x80
17628: cat-835 [002] d..1. 718.675447: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17630: => rpi_get_interrupt_info+0x8/0x58
17643: cat-835 [002] d..1. 718.675451: rpi_get_interrupt_info+0x10/0x58: [cat] 35: arm-pmu, irq_handler: armpmu_dispatch_irq+0x0/0x80
17644: cat-835 [002] d..1. 718.675459: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17646: => rpi_get_interrupt_info+0x8/0x58
17659: cat-835 [002] d..1. 718.675463: rpi_get_interrupt_info+0x10/0x58: [cat] 36: uart-pl011, irq_handler: pl011_int+0x0/0x448
17660: cat-835 [002] d..1. 718.675471: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17662: => rpi_get_interrupt_info+0x8/0x58
17675: cat-835 [002] d..1. 718.675475: rpi_get_interrupt_info+0x10/0x58: [cat] 37: mmc1, irq_handler: bcm2835_mmc_irq+0x0/0x690
17676: cat-835 [002] d..1. 718.675483: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17678: => rpi_get_interrupt_info+0x8/0x58
17691: cat-835 [002] d..1. 718.675488: rpi_get_interrupt_info+0x10/0x58: [cat] 38: v3d, irq_handler: v3d_irq+0x0/0x2f8 [v3d]
17692: cat-835 [002] d..1. 718.675496: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17694: => rpi_get_interrupt_info+0x8/0x58
17707: cat-835 [002] d..1. 718.675501: rpi_get_interrupt_info+0x10/0x58: [cat] 39: feb10000.codec, irq_handler: rpivid_irq_irq+0x0/0x128 [rpivid_hevc]
17708: cat-835 [002] d..1. 718.675508: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17710: => rpi_get_interrupt_info+0x8/0x58
17723: cat-835 [002] d..1. 718.675513: rpi_get_interrupt_info+0x10/0x58: [cat] 40: vc4 hvs, irq_handler: vc4_hvs_irq_handler+0x0/0x180 [vc4]
17724: cat-835 [002] d..1. 718.675521: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17726: => rpi_get_interrupt_info+0x8/0x58
17739: cat-835 [002] d..1. 718.675526: rpi_get_interrupt_info+0x10/0x58: [cat] 41: vc4 hdmi hpd connected, irq_handler: irq_default_primary_handler+0x0/0x18
17740: cat-835 [002] d..1. 718.675533: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17742: => rpi_get_interrupt_info+0x8/0x58
17755: cat-835 [002] d..1. 718.675537: rpi_get_interrupt_info+0x10/0x58: [cat] 42: vc4 hdmi hpd disconnected, irq_handler: irq_default_primary_handler+0x0/0x18
17756: cat-835 [002] d..1. 718.675545: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17758: => rpi_get_interrupt_info+0x8/0x58
17771: cat-835 [002] d..1. 718.675549: rpi_get_interrupt_info+0x10/0x58: [cat] 43: vc4 hdmi cec rx, irq_handler: vc4_cec_irq_handler_rx_bare+0x0/0x58 [vc4]
17772: cat-835 [002] d..1. 718.675556: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17774: => rpi_get_interrupt_info+0x8/0x58
17787: cat-835 [002] d..1. 718.675561: rpi_get_interrupt_info+0x10/0x58: [cat] 44: vc4 hdmi cec tx, irq_handler: vc4_cec_irq_handler_tx_bare+0x0/0x180 [vc4]
17788: cat-835 [002] d..1. 718.675569: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17790: => rpi_get_interrupt_info+0x8/0x58
17803: cat-835 [002] d..1. 718.675573: rpi_get_interrupt_info+0x10/0x58: [cat] 45: vc4 hdmi hpd connected, irq_handler: irq_default_primary_handler+0x0/0x18
17804: cat-835 [002] d..1. 718.675580: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17806: => rpi_get_interrupt_info+0x8/0x58
17819: cat-835 [002] d..1. 718.675585: rpi_get_interrupt_info+0x10/0x58: [cat] 46: vc4 hdmi hpd disconnected, irq_handler: irq_default_primary_handler+0x0/0x18
17820: cat-835 [002] d..1. 718.675592: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17822: => rpi_get_interrupt_info+0x8/0x58
17835: cat-835 [002] d..1. 718.675596: rpi_get_interrupt_info+0x10/0x58: [cat] 47: vc4 hdmi cec rx, irq_handler: vc4_cec_irq_handler_rx_bare+0x0/0x58 [vc4]
17836: cat-835 [002] d..1. 718.675604: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17838: => rpi_get_interrupt_info+0x8/0x58
17851: cat-835 [002] d..1. 718.675608: rpi_get_interrupt_info+0x10/0x58: [cat] 48: vc4 hdmi cec tx, irq_handler: vc4_cec_irq_handler_tx_bare+0x0/0x180 [vc4]
17852: cat-835 [002] d..1. 718.675615: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17854: => rpi_get_interrupt_info+0x8/0x58
17867: cat-835 [002] d..1. 718.675621: rpi_get_interrupt_info+0x10/0x58: [cat] 49: fe004000.txp, irq_handler: vc4_txp_interrupt+0x0/0x80 [vc4]
17868: cat-835 [002] d..1. 718.675629: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17870: => rpi_get_interrupt_info+0x8/0x58
17883: cat-835 [002] d..1. 718.675633: rpi_get_interrupt_info+0x10/0x58: [cat] 50: vc4 crtc, irq_handler: vc4_crtc_irq_handler+0x0/0x70 [vc4]
17884: cat-835 [002] d..1. 718.675640: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17886: => rpi_get_interrupt_info+0x8/0x58
17899: cat-835 [002] d..1. 718.675645: rpi_get_interrupt_info+0x10/0x58: [cat] 51: vc4 crtc, irq_handler: vc4_crtc_irq_handler+0x0/0x70 [vc4]
17900: cat-835 [002] d..1. 718.675653: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17902: => rpi_get_interrupt_info+0x8/0x58
17915: cat-835 [002] d..1. 718.675657: rpi_get_interrupt_info+0x10/0x58: [cat] 52: vc4 crtc, irq_handler: vc4_crtc_irq_handler+0x0/0x70 [vc4]
17916: cat-835 [002] d..1. 718.675664: rpi_get_interrupt_info+0x4/0x58 <-show_interrupts+0x340/0x420
17918: => rpi_get_interrupt_info+0x8/0x58
17931: cat-835 [002] d..1. 718.675668: rpi_get_interrupt_info+0x10/0x58: [cat] 53: vc4 crtc, irq_handler: vc4_crtc_irq_handler+0x0/0x70 [vc4]