u-boot

U-Boot 환경 변수와 스크립트 완전 정복(Rockchip RK3399 기반)

임베디드 친구 2025. 12. 8. 19:33
반응형

U-Boot 환경 변수와 스크립트 완전 정복(Rockchip RK3399 기반)

U-Boot은 임베디드 리눅스 시스템에서 널리 사용되는 부트로더이며, 커널 로딩, 장치 초기화, 펌웨어 업데이트 등 다양한 기능을 수행합니다. 이 과정에서 환경 변수(environment variable)는 시스템의 동작을 결정하는 핵심 요소로 작동합니다. 이번 글에서는 환경 변수의 구조, 저장 위치, 설정 및 관리 방법, 그리고 자동화 스크립트 예제를 Rockchip RK3399 기반 시스템을 중심으로 자세히 설명드리겠습니다.


1. U-Boot 환경 변수 개요

U-Boot 환경 변수는 다음과 같은 항목들로 구성됩니다.

  • bootcmd
  • bootargs
  • bootdelay
  • 커널 및 DTB 로딩 주소(kernel_addr, fdt_addr 등)
  • 자동 업데이트 스크립트 관련 변수

U-Boot 부팅 시 환경 변수는 RAM으로 로딩되며, 필요에 따라 수정, 저장, 실행이 가능합니다.


2. 환경 변수 저장 위치 및 관리 방식

2.1 RAM 환경 변수

U-Boot가 동작하는 동안 환경 변수는 RAM에서 관리됩니다.
setenv로 값을 수정하면 즉시 RAM 상에서 적용되지만, 전원을 끄면 사라지므로 영구적으로 유지하려면 저장 장치에 기록해야 합니다.

2.2 Flash / eMMC 환경 변수

RK3399 기반 보드에서는 eMMC 또는 SPI NOR Flash에 환경 변수를 저장하는 방식이 일반적입니다.
보드 설정 파일에는 다음과 같은 환경 변수 저장 설정이 포함됩니다.

#define CONFIG_ENV_IS_IN_MMC
#define CONFIG_ENV_OFFSET    0x40000
#define CONFIG_ENV_SIZE      0x20000
  • 저장 장치: eMMC
  • 환경 변수 오프셋: 0x40000
  • 크기: 0x20000

환경 변수를 영구 저장하려면 다음 명령을 사용합니다.

=> env save

3. 환경 변수 설정과 스크립트 자동 실행

U-Boot는 부팅 시 특정 환경 변수에 따라 자동으로 스크립트를 실행할 수 있습니다.
그 대표적인 것이 bootcmd 입니다.

3.1 bootargs 설정

커널에 전달할 인자를 지정합니다.

=> setenv bootargs "console=ttyS2,1500000 root=/dev/mmcblk0p5 rw rootwait"

3.2 bootcmd 설정

RK3399 기준 커널과 DTB 파일을 로드한 뒤 부팅하는 기본적인 bootcmd 예시는 다음과 같습니다.

=> setenv bootcmd 'mmc dev 0; fatload mmc 0:1 0x02000000 Image; fatload mmc 0:1 0x01f00000 rk3399.dtb; booti 0x02000000 - 0x01f00000'
=> env save

U-Boot는 다음 부팅부터 위 스크립트를 자동 실행합니다.


4. env 관련 명령 실습

4.1 printenv

현재 환경 변수 목록 출력:

=> printenv

예시 출력:

bootcmd=mmc dev 0; fatload mmc 0:1 0x02000000 Image; fatload mmc 0:1 0x01f00000 rk3399.dtb; booti 0x02000000 - 0x01f00000
bootargs=console=ttyS2,1500000 root=/dev/mmcblk0p5 rw rootwait

4.2 setenv

환경 변수 값 설정:

=> setenv bootdelay 1
=> setenv upgrade_flag 0

4.3 env save

RAM의 변경 내용을 Flash 또는 eMMC에 저장:

=> env save

4.4 env default

환경 변수를 기본(factory) 값으로 초기화:

=> env default -a
=> env save

5. 부팅 자동화 스크립트 예제

5.1 커널 자동 부팅 스크립트 (RK3399)

=> setenv bootcmd 'mmc dev 0; ext4load mmc 0:1 0x02000000 /boot/Image; ext4load mmc 0:1 0x01f00000 /boot/rk3399.dtb; booti 0x02000000 - 0x01f00000'
=> env save

전원 인가 시 다음 작업이 자동으로 수행됩니다.

  1. eMMC 0번 장치 선택
  2. 커널 이미지 로드
  3. DTB 로드
  4. booti로 커널 실행

5.2 펌웨어 자동 업데이트 스크립트 예제

업데이트 플래그 설정:

=> setenv upgrade_flag 1
=> env save

bootcmd 수정:

setenv bootcmd '
if test "${upgrade_flag}" = "1"; then
    echo Starting firmware update;
    usb start;
    fatload usb 0:1 0x20000000 update.img;
    run update_script;
else
    mmc dev 0;
    ext4load mmc 0:1 0x02000000 /boot/Image;
    ext4load mmc 0:1 0x01f00000 /boot/rk3399.dtb;
    booti 0x02000000 - 0x01f00000;
fi'

update_script 정의:

=> setenv update_script 'echo Writing firmware; mmc write 0x20000000 0x8000 0x1000; echo Update done; setenv upgrade_flag 0; env save'

이제 재부팅하면 U-Boot가 업데이트 이미지 로드 후 자동으로 펌웨어를 갱신합니다.


6. 결론

U-Boot 환경 변수는 단순한 설정값을 넘어 시스템의 행동 전체를 규정하는 핵심 요소입니다.

  • 환경 변수는 RAM에서 수정되고 Flash/eMMC에 저장
  • bootcmd는 U-Boot의 메인 스크립트로 자동 실행됨
  • bootargs는 커널에 전달하는 중요한 인자
  • printenv, setenv, env save 등을 통해 환경을 효율적으로 관리 가능
  • 자동 부팅, 자동 업데이트 등 고급 기능도 환경 변수 기반으로 구성 가능

결론: U-Boot 환경 변수는 시스템의 행동을 지배한다.

반응형