u-boot

U-Boot 빌드 및 보드 포팅 준비

임베디드 친구 2025. 12. 3. 20:57
728x90
반응형

U-Boot 빌드 및 보드 포팅 준비

임베디드 시스템 개발에서 U-Boot는 부팅 초기 단계를 책임지는 핵심 소프트웨어입니다. 새로운 보드를 지원하거나 기존 보드를 수정하기 위해서는 U-Boot 포팅 과정이 필수적입니다. 본 글에서는 RK3399 기반 보드를 예시로 하여 U-Boot 포팅을 준비하는 과정과 반드시 알아야 할 핵심 요소들을 정리합니다.

1. 크로스 컴파일러 설정

U-Boot는 타겟 보드를 직접 빌드할 수 없기 때문에, 반드시 타겟 CPU 아키텍처에 맞는 크로스 컴파일러가 필요합니다. RK3399는 ARM Cortex-A72/A53 기반의 64비트 SoC이므로 aarch64용 툴체인을 사용합니다.

● 컴파일러 설치 예시

$ sudo apt install gcc-aarch64-linux-gnu

또는 Linaro Toolchain을 다운로드하여 사용할 수 있습니다.

● 환경 변수 설정 예시

$ export CROSS_COMPILE=aarch64-linux-gnu-
$ export ARCH=arm64

CROSS_COMPILE은 U-Boot 빌드시 사용되는 실제 바이너리(prefix)를 가리키므로 반드시 정확해야 합니다.

2. 타겟 보드용 defconfig 선택 및 커스터마이징

U-Boot는 Kconfig 기반 설정 시스템을 사용하며, 특정 보드를 위한 초기 설정이 defconfig로 제공됩니다. RK3399 계열 보드는 대부분 다음 위치에서 확인할 수 있습니다.

configs/rockchip_rk3399_defconfig
configs/nanopc-t4-rk3399_defconfig
configs/firefly-rk3399_defconfig

빌드 전 defconfig를 적용합니다.

$ make rockchip_rk3399_defconfig

● menuconfig를 이용한 추가 설정

$ make menuconfig

이를 통해 UART 포트, 저장장치(eMMC, SD), 네트워크, 명령어(cmd) 설정 등을 커스터마이징할 수 있습니다.

커스터마이징된 설정은 .config에 저장되고 필요하면 다시 defconfig로 변환할 수 있습니다.

$ make savedefconfig
$ cp defconfig configs/rockchip_rk3399_custom_defconfig

3. 초기 포팅 시 필요한 최소 파일 목록

새로운 보드를 지원하려면 최소한 다음의 파일/디렉토리가 준비되어야 합니다.

● include/configs/.h

보드의 기본 설정을 포함하는 핵심 헤더입니다. 메모리 맵, UART 포트, 저장장치 설정 등이 정의됩니다.

● board///

보드 초기화 루틴이 위치합니다.

  • 초기 핀 설정
  • DRAM 초기화 코드 연동
  • 전원 및 클럭 설정

● arch//cpu/

아키텍처별 공용 코드와 CPU 초기화 코드가 위치합니다. ARM64의 경우:

arch/arm/cpu/armv8/

여기에는 MMU 초기 설정, 캐시 초기화, 어셈블리 스타트업 코드가 포함됩니다.

● dts(Device Tree) 파일

RK3399처럼 SoC 기반 구조에서는 Device Tree가 매우 중요합니다.

arch/arm/dts/rk3399-myboard.dts

여기에서 보드의 전원, GPIO, PMIC, UART, I2C, SPI, eMMC 구성 등이 정의됩니다.

4. include/configs/.h 구성 예제

아래는 RK3399 기반 보드의 config 헤더 예시입니다.

#ifndef __RK3399_MYBOARD_H
#define __RK3399_MYBOARD_H

#include <configs/rk3399_common.h>

#define CONFIG_SYS_MMC_ENV_DEV 1
#define CONFIG_SYS_MMC_ENV_PART 0
#define CONFIG_ENV_SIZE 0x8000

#define CONFIG_CONSOLE_MUX
#define CONFIG_BAUDRATE 1500000

#endif

핵심은 공통 SoC 설정을 포함하고, 필요한 부분만 오버라이드하는 방식입니다.

5. board/// 구조 예제

예시 디렉토리 구조:

board/mycompany/rk3399-myboard/
 ├── Kconfig
 ├── Makefile
 ├── myboard.c
 └── MAINTAINERS

● myboard.c 기본 구조

int board_init(void)
{
    /* GPIO, PMIC, Clock 초기화 */
    return 0;
}

int board_late_init(void)
{
    /* 부팅 환경 변수 설정 등 */
    return 0;
}

이 파일은 U-Boot 실행 과정에서 보드를 인식시키는 핵심 역할을 합니다.

6. arch//cpu/ 역할

ARM64는 다음 디렉토리를 기반으로 합니다.

arch/arm/cpu/armv8/

여기에는 다음의 중요한 코드가 포함됩니다.

  • start.S : U-Boot 최초 실행 지점
  • cpu.c : CPU 초기화
  • cache.c : 캐시 설정
  • lowlevel_init

보드 포팅 시 이 부분은 크게 수정하지 않지만, 클럭이나 DRAM 초기화 코드가 SoC 벤더 SDK에 따라 연동되는 경우가 많습니다.

7. U-Boot 환경 변수 기본 설정

U-Boot 환경 변수는 디폴트 부팅 동작을 정의합니다.

예시 (RK3399 기반):

setenv bootargs "console=ttyFIQ0,1500000 root=/dev/mmcblk1p2 rw"
setenv bootcmd "mmc dev 1; fatload mmc 1:1 0x02000000 Image; fatload mmc 1:1 0x01f00000 rk3399.dtb; booti 0x02000000 - 0x01f00000"

환경 변수를 기본값으로 포함하려면 include/env_default.h 또는 보드 디렉토리의 환경 관련 코드를 사용합니다.

● defconfig 기반 환경 변수 설정

CONFIG_BOOTCOMMAND="mmc dev 1; run mmc_boot"
CONFIG_BOOTARGS="console=ttyFIQ0,1500000"

결론 요약

보드 포팅의 출발점은 defconfig와 config 헤더다.

U-Boot 포팅은 복잡해 보이지만, 사실 시작점은 명확합니다.

  1. defconfig로 기본 구조를 잡고
  2. include/configs/.h로 보드의 핵심 설정을 정의한 후
  3. board 디렉토리와 dts 파일을 통해 보드의 실제 하드웨어 구성을 반영하면 됩니다.

RK3399처럼 SoC 기반 플랫폼은 공통 코드 비중이 크므로, 기존 레퍼런스를 참고하면 훨씬 쉽게 포팅을 진행할 수 있습니다.

반응형

'u-boot' 카테고리의 다른 글

U-Boot 소스코드 구조 분석 – RK3399 기반으로 이해하기  (0) 2025.12.02
U-Boot란 무엇인가?  (0) 2025.12.01