커널 포팅 (5. 고급 커널 포팅 및 최적화 / 5.1 부트로더 커스터마이징)

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

5.1 부트로더 커스터마이징

부트로더는 임베디드 시스템에서 커널을 로드하고 실행하는 중요한 역할을 합니다.
U-Boot을 커스터마이징하면 부팅 속도를 최적화하고, 원하는 방식으로 커널을 실행할 수 있습니다.
이 장에서는 U-Boot 환경설정, 커널 커맨드 라인(cmdline) 수정, 부팅 속도 최적화 방법을 다룹니다.


🔹 U-Boot 환경설정 (bootargs, bootcmd)

📌 1️⃣ U-Boot 환경 변수란?

U-Boot는 환경 변수(Environment Variables) 를 사용하여 부팅 설정을 관리합니다.
부팅 과정에서 가장 중요한 두 가지 변수는 다음과 같습니다.

bootargs

  • 커널에 전달되는 커맨드 라인 인자(cmdline) 를 설정하는 변수
  • 루트 파일 시스템, 콘솔 설정, 디버깅 옵션 등을 포함할 수 있음

bootcmd

  • U-Boot가 실행할 기본 부팅 명령어
  • 커널을 로드하고 실행하는 명령어를 포함

📌 2️⃣ 현재 U-Boot 환경 변수 확인

U-Boot 콘솔에서 실행:

printenv

출력 예시:

bootargs=console=ttyS0,115200 root=/dev/mmcblk0p2 rw
bootcmd=mmc dev 0; fatload mmc 0:1 0x80000000 zImage; bootz 0x80000000

📌 3️⃣ bootargs 수정

커널이 사용하는 커맨드 라인(cmdline) 인자를 설정하려면 bootargs를 수정해야 합니다.

setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rw loglevel=3 quiet
saveenv  # 변경 사항을 저장하여 재부팅 후에도 유지
  • console=ttyS0,115200 → UART 시리얼 콘솔 사용
  • root=/dev/mmcblk0p2 rw → 루트 파일 시스템을 /dev/mmcblk0p2로 설정
  • loglevel=3 → 커널 로그 레벨 조정 (불필요한 로그 출력 억제)
  • quiet → 추가적인 로그 출력을 최소화하여 부팅 속도 최적화

수정된 bootargs 확인

printenv bootargs

📌 4️⃣ bootcmd 수정

bootcmd를 설정하면, U-Boot가 자동으로 커널을 로드하고 실행할 수 있습니다.

setenv bootcmd 'mmc dev 0; fatload mmc 0:1 0x80000000 zImage; bootz 0x80000000'
saveenv  # 변경 사항을 저장하여 재부팅 후에도 유지
  • mmc dev 0 → SD 카드(0번) 선택
  • fatload mmc 0:1 0x80000000 zImage → SD 카드에서 zImage(커널)를 RAM으로 로드
  • bootz 0x80000000 → zImage 실행

설정 저장 후 재부팅

saveenv
reset
  • 재부팅 후 printenv 명령어로 변경된 설정을 확인할 수 있음

🔹 커널 커맨드 라인 수정 (cmdline 파라미터)

📌 1️⃣ 커널 커맨드라인이란?

  • 커널 부팅 시 전달되는 파라미터(cmdline)를 수정하면 부팅 동작을 조정할 수 있음
  • U-Boot의 bootargs를 수정하거나, 커널의 cmdline을 직접 변경하는 방법이 있음

📌 2️⃣ U-Boot에서 커널 커맨드라인 수정

setenv bootargs "console=ttyS0,115200 root=/dev/mmcblk0p2 rw loglevel=3 quiet"
saveenv
  • console=ttyS0,115200 → UART 출력 설정
  • root=/dev/mmcblk0p2 rw → 루트 파일 시스템 설정
  • loglevel=3 quiet → 로그 메시지를 줄여 부팅 속도 최적화

부팅 후 커널이 실제로 사용하는 cmdline 확인

cat /proc/cmdline

출력 예시:

console=ttyS0,115200 root=/dev/mmcblk0p2 rw loglevel=3 quiet

📌 3️⃣ 커널 디바이스 트리(DTS)에서 커맨드라인 설정

디바이스 트리(DTS)를 수정하여 커널 커맨드라인을 설정할 수도 있습니다.

DTS 파일 수정 (보드에 맞게 경로 확인 필요) 파일: arch/arm/boot/dts/my_board.dts

/* 사용 중인 보드에 맞게 dts 파일 경로를 확인 후 수정해야 합니다 */
chosen {
    bootargs = "console=ttyS0,115200 root=/dev/mmcblk0p2 rw loglevel=3 quiet";
};

커널 빌드 후 디바이스 트리 적용

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- dtbs
cp arch/arm/boot/dts/my_board.dtb /boot/  # 새롭게 생성된 DTB 파일을 보드에 적용

🔹 부팅 속도 최적화 (fastboot, initcall 최적화)

📌 1️⃣ U-Boot 부팅 최적화

1️⃣ 부팅 대기 시간 제거 (bootdelay=0)

setenv bootdelay 0
saveenv

2️⃣ 불필요한 U-Boot 명령어 제거 U-Boot 설정 파일(include/configs/my_board.h)에서 다음과 같은 옵션을 제거:

#undef CONFIG_CMD_USB
#undef CONFIG_CMD_NET
#undef CONFIG_CMD_DHCP

그 후 U-Boot를 다시 빌드:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-

📌 2️⃣ 커널 부팅 최적화

1️⃣ 초기 램디스크(initrd) 크기 줄이기

setenv bootargs "root=/dev/mmcblk0p2 rw initrd=0x82000000,4M"

2️⃣ 정적 드라이버 빌드 (모듈 로딩 시간 단축)

make menuconfig
# Device Drivers ---> <*> Built-in support for my driver

3️⃣ 커널 빌드

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- zImage -j$(nproc)

📌 3️⃣ Initcall 최적화

1️⃣ initcall_debug로 실행 시간 확인

setenv bootargs "console=ttyS0,115200 root=/dev/mmcblk0p2 rw initcall_debug"

2️⃣ 불필요한 initcall 제거

static int __init my_slow_init(void) {
    msleep(5000);  // 불필요한 대기 시간 제거
    return 0;
}

3️⃣ 병렬 부팅 활성화 CONFIG_CONCURRENT_BOOT 옵션은 일부 커널 버전에서만 사용 가능합니다.
대체 방법으로 initcall_debug를 사용하여 부팅 지연 원인을 확인할 수 있습니다.


✅ 정리

  1. U-Boot 환경설정
    • setenv bootargs → 커널 커맨드라인 설정
    • setenv bootcmd → 자동 부팅 설정
    • saveenv → 설정 저장
  2. 커널 커맨드라인 수정
    • /proc/cmdline 확인
    • DTS에서 bootargs 수정 가능
  3. 부팅 속도 최적화
    • bootdelay=0 → 대기 시간 제거
    • loglevel=3 quiet → 불필요한 로그 제거
    • initcall_debug로 부팅 시간 분석