1. Buildroot 기반 임베디드 Linux의 BusyBox Init 시스템 개요 및 문제 분석
Buildroot는 리눅스 커널과 루트 파일 시스템(Rootfs)을 생성하는 강력한 빌드 시스템입니다. 임베디드 환경에서는 빠른 부팅 속도와 최소한의 리소스 사용을 위해 BusyBox Init을 기본 Init 시스템으로 채택합니다.
기존 포스팅이나 가이드에서 흔히 발생하는 주요 실수는 다음과 같습니다.
- 잘못된 init.d 호출 방식: /etc/inittab 파일 내에서 특정 서비스(/etc/init.d/my_service start)를 직접 실행하도록 지정하거나, rcS에서 수동으로 개별 서비스를 호출하는 구조적 오류가 자주 발생합니다.
- BusyBox init.d 실행 메커니즘의 오해: Buildroot의 BusyBox Init 스크립트 관리 시스템은 /etc/init.d/Sxxservice 형태의 네이밍 규칙을 기반으로 정렬하여 순차 실행합니다.
본 포스팅에서는 Buildroot 환경에서 /etc/inittab의 올바른 구문 형식, /etc/init.d/rcS의 동작 원리, 서비스 제어 스크립트 작성 가이드라인을 상세히 다룹니다.
2. Buildroot Init 시스템 핵심 설정 및 해결책 요약
- make menuconfig 경로: System configuration -> Init system -> BusyBox 지정 후 BR2_INIT_BUSYBOX 선택
- /etc/inittab에 직접 개별 서비스를 등록하지 않고, Buildroot 표준 서비스 명명 규칙인 /etc/init.d/Sxxservice (예: S99myservice)를 준수
- 서비스 관리 스크립트 내 프로세스 PID 제어 시 단순 kill 명령 대신 start-stop-daemon 유틸리티 사용
3. Buildroot BusyBox Init 시스템 및 /etc/inittab 상세 분석
3.1 Buildroot Init 시스템 옵션 비교
| Init 시스템 종류 | BR2_INIT_* 옵션 | 메인 프로세스 (PID 1) | 부팅 속도 | 특징 및 적합한 유스케이스 |
| BusyBox Init | BR2_INIT_BUSYBOX | /sbin/init | 매우 빠름 | 최소 Footprint, 초저전력 임베디드 장치 |
| systemd | BR2_INIT_SYSTEMD | /lib/systemd/systemd | 보통 | 병렬 서비스 실행, 복잡한 종속성 관리 시스템 |
| SysVinit | BR2_INIT_SYSV | /sbin/init | 보통 | 전통적인 스크립트 기반 이니셜라이저 |
| None / Custom | BR2_INIT_NONE | 커널 지정 (init=) | 가변적 | 커널 매개변수로 사용자 지정 init 앱 직접 실행 |
3.2 BusyBox inittab 구문 규칙 및 분석
BusyBox의 /etc/inittab 구문 형식은 다음과 같습니다.
id:runlevels:action:process
- id: 터미널 ID 또는 비워둠.
- runlevels: BusyBox에서는 무시됨.
- action: 실행 유형 (sysinit, respawn, askfirst, shutdown, wait, once).
- process: 실행할 바이너리 또는 스크립트 경로.
수정된 올바른 /etc/inittab 예제
# Boot-time initialization
::sysinit:/etc/init.d/rcS
::sysinit:/etc/init.d/rcK
# Console shell configuration
ttyS0::askfirst:-/bin/sh
# Stoppage and reboot action
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
3.3 /etc/init.d/rcS 스크립트 분석 및 Sxx 스크립트 정렬 구조
/etc/init.d/rcS 스크립트는 /etc/init.d/ 디렉터리 내부에서 대문자 S로 시작하고 2자리 숫자가 붙은 모든 실행 파일을 사전순으로 정렬하여 실행합니다.
#!/bin/sh
# /etc/init.d/rcS - System initialization script
for i in /etc/init.d/S??* ; do
[ -x "$i" ] || continue
case "$i" in
*.sh)
# Source shell script in current environment
. "$i"
;;
*)
# Execute script in subshell
"$i" start
;;
esac
done
4. Buildroot 서비스 스크립트 작성 가이드: start-stop-daemon 활용
Buildroot 환경에서 안정적인 데몬 관리를 위해 start-stop-daemon을 사용하는 표준 서비스 스크립트 작성법입니다.
4.1 표준 서비스 스크립트 (/etc/init.d/S90myservice) 예제
#!/bin/sh
# /etc/init.d/S90myservice - Init script for custom daemon service
DAEMON="my_service_bin"
DAEMON_PATH="/usr/bin/$DAEMON"
PIDFILE="/var/run/$DAEMON.pid"
DAEMON_ARGS="--daemonize --config /etc/myservice.conf"
start() {
printf "Starting %s: " "$DAEMON"
start-stop-daemon -S -q -m -p "$PIDFILE" -b -x "$DAEMON_PATH" -- $DAEMON_ARGS
status=$?
if [ $status -eq 0 ]; then
echo "OK"
else
echo "FAIL"
fi
return $status
}
stop() {
printf "Stopping %s: " "$DAEMON"
start-stop-daemon -K -q -p "$PIDFILE"
status=$?
if [ $status -eq 0 ]; then
rm -f "$PIDFILE"
echo "OK"
else
echo "FAIL"
fi
return $status
}
restart() {
stop
sleep 1
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
restart
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit $?
4.2 Buildroot 오버레이(Rootfs Overlay) 등록 방법
Buildroot 소스 트리 외부에 파일 시스템 변경사항을 저장하려면 BR2_ROOTFS_OVERLAY 설정을 이용합니다.
- 프로젝트 디렉터리 내에 board/company/board_name/rootfs_overlay 구조 생성.
- 타겟 경로에 맞추어 파일 배치:
- board/company/board_name/rootfs_overlay/etc/init.d/S90myservice
- make menuconfig에서 경로 설정:
- System configuration -> Root FS overlay directories -> board/company/board_name/rootfs_overlay 입력.
- 실행 권한 지정 (chmod 755 S90myservice).
5. Buildroot Init 설정 시 엔지니어가 자주 범하는 실수 및 예방책
5.1 /etc/inittab 내에 서비스 시작 구문을 직접 등록하는 오류
- 실수 사례: ::respawn:/etc/init.d/my_service start
- 문제점: inittab 내의 respawn 태그는 바이너리/프로세스를 직접 감시하기 위한 구문입니다. start 인자를 가진 쉘 스크립트를 지정하면 스크립트 실행 후 즉시 종료되어 무한 루프 상태로 스크립트가 반복 호출됩니다.
- 해결책: 백그라운드 데몬 관리는 /etc/init.d/Sxxservice 스크립트 내에서 start-stop-daemon으로 처리하고, inittab에는 단순 쉘 또는 메인 모니터링 프로세스만 지정합니다.
5.2 PID 파일 미삭제로 인한 서비스 재시작 실패
- 실수 사례: 프로세스가 비정상 종료(SIGKILL 등)되었을 때 /var/run/my_service.pid가 남아 있어 start-stop-daemon 실행이 블로킹되는 현상.
- 해결책: /var/run 디렉터리를 tmpfs로 마운트하여 부팅 시 자동으로 초기화되도록 설정하거나, 서비스 스크립트의 start() 함수 진입 시 구형 PID 파일 존재 여부를 체크 및 제거합니다.
결론
Buildroot 환경에서 올바른 Init 시스템 및 서비스 구성은 시스템의 부팅 안정성과 유지보수성에 직접적인 영향을 미칩니다. BusyBox Init 기반 구조에서는 /etc/inittab에서 /etc/init.d/rcS를 호출하고, 명명 규칙(Sxx)에 맞춰 작성된 서비스 스크립트를 start-stop-daemon으로 관리하는 것이 리눅스 표준 디자인 패턴입니다.