임베디드 시스템을 개발하거나 유지보수할 때 부팅 프로세스를 정확히 이해하는 것은 시스템 안정성을 확보하고 성능을 최적화하는 첫걸음입니다. 전원이 켜지는 순간부터 사용자 애플리케이션이 실행되기까지, 보이지 않는 곳에서 여러 소프트웨어 모듈이 긴밀하게 상호작용합니다. 디버깅 효율을 높이고 부팅 시간을 단축하기 위해 필수적으로 알아야 할 임베디드 리눅스 부트 프로세스의 핵심 구조와 단계별 역할을 정리했습니다.

핵심 요약 3줄
- 임베디드 리눅스 부팅은 Boot ROM, U-Boot(부트로더), Kernel, Rootfs 단계로 순차적으로 진행됩니다.
- 부트로더는 하드웨어를 초기화하고 커널 이미지와 디바이스 트리를 메모리에 로드하는 핵심 역할을 합니다.
- 커널이 정상적으로 구동된 후 Rootfs를 마운트하고 init 프로세스를 실행해야 최종 사용자 환경이 완성됩니다.
임베디드 리눅스 부트 프로세스 개요
임베디드 리눅스 시스템의 부팅은 전원 공급 후 시스템이 운영체제를 로드하고 제어권을 넘겨주기까지의 연속적인 과정입니다. 전체적인 흐름을 직관적으로 이해하기 위해 각 단계의 핵심 역할을 아래 표로 정리했습니다.
| 부팅 단계 | 주요 역할 | 구동 위치 | 주요 출력 예시 |
| Boot ROM | 1차 부트로더(SPL) 로드 및 초기 하드웨어 스캔 | SoC 내부 ROM | 부트 소스(eMMC, SD카드) 탐색 로그 |
| U-Boot (SPL/Main) | 하드웨어 전반 초기화, 커널 및 디바이스 트리 로드 | SRAM / DRAM | U-Boot SPL 2023.01 ..., DRAM: 4 GiB |
| Linux Kernel | 메모리/디바이스 드라이버 초기화, Rootfs 마운트 | DRAM | Booting Linux on physical CPU ... |
| Root Filesystem | init 프로세스 실행 및 사용자 애플리케이션 구동 | Storage (eMMC 등) | init: Starting system initialization |
부팅 단계별 상세 분석
1. Boot ROM 단계
SoC(System on Chip) 내부에 단단히 새겨진 코드가 가장 먼저 실행되는 단계입니다. 하드웨어적으로 고정된 영역이므로 수정이 불가능합니다.
- 부트 소스 탐색: eMMC, SD 카드, SPI Flash 등 사전에 정의된 순서에 따라 부팅 매체를 스캔합니다.
- 부트로더 로드: 발견된 부트 소스에서 다음 단계 소프트웨어인 U-Boot의 1차 부트로더(SPL)를 내부 SRAM으로 읽어와 실행합니다.
2. U-Boot (Bootloader) 단계
임베디드 리눅스에서 널리 쓰이는 U-Boot는 시스템 리소스가 제한적인 상황을 고려해 대개 두 단계로 나누어 동작합니다.
- 1차 부트로더 (SPL): 크기가 작은 내부 SRAM에서 실행되며, DRAM 컨트롤러를 초기화하여 시스템 메모리를 사용할 수 있도록 준비합니다. 이후 메인 부트로더를 DRAM으로 로드합니다.
- 2차 부트로더 (Main): 전체 하드웨어를 초기화하고, 커널 이미지와 디바이스 트리(Device Tree)를 메모리에 올린 뒤 부팅 인자(bootargs)를 커널에 전달합니다.
# U-Boot 환경 변수 및 부팅 명령 예시
=> printenv
=> setenv bootargs "console=ttyFIQ0 root=/dev/mmcblk0p1 rw rootwait"
=> bootm 0x00200000
# U-Boot 실행 로그 예시
U-Boot SPL 2023.01 (Jan 16 2025 - 15:00:00)
Trying to boot from MMC1
U-Boot 2023.01 (Jan 16 2025 - 15:00:00 +0800)
CPU: Core Architecture
DRAM: 4 GiB
Loading kernel from 0x00200000...
Booting kernel at 0x00208000 with device tree at 0x01f00000...
3. Linux Kernel 단계
부트로더로부터 제어권을 넘겨받은 커널은 운영체제의 핵심 기능을 활성화합니다.
- 하드웨어 서브시스템 초기화: 가상 메모리, 인터럽트, 타이머 등을 설정하고 디바이스 트리 정보를 바탕으로 각 주변 장치의 드라이버를 로드합니다.
- 스토리지 연결: 시스템 구성에 명시된 파일 시스템(Rootfs)을 찾아 마운트를 시도합니다.
# 커널 구동 로그 예시
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 5.15.0 (user@buildserver) (gcc version 9.3.0)
[ 0.000000] Initializing cgroup subsys memory
[ 1.000000] VFS: Mounted root (ext4 filesystem) on device 179:1.
4. Root Filesystem (Rootfs) 단계
커널 초기화가 끝나면 사용자 공간(User Space)의 첫 번째 프로세스인 init을 실행합니다.
- 시스템 초기화 스크립트 실행: 네트워크 설정, 주요 서비스 및 데몬을 구동합니다.
- 사용자 환경 제공: 최종적으로 개발자가 작성한 애플리케이션이나 셸 환경을 화면에 띄우며 부팅을 마무리합니다.
# Rootfs 진입 후 init 프로세스 로그 예시
[ 2.000000] init: Starting system initialization
[ 2.100000] init: Loading user applications...
[ 2.500000] systemd[1]: Started target Basic System.
개발을 위한 팁
- U-Boot 콘솔 활용: 부팅 과정에서 문제가 발생하면 즉시 U-Boot 콘솔에 진입하여 printenv로 환경 변수를 점검해야 합니다. 특히 bootargs 세팅이 잘못되면 커널은 뜨더라도 Rootfs를 찾지 못하는 상황이 발생합니다.
- 부팅 시간 단축(Fast Boot): 양산형 장비에서는 U-Boot의 부트 딜레이 타임아웃을 0초로 설정하고, 커널 로그 출력을 최소화(quiet 옵션 사용)하는 것만으로도 수 초 이상의 부팅 시간을 줄일 수 있습니다.
- 디바이스 트리 분리 관리: 하드웨어 핀 맵이나 주변 장치가 변경될 때 커널 코드를 매번 수정하기보다는 디바이스 트리(DTS) 파일만 독립적으로 수정하여 컴파일하는 것이 유지보수에 유리합니다.
흔히 하는 실수
- Panic: Unable to mount root fs: 커널은 정상적으로 뜨는데 이 에러 플래그와 함께 멈춘다면 십중팔구 bootargs에 지정한 스토리지 경로(/dev/mmcblk0p1 등)가 잘못되었거나, 커널 빌드 시 해당 스토리지 파일 시스템(ext4 등) 드라이버를 내장(Built-in)하지 않고 모듈로 빌드했기 때문입니다.
- DRAM 초기화 실패로 인한 무한 리부팅: SPL 단계에서 메모리 타이밍 설정이 맞지 않으면 메인 U-Boot로 넘어가지 못하고 하드웨어 워치독에 의해 무한 루프에 빠질 수 있습니다. 보드 변경 시 반드시 메모리 파라미터를 먼저 검증해야 합니다.
- 전압 불안정으로 인한 부팅 커널 다운: 부팅 시 시스템 소모 전류가 급격히 상승합니다. 전원 공급 장치의 용량이 부족하면 커널 로드 직후 주변 장치들이 켜질 때 전압 강하가 일어나 시스템이 먹통이 되기도 하므로 하드웨어 환경도 함께 살펴야 합니다.
결론
임베디드 리눅스의 부팅 과정은 각 단계가 이전 단계의 결과물에 의존하는 유기적인 구조를 띱니다. Boot ROM이 길을 열고, U-Boot가 징검다리를 놓으면, 커널과 Rootfs가 비로소 무대를 완성하는 흐름입니다. 이 전체 구조를 머릿속에 넣어두면 앞으로 시스템 다운이나 커널 패닉 같은 까다로운 디버깅 상황을 마주하더라도 어느 단계를 먼저 파헤쳐야 할지 명확한 기준을 잡을 수 있습니다.
'Embedded System > Linux Kernel & Device Drivers' 카테고리의 다른 글
| 임베디드 리눅스 BSP 개념과 개발 공정: 수정부터 신규 작성까지 (0) | 2025.03.12 |
|---|---|
| 임베디드 리눅스 커널 포팅 절차 총정리: 환경 구축부터 빌드까지 (0) | 2025.03.11 |
| 임베디드 리눅스 디바이스 트리(Device Tree) 구조와 작성법 총정리 (0) | 2025.03.10 |
| ARM64 임베디드 리눅스 커널 빌드 환경 구축 및 컴파일 실무 (0) | 2025.03.08 |
| 임베디드 리눅스 커널 구조 이해와 ARM64 빌드 실무 가이드 (0) | 2025.03.07 |