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=arm64CROSS_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_defconfig3. 초기 포팅 시 필요한 최소 파일 목록
새로운 보드를 지원하려면 최소한 다음의 파일/디렉토리가 준비되어야 합니다.
● 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 포팅은 복잡해 보이지만, 사실 시작점은 명확합니다.
- defconfig로 기본 구조를 잡고
- include/configs/
.h로 보드의 핵심 설정을 정의한 후 - board 디렉토리와 dts 파일을 통해 보드의 실제 하드웨어 구성을 반영하면 됩니다.
RK3399처럼 SoC 기반 플랫폼은 공통 코드 비중이 크므로, 기존 레퍼런스를 참고하면 훨씬 쉽게 포팅을 진행할 수 있습니다.
'u-boot' 카테고리의 다른 글
| U-Boot 소스코드 구조 분석 – RK3399 기반으로 이해하기 (0) | 2025.12.02 |
|---|---|
| U-Boot란 무엇인가? (0) | 2025.12.01 |