u-boot

U-Boot 디버깅과 커스터마이징: UART 로그를 이용한 실전 기법

임베디드 친구 2025. 12. 10. 20:12
반응형

U-Boot 디버깅과 커스터마이징: UART 로그를 이용한 실전 기법

본 글은 RK3399 기반 시스템을 예제로 하여, U-Boot 단계에서의 디버깅과 커스터마이징 방법을 상세히 설명드립니다. 특히 UART 로그 활용, CONFIG_DEBUG_UART, CONFIG_CMD_LOG, printf 삽입 디버깅, 부트 로고 커스터마이징, boot delay 변경 등을 중심으로 살펴봅니다.


1. UART 로그 기반 디버깅의 기본 개념

U-Boot 실행은 SoC 초기화, 메모리 설정, 장치 트리 로드, 커널 부트 등 여러 단계를 거칩니다. 이때 UART 콘솔은 내부 처리 흐름을 직접 보여주는 가장 신뢰도 높은 디버깅 도구입니다.

UART 초기 동작 과정 (RK3399 기준)

  • SoC ROM → SRAM 로더 → U-Boot TPL/SPL → U-Boot 본체 순서로 실행
  • SPL 단계에서 UART 초기화가 이뤄지면 바로 콘솔 출력이 가능합니다.

UART 로그가 없다면 U-Boot 내부에서 어떤 단계에서 멈췄는지 추적하기 어렵습니다. 따라서 디버깅의 출발점은 UART 로그 확보입니다.


2. CONFIG_DEBUG_UART 활성화

CONFIG_DEBUG_UART는 UART 초기화 이전 단계에서도 디버그 메시지를 출력할 수 있도록 지원하는 옵션입니다.

설정 방법

configs/rockchip_rk3399_defconfig 또는 커스텀 defconfig 파일에 다음 항목을 추가합니다.

CONFIG_DEBUG_UART_BASE=0xFF1A0000
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_DEBUG_UART_SHIFT=2

설명

  • BASE 주소: RK3399 UART2 주소(예시)
  • CLOCK: UART 입력 클럭 설정
  • SHIFT: 레지스터 오프셋 설정

빌드

$ make rockchip_rk3399_defconfig
$ make -j8

UART 초기화 이전에도 메시지가 출력되므로 SPL 단계 문제를 추적하기에 매우 유용합니다.


3. CONFIG_CMD_LOG 활용

U-Boot에는 로그 버퍼 및 다양한 로그 레벨을 제어하는 log 명령이 존재합니다. 이를 사용하기 위해 다음 설정을 추가합니다.

CONFIG_CMD_LOG=y

활용 예제

U-Boot 콘솔에서 다음 명령을 사용할 수 있습니다.

=> log level 7
=> log show

로그 레벨 7은 디버그 전체 메시지를 표시하므로 내부 동작을 상세히 확인할 수 있습니다.


4. printf 삽입 디버깅 기법

U-Boot는 C 기반 부트로더이므로 특정 함수에 printf()를 직접 삽입하는 방식이 가장 단순하면서도 강력한 디버깅 방법입니다.

예제: 보드 초기화 코드 디버깅

board/rockchip/evb_rk3399/evb_rk3399.c 에 다음과 같이 삽입합니다.

int board_late_init(void)
{
    printf("[DBG] board_late_init() start\n");

    /* 기존 초기화 코드 */

    printf("[DBG] board_late_init() end\n");
    return 0;
}

SPL 디버깅 예제

arch/arm/mach-rockchip/spl.c:

void board_init_f(ulong dummy)
{
    printf("[SPL] board_init_f entered\n");
    ...
}

이런 방식은 디버거 없이도 코드 흐름을 추적하기에 매우 효과적입니다.


5. 부트 로고 추가: Custom Boot Logo

RK3399 U-Boot는 BMP 포맷 부트 로고를 지원합니다.

5.1 BMP 파일 준비

  • 24bit BMP 권장
  • 해상도: 1920x1080 또는 시스템 패널에 맞게 설정

5.2 경로 배치

u-boot/board/rockchip/common/logo.bmp 와 같이 위치시킵니다.

5.3 Kconfig 설정

configs/rockchip_rk3399_defconfig 수정:

CONFIG_VIDEO_LOGO=y
CONFIG_VIDEO_BMP=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SCREEN_ALIGN=y
CONFIG_BMP_24BMP=y

5.4 화면 출력 코드 변경 (선택)

common/splash.c:

splash_screen_prepare();
bmp_display(bmp_addr, 0, 0);

부팅 시 로고가 LCD 혹은 HDMI에 표시됩니다.


6. Boot Delay 변경

부팅 선택 시간을 변경하는 방법은 간단합니다.

defconfig 설정:

또는 부팅 후 환경 변수 수정:

=> setenv bootdelay 0
=> saveenv

RK3399처럼 패널 기반 시스템이라면 bootdelay가 길면 부팅 체감이 느려집니다. 제조용 기기는 일반적으로 0초 혹은 -2(자동부팅 강제)를 설정합니다.


7. 종합 정리

  • UART 로그는 부트로더의 동작 단계를 가장 명확하게 보여주는 핵심 도구입니다.
  • CONFIG_DEBUG_UART를 사용하면 초기에 멈추는 문제도 확인할 수 있습니다.
  • CONFIG_CMD_LOG는 실행 중 로그 레벨을 조정하여 상세 추적이 가능합니다.
  • printf 삽입은 가장 직접적이며 효과적인 디버깅 방법입니다.
  • Custom boot logo 및 boot delay 조정은 U-Boot 커스터마이징의 대표적인 실전 사례입니다.

결론

“디버깅 로그는 부트로더의 지도다.”

U-Boot 디버깅은 결국 로그를 어떻게 수집하고, 이해하고, 필요한 위치에 메시지를 추가하느냐에 달려 있습니다. RK3399과 같은 복잡한 플랫폼에서도 올바른 디버깅 기법을 적용하면 문제의 원인을 신속하게 파악할 수 있습니다.

반응형