커널 포팅 (3. 커널 포팅 기본 실습 / 3.3 부트 로그 분석 및 디버깅)

2025. 3. 6. 19:42프로그래밍/시스템

3.3 부트 로그 분석 및 디버깅

커널이 부팅될 때 어떤 단계가 실행되는지 이해하고, 부팅 실패 시 로그를 분석하는 방법을 알아야 합니다.
이 과정에서는 커널 부팅 과정의 주요 함수, 부팅 로그 분석 방법, UART(시리얼 콘솔) 활용법을 설명합니다.


🔹 커널 부팅 과정 단계별 분석

커널이 부팅될 때 실행되는 주요 함수들은 start_kernel()을 시작으로 메모리 초기화, 프로세스 생성, 드라이버 로드 등 여러 단계를 거칩니다.

1️⃣ 커널 부팅 과정 개요

start_kernel() → setup_arch() → init_IRQ() → initcall() → init_main()

2️⃣ 주요 함수 설명

함수  역할
start_kernel() 커널 부팅 시작, 시스템 초기화
setup_arch() CPU 및 하드웨어 초기화
parse_early_param() 커널 커맨드라인 파라미터 분석
init_IRQ() 인터럽트 컨트롤러 초기화
rest_init() 프로세스 생성 및 실행 (init 프로세스 실행)
init_main() 루트 파일 시스템 마운트, 사용자 공간 프로그램 실행

3️⃣ start_kernel() 함수 (커널 부팅 시작)

void __init start_kernel(void)
{
    printk(KERN_INFO "Booting Linux Kernel...\n");

    setup_arch();
    init_IRQ();
    console_init();
    rest_init();
}
  • setup_arch() → 아키텍처별 하드웨어 설정
  • init_IRQ() → 인터럽트 컨트롤러 초기화
  • console_init() → UART(시리얼 콘솔) 초기화
  • rest_init() → 첫 번째 유저 프로세스(init) 실행

4️⃣ init_main() 함수 (최종 사용자 프로세스 실행)

static int __init init_main(void *unused)
{
    do_basic_setup();
    prepare_namespace();
    run_init_process("/sbin/init");
}
  • do_basic_setup() → 드라이버 및 파일 시스템 초기화
  • prepare_namespace() → 루트 파일 시스템 마운트
  • run_init_process("/sbin/init") → /sbin/init 실행 (사용자 공간 시작)

💡 커널이 부팅되지 않으면?

  • printk()를 사용하여 어느 단계에서 멈췄는지 확인해야 함

🔹 부팅 실패 시 로그 분석하는 방법 (dmesg, printk 활용)

1️⃣ dmesg 명령어로 부팅 로그 확인

dmesg | less
  • 커널 부팅 시 출력된 로그 확인
  • grep을 사용하여 특정 키워드 필터링
dmesg | grep "error"
dmesg | grep "panic"
dmesg | grep "init"

2️⃣ printk()를 활용하여 부팅 과정 디버깅 커널 내부에서 디버깅할 때는 printk()를 사용하여 로그를 출력할 수 있음.

#include <linux/kernel.h>

printk(KERN_INFO "Custom Debug: My driver is loading...\n");
printk(KERN_ERR "Error: Device not found!\n");
  • KERN_INFO: 일반적인 정보 로그 (dmesg | grep "INFO")
  • KERN_ERR: 오류 메시지 (dmesg | grep "ERR")

3️⃣ printk() 로그 레벨

로그 레벨 설명
KERN_EMERG 긴급 메시지 (시스템 붕괴)
KERN_ALERT 즉시 조치가 필요한 경고
KERN_CRIT 치명적인 오류
KERN_ERR 일반 오류
KERN_WARNING 경고 메시지
KERN_NOTICE 중요하지 않은 정보
KERN_INFO 일반 정보 메시지
KERN_DEBUG 디버깅 정보

💡 부팅 과정에서 커널이 멈춘다면?

  • printk(KERN_INFO "Checking step X"); 등을 삽입하여 어디서 멈추는지 확인

4️⃣ 커널 패닉 분석 (Kernel Panic 로그) 부팅 실패 시 Kernel Panic이 발생할 수 있음.

dmesg | grep "panic"

예제:

Kernel panic - not syncing: Attempted to kill init!

💡 해결 방법

  • /sbin/init 실행이 실패했는지 확인 (ls /sbin/init)
  • 루트 파일 시스템이 제대로 마운트되었는지 확인

🔹 UART(시리얼 로그) 분석 및 활용

부팅 과정에서 시스템이 멈추면, 로그를 보려면 UART(시리얼 콘솔) 을 사용해야 합니다.
임베디드 시스템에서는 UART를 통해 부팅 로그를 확인하고, U-Boot 및 커널 디버깅이 가능함.

1️⃣ UART 연결 및 설정

  • UART 핀(RX, TX, GND)을 USB-시리얼 컨버터에 연결
  • minicom 또는 screen을 사용하여 UART 포트 열기

2️⃣ minicom을 사용하여 부팅 로그 확인

sudo minicom -D /dev/ttyUSB0 -b 115200
  • -D → UART 디바이스 선택 (/dev/ttyUSB0)
  • -b → 보드레이트 설정 (115200)

3️⃣ UART로 커널 부팅 로그 출력 (console=ttyS0,115200) 부트로더에서 커널 커맨드라인에 UART 출력 설정:

setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2
bootz 0x80000000 - 0x82000000

4️⃣ UART 로그 예제

Booting Linux Kernel...
CPU: ARM Cortex-A53
Memory: 1024MB
Mounting root filesystem...
Kernel panic - not syncing: No working init found!

💡 이 문제 해결 방법

  • /sbin/init 파일이 있는지 확인 (ls /sbin/init)
  • 올바른 루트 파일 시스템을 마운트하도록 bootargs 수정

5️⃣ ttyS0 또는 ttyAMA0 선택

  • x86 환경: ttyS0
  • ARM 환경: ttyAMA0 또는 ttyS0
  • 커널 커맨드라인에서 console=ttyS0,115200 또는 console=ttyAMA0,115200 설정

✅ 정리

  1. 커널 부팅 과정 분석
    • start_kernel(), init_main() 함수 확인
    • rest_init()에서 프로세스 생성 및 실행
  2. 부팅 실패 시 로그 분석
    • dmesg 및 printk() 활용
    • Kernel Panic 메시지 확인 및 디버깅
    • 루트 파일 시스템 마운트 오류 해결
  3. UART(시리얼 콘솔) 활용
    • minicom -D /dev/ttyUSB0 -b 115200으로 UART 접속
    • console=ttyS0,115200 설정 후 U-Boot에서 실행
    • UART 로그를 통해 커널 부팅 실패 원인 분석