운영체제/리눅스

[리눅스 커널 디버깅] 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]