본문 바로가기

Linux

Linux crash dump

Linux 커널 디버깅 및 시스템 분석 관점에서 FADump, Minidump, Kmemdump는 시스템 크래시(Crash) 발생 시 메모리 상태를 저장(덤프)하는 서로 다른 메커니즘을 의미합니다.

이들은 주로 사용되는 아키텍처(서버 vs 임베디드)덤프의 범위(전체 메모리 vs 특정 영역)에 따라 구분됩니다.


1. FADump (Firmware Assisted Dump)

설명:
FADump는 주로 IBM Power (ppc64le) 아키텍처에서 사용되는 덤프 메커니즘입니다.
기존의 kdump가 크래시 발생 시 커널 내부에서 kexec를 통해 캡처 커널을 로드하는 것과 달리, FADump는 하드웨어 펌웨어의 도움을 받습니다.
시스템이 크래시되면 펌웨어가 메모리 내용을 보존한 상태로 시스템을 완전히 리셋(Reset)하고 재부팅합니다.
이후 부팅된 새 커널이 보존된 이전 메모리 영역을 읽어 /proc/vmcore로 내보냅니다.
이 vmcore는 /proc/vmcore 인터페이스를 통해 노출되며, 보통 kdump 서비스에 의해 /var/crash 디렉토리에 파일로 저장됩니다.

  • 장점: 시스템을 완전히 리셋하므로 장치(PCI 등) 상태가 불안정한 상황에서도 kdump보다 훨씬 안정적으로 덤프를 수행할 수 있습니다.
  • 주요 대상: IBM Power Systems (Enterprise Linux).

사용 예제 (RHEL/CentOS on Power):
FADump는 커널 부트 파라미터나 sysfs를 통해 제어합니다.

  1. 설정 확인 및 등록:
  2. # FADump 지원 여부 확인 cat /sys/kernel/fadump_enabled # 1이면 활성화됨 # FADump 등록 (서비스 시작) echo 1 > /sys/kernel/fadump_registered
  3. 크래시 유발 테스트:
  4. echo c > /proc/sysrq-trigger # 시스템이 재부팅된 후 /var/crash/ 디렉토리에 vmcore가 생성되었는지 확인

출처: Linux Kernel Documentation: firmware-assisted-dump, IBM Documentation.


2. Minidump (Embedded/Android Context)

설명:
리눅스 서버 환경보다는 주로 임베디드, 안드로이드(Qualcomm 등), IoT 기기에서 사용되는 용어입니다.
서버와 달리 임베디드 기기는 저장 공간이 부족하여 RAM 전체를 덤프(Full Dump)하기 어렵습니다.
따라서 사전에 정의된 중요 메모리 영역(커널 데이터 구조체, 스택, per-cpu 데이터, 드라이버 내부 버퍼 등)만 선별하여 작게 저장하는 방식을 Minidump라고 합니다.

  • 참고: Windows의 'Minidump'와 개념은 같지만, 여기서 설명하는 것은 리눅스 커널 컨텍스트(특히 Qualcomm Minidump 등)입니다.
  • 장점: 덤프 파일 크기가 매우 작아 저장 및 전송이 용이합니다.
  • 단점: 전체 메모리가 없으므로 문제 분석에 한계가 있을 수 있습니다.

사용 예제 (개념적/Android):
일반적인 리눅스 쉘 명령보다는 칩셋 벤더의 도구(QPST 등)나 커널 드라이버를 통해 설정됩니다. 최근 리눅스 커널에서는 이를 표준화하려는 움직임이 있습니다.

/* 커널 드라이버 개발 시 (의사 코드) */
// 특정 중요 데이터 구조체만 덤프에 포함되도록 등록
qcom_minidump_region_register(&region_info);

 


3. Kmemdump (Kernel Memory Dump)

설명:
Kmemdump는 최근 몇 년간(2022년 이후) 리눅스 커널 커뮤니티(주로 Linaro/Qualcomm 주도)에서 제안된 차세대 덤프 프레임워크입니다.
기존의 Minidump 기능이 특정 벤더(Qualcomm)에 종속적인 것을 해결하기 위해, 이를 일반화(Generic)한 것입니다.
커널 모듈이나 드라이버가 "나는 이 메모리 영역이 디버깅에 중요해"라고 등록하면, 크래시 발생 시 백엔드(Minidump, pstore 등)를 통해 해당 영역만 덤프합니다.

  • 핵심: Full RAM Dump가 불가능한 장치에서 "관심 있는 영역(Region of Interest)"만 골라서 덤프하는 표준 인터페이스.
  • 관계: Kmemdump는 프론트엔드(API), Minidump는 이를 수행하는 백엔드 중 하나가 될 수 있습니다.

아키텍쳐:

  1. Provider (클라이언트 드라이버): 디버깅이 필요한 중요 데이터(변수, 로그 버퍼 등)를 가진 드라이버.
  2. Core (Kmemdump 프레임워크): 등록된 메모리 영역 리스트를 관리.
  3. Backend: 실제 크래시 발생 시 데이터를 저장할 위치 (예: SMEM, SRAM, 별도 파티션).

사용 예제 (커널 개발/패치 관점):
Kmemdump는 사용자가 명령어로 쓴다기보다, 커널 개발자가 드라이버 코드 내에 삽입합니다.

/* 드라이버 코드 내 (예시) */
#include <linux/kmemdump.h>

struct kmemdump_region my_debug_data;

// 1. 디버깅에 필요한 메모리 영역 설정
my_debug_data.name = "my_driver_log";
my_debug_data.virt_addr = log_buffer;
my_debug_data.size = 4096;

// 2. Kmemdump 시스템에 등록
kmemdump_register_region(&my_debug_data);

출처: LWN.net: introduce kmemdump, Linaro Blog.

3.1 적용 및 테스트 예제 (Kernel Module)

이 예제는 Kmemdump API가 커널에 패치되어 있다고 가정하거나, 유사한 메커니즘인 pstore/ramoops를 활용하는 방식의 개념 증명(PoC) 코드입니다.

시나리오

: "내 커널 모듈(my_critical_driver# 단계 A: 커널 모듈 코드 작성 (kmemdump_test.c`)

(참고: 실제 함수명은 커널 버전 및 패치셋에 따라 minidump_register 혹은 kmemdump_register 등으로 다를 수 있습니다. 여기서는 일반화된 API 명칭을 사용합니다.)

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
// 실제 환경에서는 해당 벤더의 헤더 필요 (예: <soc/qcom/minidump.h>)
// 표준화된 헤더가 없다면 아래 구조체는 예시입니다.

struct kmemdump_region {
    const char *name;
    u64 virt_addr;
    u64 phys_addr;
    size_t size;
    int id;
};

/* 가상의 등록 함수 (벤더 커널 API에 맞게 수정 필요) */
extern int kmemdump_region_register(struct kmemdump_region *region);

static char *critical_buffer;
static struct kmemdump_region my_region;

static int __init my_module_init(void)
{
    printk(KERN_INFO "Kmemdump Test: Module Loaded\n");

    // 1. 덤프하고 싶은 중요 메모리 할당
    critical_buffer = kmalloc(1024, GFP_KERNEL);
    if (!critical_buffer) return -ENOMEM;

    // 2. 중요 데이터 기록
    sprintf(critical_buffer, "CRITICAL_STATE: User_ID=1234, Last_Cmd=Format, Status=Panic!!");

    // 3. Kmemdump에 영역 등록
    my_region.name = "my_critical_data";
    my_region.virt_addr = (u64)critical_buffer;
    my_region.size = 1024;
    my_region.id = 10; // 고유 ID

    // 실제 등록 (심볼이 export 되어 있어야 함)
    // kmemdump_region_register(&my_region); 
    printk(KERN_INFO "Kmemdump Test: Region Registered at %llx\n", my_region.virt_addr);

    return 0;
}

static void __exit my_module_exit(void)
{
    kfree(critical_buffer);
    printk(KERN_INFO "Kmemdump Test: Module Unloaded\n");
}

module_init(my_module_init);
module_exit(my_module_exit);
MODULE_LICENSE("GPL");

빌드 및 로드

Makefile

obj-m += kmemdump_test.o
all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

 

컴파일 및 로드

make
sudo insmod kmemdump_test.ko
dmesg | tail

크래시 유발 및 확인 (테스트)

시스템을 강제로 크래시 시켜 덤프가 생성되는지 확인합니다.

# 데이터 동기화
sync

# 커널 패닉 유발 (주의: 시스템이 즉시 재부팅됩니다)
echo c | sudo tee /proc/sysrq-trigger

재부팅 후 확인:
임베디드 장비의 경우, 부트로더나 특정 파티션에서 덤프를 추출하여 ramdump 툴로 분석합니다. 등록한 my_critical_data 영역의 텍스트가 보이면 성공입니다.


 

'Linux' 카테고리의 다른 글

Linux: pstore, ramoops  (0) 2025.12.21