임베디드 리눅스 시스템 개발에서 커널 설정(Kernel Configuration)은 제품의 성패를 가르는 가장 중요한 공정 중 하나입니다. 범용 PC 환경과 달리 임베디드 환경은 메모리와 스토리지 용량이 제한적이며 전력 소비에도 민감합니다. 시스템에 불필요한 드라이버와 기능을 제거하고, 타깃 보드에 꼭 필요한 하드웨어 가속 및 파일 시스템 옵션만 정밀하게 골라내어 가볍고 안정적인 맞춤형 커널 뼈대(.config)를 구축하는 방법을 상세히 살펴보겠습니다.

핵심 요약 3줄
- 커널 설정은 타깃 시스템의 요구사항에 맞춰 필요한 드라이버와 기능을 선택하고 메인 설정 파일인 .config를 생성하는 과정입니다.
- 터미널 기반의 텍스트 인터페이스인 menuconfig를 활용하면 시스템 유형, 전원 관리, 파일 시스템, 네트워크 옵션을 직관적으로 제어할 수 있습니다.
- 최적화가 완료된 설정은 savedefconfig 명령을 통해 경량화된 기본 설정 파일로 백업하여 지속적인 유지보수에 활용합니다.
1. 리눅스 커널 설정의 기본 개념과 접근 방법
리눅스 커널은 수많은 하드웨어를 지원할 수 있도록 방대한 소스코드로 이루어져 있습니다. 커널 설정 단계는 이 거대한 소스코드 중에서 '이번 빌드에 어떤 부분을 포함할 것인가'를 결정하는 작업입니다. 개발자는 각 기능의 빌드 방식을 크게 세 가지 상태로 정의할 수 있습니다.
| 설정 상태 (State) | 기호 | 동작 방식 및 커널 포함 여부 | 비고 |
| Built-in (내장) | [*] 또는 <*> | 커널 메인 실행 이미지(Image) 내부에 코드를 직접 통합 | 부팅 시 즉시 로드, 필수 드라이버에 지정 |
| Module (모듈) | <M> | 커널 외부에 독립된 파일(.ko)로 빌드하여 런타임에 동적 로드 | 스토리지 용량 절감, 필요할 때만 로드 |
| Exclude (제외) | [ ] 또는 < > | 빌드 대상에서 완전히 제외하여 컴파일조차 하지 않음 | 커널 바이너리 크기 최소화 |
설정을 조율하는 도구 역시 개발 환경에 따라 다양하게 제공됩니다.
| 설정 도구명 | 구동 환경 | 특징 및 장단점 |
| menuconfig | 텍스트 사용자 인터페이스 (TUI) | 원격 서버(SSH) 환경에서도 별도의 그래픽 설정 없이 컴파일러 의존성만 갖추면 즉시 실행 가능하여 가장 널리 쓰임 |
| xconfig | 그래픽 사용자 인터페이스 (GUI) | 호스트 PC의 X-Window 환경에서 마우스 클릭으로 편리하게 설정할 수 있으나 Qt 라이브러리 등 사전 패키지 설치 필요 |
| defconfig | 텍스트 구성 파일 수동 로드 | 칩셋 제조사가 미리 검증해 둔 보드 전용 디폴트 설정 값을 가져와 커널 구성의 시작점으로 활용 |
2. 개발 환경 구축 및 소스코드 준비
크로스 컴파일러를 호스트 PC에 배치하고 타깃 프로세서 아키텍처에 맞는 기본 구성 파일 체계를 확보하는 사전 단계입니다.
1단계: 크로스 툴체인(Cross-Toolchain) 배치
호스트 PC 환경에서 타깃 보드용 64비트 ARM 바이너리를 찍어낼 수 있도록 크로스 컴파일러를 설치하고 환경 변수(PATH)에 경로를 등록합니다.
# 툴체인 압축 해제 및 시스템 경로 등록 예시
tar -xvf gcc-linaro-*.tar.xz -C /opt/
echo "export PATH=/opt/gcc-linaro/bin:$PATH" >> ~/.bashrc
source ~/.bashrc
2단계: 소스코드 준비 및 초기화
제조사 안정화 브랜치의 커널 소스코드를 클론한 뒤, 타깃 프로세서 구조에 맞는 표준 기본 설정 파일(defconfig)을 아키텍처 환경 변수와 함께 호출하여 초기 .config 파일을 생성합니다.
# 커널 저장소 다운로드 및 이동
git clone https://github.com/linux-development/kernel.git rk_kernel
cd rk_kernel
# 대상 아키텍처 명시 후 제조사 제공 기본 세팅 파일 로드
make ARCH=arm64 **********_defconfig
3. 임베디드 최적화를 위한 핵심 커널 설정 조정
기본 세팅을 불러왔다면 이제 시스템 설계 요구사항에 맞춰 튜닝을 진행할 차례입니다. 터미널 창에 make ARCH=arm64 menuconfig 명령을 입력하면 키보드 방향키로 탐색할 수 있는 메뉴 화면이 나타납니다.
임베디드 타깃 맞춤형 추천 설정 항목
| 대분류 메뉴 | 세부 튜닝 경로 및 타깃 옵션 명칭 | 활성화 목적 및 최적화 효과 |
| System Type | System Type ---> CPU Features ---> Core Architecture 선택 | ARM Cortex 대형/소형 멀티코어 아키텍처 연산 성능 극대화 |
| Power Management | Power management options ---> Suspend to RAM / Hibernate | 장비 대기 상태에서의 소모 전류 최소화 및 절전 모드 구현 |
| File Systems | File systems ---> Extended 4 (ext4) & SquashFS 4.0 | 시스템 루트 영역 마운트 및 읽기 전용 압축 파일 시스템 지원 |
| Networking | Networking support ---> Networking options ---> IPv6 protocol | 사물인터넷(IoT) 장비 연동 및 표준 네트워크 스택 확보 |
| Device Drivers | Device Drivers ---> Graphics support ---> DRM support | 디스플레이 출력 및 내장 그래픽 아키텍처 하드웨어 가속 활성화 |
주요 메뉴 진입 매핑 예시
# 파일 시스템 진입 설정 예시
File systems --->
<*> The Extended 4 (ext4) filesystem
<*> SquashFS 4.0 - Squashed file system support
# 네트워크 옵션 진입 설정 예시
Networking support --->
<*> Networking options --->
[*] IPv6 protocol
설정 도구 내에서 작업을 마치고 <Save>를 선택하면 현재 디렉토리에 최종 컴파일 지침서 역할을 하는 .config 파일이 저장됩니다.
4. 커널 빌드 및 스토리지 배포 프로세스
설정 파일 조율이 끝났다면 컴파일러를 구동하여 최종 커널 실행 바이너리 이미지를 추출하고 이를 타깃 스토리지 미디어로 이전합니다.
1단계: 미니멀 파일 백업 (savedefconfig)
현재 세팅된 수백 수천 가지의 옵션 중 디폴트 값과 달라진 '핵심 변경 내역'만 골라내어 가벼운 백업 파일인 defconfig로 추출합니다. 이 작업을 해두면 나중에 소스코드가 더러워져도 언제든 설정을 온전하게 복원할 수 있습니다.
make ARCH=arm64 savedefconfig
2단계: 크로스 컴파일 수행
호스트 컴파일러 연산 스레드 개수(nproc)를 총동원하여 병렬 컴파일을 진행합니다.
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
컴파일 완료 시 아키텍처 출력 폴더 내부인 arch/arm64/boot/Image 경로에 압축되지 않은 순수 커널 실행 바이너리가 생성됩니다.
3단계: 타깃 보드 배포 및 부팅 검증
추출된 이미지를 타깃 보드의 부팅 파티션 블록 영역에 로우 레벨로 기록하거나 파일 시스템 내에 복사한 후 장비를 리부팅하여 새로 빌드된 커널 버전 정보가 커널 로그 시스템에 정상적으로 적재되었는지 교차 검증합니다.
# 부트 영역 기록
sudo dd if=arch/arm64/boot/Image of=/dev/mmcblk0p1 bs=4M
sync
# 보드 부팅 후 셸 터미널에서 구동 확인
dmesg | grep Linux
개발을 위한 팁
- /proc/config.gz 기능의 활성화: 커널 설정 시 General setup ---> Kernel .config support 옵션을 체크해두면, 양산 배포 후 가동 중인 타깃 보드 내부에서 zcat /proc/config.gz 명령을 실행해 현재 보드에 적용된 커널 옵션을 실시간으로 역추적할 수 있어 디버깅에 매우 유리합니다.
- 검색 기능(/)의 적극적인 활용: menuconfig 화면에서 키보드의 슬래시(/) 키를 누르면 찾고자 하는 드라이버 매크로 이름(예: DRM_ROCKCHIP)을 검색할 수 있습니다. 해당 드라이버가 속한 상위 메뉴 경로와 활성화를 위해 선행되어야 하는 의존성(Depends on) 목록까지 한눈에 보여주므로 메뉴를 헤매는 시간을 줄여줍니다.
- 증분 빌드 활용: 커널 설정을 한두 개 바꾼 후 다시 빌드할 때 make clean을 매번 돌릴 필요가 없습니다. 변경된 옵션과 연관된 소스코드만 선별적으로 컴파일되므로 변경 후 곧바로 make 명령을 내리면 시간을 대폭 아낄 수 있습니다.
흔히 하는 실수
- 의존성 설정을 무시한 드라이버 탐색: 특정 주변 장치 드라이버를 켜고 싶어서 메뉴를 이리저리 뒤져도 보이지 않는 경우가 있습니다. 이는 해당 드라이버의 부모 격인 상위 하드웨어 버스 옵션이나 공통 서브시스템 옵션(예: CONFIG_NET)이 꺼져 있어서 하위 항목이 숨겨진 상태이기 때문이므로 검색 기능을 통해 선행 조건을 먼저 충족해야 합니다.
- .config 파일의 직접적인 수동 편집: vi 에디터 등으로 .config 텍스트 파일을 열어 옵션을 강제로 Y나 M으로 수정하면 컴파일러가 이를 인지하지 못하거나 빌드 스크립트 파싱 과정에서 설정 오류를 내며 초기화될 수 있습니다. 옵션 수정은 반드시 menuconfig 도구를 거치거나 제조사 공식 수정 가이드라인을 따라야 합니다.
- 호스트 PC 네이티브 빌드로 인한 컴파일 오염: CROSS_COMPILE 환경 변수를 빼먹고 컴파일을 돌리면 호스트 PC의 x86 GCC 가 작동하면서 중간 오브젝트 파일들(.o)이 64비트 x86 규격으로 꼬이게 됩니다. 이 상태에서 뒤늦게 변수를 주고 빌드를 돌리면 아키텍처 불일치 링크 에러가 나므로, 이때는 make mrproper 명령으로 빌드 트리를 아예 깨끗하게 청소한 후 처음부터 다시 빌드해야 합니다.
결론
리눅스 커널 설정 공정은 컴파일러 뒤에 숨겨진 수많은 드라이버 모듈 중에서 시스템에 꼭 필요한 에센스만 추출해내는 정밀한 필터링 작업입니다. menuconfig 도구의 기본 제어 메커니즘을 숙지하고, 시스템 요구사항에 부합하는 파일 시스템과 전원 관리 옵션을 올바르게 선별하는 역량을 갖춘다면, 제한된 자원 속에서도 최고의 하드웨어 퍼포먼스를 뽑아내는 고도로 최적화된 임베디드 운영체제 환경을 성공적으로 완성할 수 있습니다.
'Embedded System > Linux Kernel & Device Drivers' 카테고리의 다른 글
| 임베디드 리눅스 커널 모듈(LKM) 작성 및 동적 로딩 가이드 (0) | 2025.03.16 |
|---|---|
| 임베디드 리눅스 루트 파일 시스템(Rootfs) 제작 및 최적화 가이드 (0) | 2025.03.15 |
| 임베디드 리눅스 U-Boot 포팅 및 필수 환경 변수 설정 가이드 (0) | 2025.03.13 |
| 임베디드 리눅스 BSP 개념과 개발 공정: 수정부터 신규 작성까지 (0) | 2025.03.12 |
| 임베디드 리눅스 커널 포팅 절차 총정리: 환경 구축부터 빌드까지 (0) | 2025.03.11 |