커널 포팅 (2. 커널 소스 분석 및 빌드 / 2.4 U-Boot과의 연동)

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

2.4 U-Boot과의 연동

U-Boot(Universal Bootloader)는 임베디드 시스템에서 널리 사용되는 부트로더로, 커널을 메모리에 로드하고 실행하는 역할을 합니다.
커널 포팅 과정에서 U-Boot을 설정하고 빌드한 후, 커널과 연동하여 부팅하는 방법을 이해하는 것이 중요합니다.


🔹 U-Boot이란 무엇인가?

U-Boot(유니버설 부트로더)는 임베디드 시스템에서 커널을 로드하고 실행하기 위한 오픈소스 부트로더입니다.
임베디드 시스템에서는 운영체제가 부팅되기 전 하드웨어 초기화 및 커널 로드가 필요하며, 이를 U-Boot이 담당합니다.

U-Boot의 역할

  1. 하드웨어 초기화:
    • CPU, RAM, 저장장치(SD 카드, eMMC, NAND/NOR 플래시) 설정
    • 주변 장치(GPIO, I2C, SPI, USB 등) 초기화
  2. 커널 로드 및 실행:
    • 커널 이미지를 로드하여 실행 (bootm, bootz 명령어 사용)
    • 디바이스 트리(DTB) 및 루트 파일 시스템(RootFS)와 함께 실행
  3. 네트워크 부팅 지원:
    • TFTP 서버를 통해 원격으로 커널 로드 (tftpboot)
  4. 명령 인터페이스 제공:
    • U-Boot 명령어를 통해 부팅 설정 수정 가능

U-Boot이 필요한 이유

  • 커널을 직접 로드하고 실행할 수 있음
  • 다양한 부팅 옵션 제공 (SD 카드, eMMC, 네트워크 부팅 등)
  • 리눅스 커널과 긴밀하게 연동 가능

U-Boot 지원 플랫폼

  • ARM (라즈베리파이, BeagleBone, FriendlyARM 등)
  • RISC-V
  • x86 (일부 보드)

🔹 U-Boot 설정 및 빌드 (make u-boot)

U-Boot을 사용하려면 소스 코드를 다운로드하고, 타겟 보드에 맞게 설정한 후 빌드해야 합니다.

1️⃣ U-Boot 소스 코드 다운로드

git clone https://source.denx.de/u-boot/u-boot.git
cd u-boot

2️⃣ 빌드 환경 설정

make distclean
  • 기존 설정을 정리하여 깨끗한 상태에서 빌드할 수 있도록 초기화

3️⃣ 타겟 보드 설정 (defconfig 적용)

make <타겟보드>_defconfig

예제:

make rpi_4_defconfig   # 라즈베리파이 4
make am335x_evm_defconfig  # BeagleBone Black
  • configs/ 디렉토리에 defconfig 파일이 있음

4️⃣ U-Boot 빌드

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j$(nproc)
  • ARCH=arm: ARM 아키텍처 지정
  • CROSS_COMPILE=arm-linux-gnueabi-: ARM 크로스 컴파일러 사용
  • -j$(nproc): CPU 코어 수만큼 병렬 빌드

5️⃣ 빌드 완료 후 생성된 파일 확인

ls -l
  • u-boot.bin → U-Boot 실행 바이너리
  • u-boot.img → 일부 보드에서 사용되는 부트 이미지

6️⃣ U-Boot 실행 (QEMU 사용)

qemu-system-arm -M versatilepb -kernel u-boot.bin -nographic
  • QEMU 환경에서 U-Boot 실행 후 명령어 입력 가능

🔹 U-Boot 환경에서 커널 실행하는 방법

U-Boot에서 커널을 로드하고 실행하는 방법은 여러 가지가 있으며, 대표적으로 SD 카드, TFTP(Network), 플래시 메모리에서 로드하는 방법이 있습니다.


📌 1️⃣ SD 카드에서 커널 로드 및 실행

U-Boot에서 SD 카드 파일 확인

mmc dev 0
fatls mmc 0:1

커널 로드 후 실행

fatload mmc 0:1 0x80000000 zImage
fatload mmc 0:1 0x82000000 bcm2711-rpi-4-b.dtb
bootz 0x80000000 - 0x82000000
  • fatload: SD 카드에서 파일 로드
  • 0x80000000: 커널을 로드할 RAM 주소
  • bootz: zImage 실행 (ARM 전용)

📌 2️⃣ TFTP(Network)에서 커널 로드 및 실행 (tftpboot)

1️⃣ U-Boot에서 네트워크 설정

setenv ipaddr 192.168.1.100    # 보드의 IP 주소 설정
setenv serverip 192.168.1.1    # TFTP 서버 IP 설정
saveenv

2️⃣ TFTP를 사용하여 커널 로드

tftpboot 0x80000000 zImage
tftpboot 0x82000000 bcm2711-rpi-4-b.dtb

3️⃣ 커널 실행

bootz 0x80000000 - 0x82000000
  • tftpboot: 네트워크를 통해 커널 다운로드
  • bootz: ARM 아키텍처에서 zImage 실행

💡 TFTP 서버 설정 (호스트 PC)

sudo apt install tftpd-hpa
sudo systemctl start tftpd-hpa
cp zImage /srv/tftp/
cp bcm2711-rpi-4-b.dtb /srv/tftp/
  • U-Boot에서 TFTP를 사용하려면 호스트 PC에 TFTP 서버가 설치되어 있어야 함

📌 3️⃣ 플래시 메모리에서 커널 실행

커널을 플래시에 저장

nand erase 0x600000 0x800000
nand write 0x80000000 0x600000 0x800000

플래시에서 커널 실행

bootm 0x600000
  • bootm: uImage 실행 (ARM, x86에서 사용 가능)

🔹 U-Boot 부팅 설정 (bootcmd 자동 실행)

U-Boot 부팅 시 매번 명령어를 입력하는 대신, 자동으로 커널을 로드하고 실행하도록 설정할 수 있습니다.

1️⃣ bootcmd 변수 설정

setenv bootcmd 'fatload mmc 0:1 0x80000000 zImage; fatload mmc 0:1 0x82000000 bcm2711-rpi-4-b.dtb; bootz 0x80000000 - 0x82000000'

2️⃣ 환경 변수 저장

saveenv

3️⃣ U-Boot 재부팅 후 자동 실행 확인

reset
  • 이제 부팅 시 자동으로 커널이 실행됨

✅ 정리

  1. U-Boot이란?
    • 임베디드 시스템에서 커널을 로드하고 실행하는 부트로더
    • 하드웨어 초기화, 부트 커맨드 설정, 네트워크 부팅 지원
  2. U-Boot 설정 및 빌드
    • make <보드명>_defconfig
    • make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
    • u-boot.bin 파일 생성 후 실행
  3. 커널 실행 방법
    • SD 카드 부팅: fatload mmc 0:1 → bootz
    • 네트워크 부팅(TFTP): tftpboot → bootz
    • 플래시 부팅: nand read → bootm
  4. 자동 부팅 설정
    • setenv bootcmd 설정 후 saveenv로 저장