커널 개발 환경 설정
Linux 커널 개발을 위한 개발 환경 구축 가이드: 필수 도구 설치, 에디터 설정, QEMU/KVM 가상 환경, 크로스 컴파일(Cross Compilation), GDB/KGDB 디버거 설정까지 완벽 정리.
핵심 요약
- 필수 도구 — gcc, make, git, flex, bison, libelf-dev 등 빌드에 필수적인 패키지를 먼저 설치합니다.
- 개발 보조 도구 — ctags, cscope, clangd 등으로 코드 탐색과 자동완성을 강화합니다.
- 가상 환경 — QEMU/KVM으로 안전하게 커널을 테스트하고 디버깅(Debugging)합니다.
- 크로스 컴파일 — ARM, ARM64, RISC-V 등 다른 아키텍처용 커널을 빌드합니다.
- 디버거 설정 — GDB/KGDB로 커널 소스 레벨 디버깅을 수행합니다.
단계별 이해
- 도구 설치
배포판에 맞는 패키지 관리자로 필수 도구를 설치합니다. - 에디터 구성
선호하는 에디터에 코드 탐색 도구를 연동합니다. - 가상 환경 준비
QEMU/KVM으로 테스트용 가상 머신을 구성합니다. - 첫 빌드 실행
간단한 설정으로 커널을 빌드하고 부팅 테스트합니다. - 디버거 연동
GDB와 QEMU를 연결하여 커널 디버깅 환경을 완성합니다.
환경 설계 원칙
커널 개발 환경은 단순 설치보다 재현성, 격리(Isolation), 검증 가능성이 중요합니다. 처음 한 번만 잘 구성하면 이후 실험 속도와 안정성이 크게 올라갑니다.
| 원칙 | 설명 | 실무 권장 |
|---|---|---|
| 재현성 | 같은 입력이면 같은 빌드 결과가 나와야 함 | 툴 버전 고정, 설정 파일(.config) 보관, 빌드 로그 아카이브 |
| 격리 | 호스트 시스템과 테스트 환경 분리 | QEMU/KVM 기본, 실제 장비는 후반 검증 단계에서만 사용 |
| 검증 가능성 | 문제 발생 시 원인 추적이 가능해야 함 | CONFIG_DEBUG_INFO, FRAME_POINTER, 로그 수집 자동화 |
| 점진적 확장 | 필수 도구부터 시작해 점진적으로 추가 | 필수(빌드) → 권장(탐색/가상화(Virtualization)) → 선택(분석/자동화) |
개발 도구 의존성 로드맵
커널 개발 환경은 여러 도구들이 계층적으로 연결된 생태계입니다. 아래 다이어그램은 각 도구의 역할과 의존 관계를 보여주며, 환경 구축 순서를 안내합니다.
환경 구축 권장 순서:
- 최소 환경 (1~2시간): Layer 0-1 + QEMU → 간단한 커널 빌드/부팅 가능
- 기본 개발 (반나절): + Layer 2A/2B → 코드 탐색 및 가상머신 테스트
- 완전한 환경 (1일): + Layer 3 → 디버깅 및 분석까지 모든 작업 가능
- 전문가 환경 (지속): + Layer 4 → 다중 아키텍처 개발 및 자동화
디스크 공간: 커널 소스 3GB + 빌드 결과 10GB + 가상머신 이미지 5GB = 최소 20GB 여유 필요
필수 개발 도구 설치
Linux 커널 빌드를 위해서는 컴파일러, 빌드 시스템, 버전 관리 시스템, 그리고 다양한 유틸리티가 필요합니다. 배포판별로 패키지 이름이 다를 수 있으므로 각 배포판에 맞는 명령어를 사용하세요.
Ubuntu / Debian 계열
# 필수 빌드 도구
sudo apt update
sudo apt install -y build-essential \
gcc make git pkg-config \
flex bison \
libelf-dev libssl-dev \
bc libncurses-dev \
cpio rsync
# 커널 문서 빌드 도구 (선택)
sudo apt install -y python3-sphinx \
texlive-latex-base texlive-latex-extra
# 추가 유틸리티
sudo apt install -y kmod dwarves \
sparse ccache
build-essential: gcc, g++, make 등 기본 빌드 도구 모음flex, bison: 파서 생성기 (커널 빌드 스크립트에서 사용)libelf-dev: BPF, eBPF 프로그램 빌드에 필요libssl-dev: 서명된 커널 모듈 빌드에 필요bc: 커널 빌드 스크립트의 계산기libncurses-dev: menuconfig TUI에 필요pkg-config:libelf,openssl등 라이브러리 존재 여부를 스크립트로 검증할 때 사용dwarves: pahole 등 DWARF 디버깅 정보 분석 도구sparse: 정적 분석 도구ccache: 컴파일러 캐시(Cache)로 재빌드 속도 향상
설치 직후 검증 명령
패키지 설치가 끝나면 바로 아래 명령으로 도구 상태를 확인하세요. 설치 자체보다 실행 가능한 상태를 검증하는 과정이 중요합니다.
# 필수 도구 버전 확인
gcc --version | head -1
make --version | head -1
git --version
ld --version | head -1
flex --version
bison --version | head -1
# 커널 빌드 관련 라이브러리 존재 확인
pkg-config --modversion libelf
openssl version
# 커널 소스에서 최소 빌드 검증
make mrproper
make defconfig
make -j$(nproc) bzImage
make defconfig가 실패하면 ncurses, flex, bison, bc 계열 의존성이 누락됐을 가능성이 큽니다.
bzImage 빌드가 실패하면 컴파일러/링커(Linker)/헤더 버전 조합을 우선 확인하세요.
버전 관리 정책
커널 개발에서는 "최신 버전"보다 "팀 전체에서 동일한 조합"이 더 중요할 때가 많습니다. 도구 버전을 팀 기준으로 고정하면 재현 불가 버그를 크게 줄일 수 있습니다.
- 컴파일러: GCC/Clang 메이저 버전을 팀 단위로 맞춥니다.
- 정적 분석 도구: sparse, coccinelle 버전 차이는 경고 양상 차이를 만듭니다.
- 디버거: GDB 버전 차이는 Python 스크립트 동작 차이로 이어질 수 있습니다.
- 문서화: 프로젝트 루트에 "권장 도구 버전 표"를 두고 신규 인원이 그대로 따라오게 합니다.
Fedora / RHEL / CentOS 계열
# 필수 빌드 도구
sudo dnf groupinstall -y "Development Tools"
sudo dnf install -y gcc make git pkgconf-pkg-config \
flex bison \
elfutils-libelf-devel openssl-devel \
bc ncurses-devel \
cpio rsync
# 추가 유틸리티
sudo dnf install -y kmod dwarves \
sparse ccache
Arch Linux
# 필수 빌드 도구
sudo pacman -S --needed base-devel pkgconf \
gcc make git \
flex bison \
libelf openssl \
bc ncurses \
cpio rsync
# 추가 유틸리티
sudo pacman -S kmod pahole \
sparse ccache
LLVM/Clang 대체 툴체인
리눅스 커널은 GCC 외에도 LLVM/Clang으로 공식 빌드를 지원합니다. Clang은 더 상세한 경고 메시지, CFI(Control Flow Integrity), 링크 타임 최적화(LTO) 등 GCC에 없는 보안/최적화 기능을 제공합니다.
LLVM/Clang 설치
# Ubuntu/Debian (배포판 기본 LLVM 패키지)
sudo apt install -y clang lld llvm
# Fedora
sudo dnf install -y clang lld llvm
# Arch Linux
sudo pacman -S clang lld llvm
Clang으로 커널 빌드
# 기본 Clang 빌드
make CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm \
STRIP=llvm-strip OBJCOPY=llvm-objcopy \
OBJDUMP=llvm-objdump READELF=llvm-readelf \
HOSTCC=clang HOSTCXX=clang++ HOSTAR=llvm-ar \
defconfig
# 간편한 방법: LLVM=1 (모든 도구를 LLVM으로)
make LLVM=1 defconfig
make LLVM=1 -j$(nproc)
# 접미사 버전 패키지(clang-18 등)를 설치했다면
make LLVM=-${LLVM_VERSION} defconfig
make LLVM=-${LLVM_VERSION} -j$(nproc)
# Clang으로 크로스 컴파일 (단일 바이너리로 모든 아키텍처)
make LLVM=1 ARCH=arm64 defconfig
make LLVM=1 ARCH=arm64 -j$(nproc)
Clang 전용 기능
| 기능 | 설정 옵션 | 설명 |
|---|---|---|
| CFI | CONFIG_CFI_CLANG |
간접 호출 대상 검증, 코드 재사용 공격 방어 |
| LTO (Thin) | CONFIG_LTO_CLANG_THIN |
링크 타임 최적화 (전체 프로그램 최적화) |
| Shadow Call Stack | CONFIG_SHADOW_CALL_STACK |
ROP 공격 방어 (ARM64) |
| KCFI | CONFIG_CFI_CLANG |
커널 전용 CFI 구현 |
| Auto-init | CONFIG_INIT_STACK_ALL_ZERO |
스택 변수 자동 초기화 (정보 유출 방지) |
GCC vs Clang 비교
| 항목 | GCC | Clang/LLVM |
|---|---|---|
| 역사 | 커널 공식 기본 컴파일러 | 4.x부터 공식 지원, Android 커널 기본 |
| 에러 메시지 | 간결 | 상세하고 컬러풀, 제안 포함 |
| 경고 수준 | 보수적 | 더 많은 잠재 문제 감지 |
| 크로스 컴파일 | 아키텍처별 별도 툴체인 | 단일 바이너리로 모든 아키텍처 |
| LTO | 지원 (느림) | ThinLTO로 빠르고 효율적 |
| 보안 기능 | 기본 | CFI, Shadow Call Stack 등 추가 |
| 빌드 속도 | 보통 | 비슷하거나 약간 빠름 |
| 플러그인 | GCC 플러그인 지원 | 미지원 (대안 기능 제공) |
# 양쪽 컴파일러로 빌드 테스트
# GCC 빌드
make O=build-gcc defconfig
make O=build-gcc -j$(nproc) 2>&1 | tee gcc-warnings.log
# Clang 빌드
make O=build-clang LLVM=1 defconfig
make O=build-clang LLVM=1 -j$(nproc) 2>&1 | tee clang-warnings.log
# 경고 비교
diff <(grep "warning:" gcc-warnings.log | sort) \
<(grep "warning:" clang-warnings.log | sort)
코드 탐색 도구
ctags, cscope, clangd 등 코드 탐색 도구의 설치, 에디터 통합, 인덱스 관리 전략은 별도 페이지로 분리되었습니다.
에디터 설정
Vim, VS Code, Emacs, Neovim의 커널 개발 최적화 설정은 별도 페이지로 분리되었습니다.
QEMU/KVM 가상 환경 설정
QEMU 설치, rootfs 생성, 커널 부팅, 빠른 테스트 루프, 부팅 실패 대응 등 QEMU/KVM 가상 환경의 상세 가이드는 별도 페이지로 분리되었습니다.
virtme-ng: 빠른 커널 테스트
virtme-ng는 별도 rootfs 없이 호스트 파일시스템(Filesystem)을 공유하여 빌드한 커널을 즉시 부팅하는 도구입니다. 설치, 사용법, QEMU와의 비교는 QEMU 가이드에서 확인할 수 있습니다.
initramfs 직접 생성
BusyBox 기반 initramfs 생성, 커널 내장 initramfs, 고급 구성 등 상세 가이드는 QEMU 페이지에서 확인할 수 있습니다.
BusyBox 멀티콜 바이너리 아키텍처, 애플릿 시스템 등 심층 내용은 BusyBox 종합 가이드를 참고하세요.
크로스 컴파일 환경
ARM, ARM64, RISC-V 크로스 컴파일 환경 구축은 별도 페이지로 분리되었습니다.
GDB/KGDB 디버거 설정
GDB/KGDB를 이용한 커널 소스 레벨 디버깅 — QEMU-GDB 연동 워크플로, GDB 명령어, KGDB 실제 하드웨어 디버깅 등 상세 가이드는 별도 페이지로 분리되었습니다.
디버그 커널 설정 옵션 총정리
커널 디버그 CONFIG 옵션 카테고리별 정리, 목적별 프로필, Sanitizer 조합 가이드는 별도 페이지로 분리되었습니다.
빌드 속도 최적화
ccache (컴파일러 캐시)
ccache는 컴파일 결과를 캐싱하여 재빌드 속도를 크게 향상시킵니다.
# ccache 설치 (이미 위에서 설치됨)
sudo apt install ccache
# ccache 캐시 크기 설정 (기본 5GB, 10GB 권장)
ccache -M 10G
# ccache 통계 확인
ccache -s
# 커널 빌드 시 ccache 사용
make CC="ccache gcc" -j$(nproc)
# 또는 PATH에 ccache 심볼릭 링크 추가
export PATH="/usr/lib/ccache:$PATH"
make -j$(nproc)
distcc (분산 컴파일)
여러 머신을 사용하여 병렬로 컴파일하면 빌드 시간을 대폭 단축할 수 있습니다.
# 서버 머신에서 distccd 실행
sudo apt install distcc
distccd --daemon --allow 192.168.1.0/24
# 클라이언트 머신에서 빌드
export DISTCC_HOSTS="localhost 192.168.1.100 192.168.1.101"
make CC="distcc gcc" -j16
ccache만으로 이득을 확인한 뒤, 대형 소스 트리에서만 distcc를 추가하는 순서가 안전합니다.
빌드 환경 성능 튜닝
커널 빌드 성능은 디스크 I/O, 병렬 작업 수, 캐시 효율에 크게 좌우됩니다. 아래 기법으로 빌드 시간을 50% 이상 단축할 수 있습니다.
tmpfs 빌드 (RAM 디스크)
# 별도 빌드 디렉토리를 tmpfs에 마운트
sudo mkdir -p /mnt/kbuild
sudo mount -t tmpfs -o size=15G tmpfs /mnt/kbuild
# 소스와 빌드 디렉토리 분리 (O= 옵션)
cd /home/user/linux
make O=/mnt/kbuild defconfig
make O=/mnt/kbuild -j$(nproc)
# 영구 설정: /etc/fstab에 추가
# tmpfs /mnt/kbuild tmpfs size=15G,mode=1777 0 0
병렬 작업 수 최적화
# 기본: CPU 코어 수
make -j$(nproc)
# 코어 수 + 2 (I/O 대기 보상)
make -j$(( $(nproc) + 2 ))
# 메모리 제한 고려: 코어당 2GB 필요 (LTO 시)
# 16GB RAM, 8코어 → -j8이 안전
# 8GB RAM, 8코어 → -j4 권장
# 백그라운드 빌드 (낮은 우선순위)
nice -n 19 ionice -c3 make -j$(nproc)
증분 빌드 최적화
| 기법 | 명령 | 효과 |
|---|---|---|
| 단일 파일 빌드 | make drivers/net/my_driver.o |
컴파일 오류만 빠르게 확인 |
| 단일 디렉토리 빌드 | make drivers/net/ |
서브시스템 전체 빌드 |
| 모듈만 빌드 | make modules |
vmlinux 재링크 건너뜀 |
| ccache + 분리 빌드 | make CC="ccache gcc" O=build/ |
캐시 히트로 재빌드 10초 이내 |
| 전처리만 확인 | make drivers/net/my_driver.i |
매크로(Macro) 전개 결과 확인 |
| 어셈블리(Assembly) 확인 | make drivers/net/my_driver.s |
컴파일러 출력 코드 확인 |
정적 분석 도구
Sparse, Coccinelle, checkpatch.pl 등 커널 정적 분석 도구의 설치와 상세 사용법은 별도 페이지로 분리되었습니다.
커널 셀프테스트 (kselftest)
커널 셀프테스트는 커널 기능의 회귀를 자동으로 검출하는 테스트 프레임워크입니다. tools/testing/selftests/에 서브시스템별 테스트가 있으며, 패치(Patch) 제출 전 관련 테스트를 실행하는 것이 좋습니다.
셀프테스트 실행
# 전체 셀프테스트 빌드 & 실행
make -C tools/testing/selftests run_tests
# 특정 서브시스템 테스트만 실행
make -C tools/testing/selftests TARGETS="net mm" run_tests
# 개별 테스트 빌드
make -C tools/testing/selftests/net
# 크로스 컴파일 셀프테스트
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- \
-C tools/testing/selftests TARGETS="bpf"
# 설치 (QEMU rootfs에 복사용)
make -C tools/testing/selftests TARGETS="net" \
INSTALL_PATH=/path/to/rootfs/kselftest install
주요 테스트 타겟
| 타겟 | 테스트 영역 | 선행 조건 |
|---|---|---|
bpf |
BPF/eBPF 프로그램 | CONFIG_BPF_SYSCALL, clang/llvm |
net |
네트워킹 스택 | CONFIG_NET |
mm |
메모리 관리(Memory Management) | CONFIG_USERFAULTFD |
cgroup |
컨트롤 그룹 | CONFIG_CGROUPS |
futex |
Futex 동기화 | CONFIG_FUTEX |
seccomp |
Seccomp 필터 | CONFIG_SECCOMP |
kvm |
KVM 가상화 | CONFIG_KVM |
filesystems |
파일시스템 공통 | 다양한 FS CONFIG |
테스트 작성 기본 패턴
// tools/testing/selftests/my_subsystem/my_test.c
#include "../kselftest_harness.h"
/* 기본 테스트 */
TEST(my_basic_test)
{
int result = do_something();
/* 성공 조건 확인 */
ASSERT_EQ(result, 0);
ASSERT_NE(result, -1);
ASSERT_GT(result, -1);
EXPECT_TRUE(result >= 0);
}
/* 파라미터화된 테스트 */
FIXTURE(my_fixture)
{
int fd;
};
FIXTURE_SETUP(my_fixture)
{
self->fd = open("/dev/mydev", O_RDWR);
ASSERT_GE(self->fd, 0);
}
FIXTURE_TEARDOWN(my_fixture)
{
close(self->fd);
}
TEST_F(my_fixture, read_test)
{
char buf[64];
ssize_t n = read(self->fd, buf, sizeof(buf));
ASSERT_GT(n, 0);
}
TEST_HARNESS_MAIN
# tools/testing/selftests/my_subsystem/Makefile
TEST_GEN_PROGS := my_test
include ../lib.mk
KSFT_SKIP반환으로 선행 조건 미충족 시 테스트 건너뛰기make -C tools/testing/selftests TARGETS="net" summary=1로 결과 요약- QEMU에서 실행 시
INSTALL_PATH로 rootfs에 테스트 복사 후 실행 - CI 파이프라인(Pipeline)에 셀프테스트 포함하여 자동 회귀 검사
일반적인 개발 워크플로
- 소스 다운로드
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git cd linux - 브랜치 생성
git checkout -b my-feature - 설정 및 빌드
make defconfig ./scripts/config --enable DEBUG_INFO make -j$(nproc) - 코드 탐색 인덱스 생성
make tags cscope ./scripts/clang-tools/gen_compile_commands.py - 코드 수정 및 테스트
# 에디터로 코드 수정 vim drivers/my_driver.c # 재빌드 make -j$(nproc) # QEMU 테스트 qemu-system-x86_64 -kernel arch/x86/boot/bzImage ... - 코딩 스타일 검사
./scripts/checkpatch.pl --file drivers/my_driver.c - 정적 분석
make C=2 drivers/my_driver.o - 패치 생성
git add drivers/my_driver.c git commit -s git format-patch -1
Git 커널 패치 워크플로
리눅스 커널 이메일 기반 패치 워크플로 — git format-patch, git send-email, get_maintainer.pl, b4 도구의 상세 사용법은 별도 페이지로 분리되었습니다.
git bisect (회귀 추적)
특정 커밋에서 버그가 도입된 시점을 이진 탐색으로 찾습니다. 수천 개의 커밋 중에서도 log₂(N) 번의 테스트로 원인 커밋을 특정할 수 있습니다.
# bisect 시작
git bisect start
# 현재(버그 있음) = bad, 정상 동작 커밋 = good
git bisect bad HEAD
git bisect good v6.6
# Git이 중간 커밋을 체크아웃 → 테스트 → good/bad 반복
# 빌드 & 테스트
make -j$(nproc) && qemu-system-x86_64 ...
git bisect good # 또는 git bisect bad
# 자동 bisect (스크립트로 자동화)
git bisect start HEAD v6.6
git bisect run ./test-script.sh
# bisect 종료 & 정리
git bisect reset
- 제목:
subsystem: 변경 요약(50자 이내, 마침표 없음) - 본문: 왜 변경이 필요한지 설명 (72자/줄)
- Signed-off-by: DCO(Developer Certificate of Origin) 동의 필수 (
git commit -s) - Fixes: 버그 수정 시 원인 커밋 SHA 참조
- Cc: stable 백포트 요청 시
Cc: stable@vger.kernel.org
트러블슈팅 플레이북
아래 순서대로 점검하면 환경 문제를 빠르게 축소할 수 있습니다. 핵심은 문제 범위를 한 단계씩 좁히는 것입니다.
- 도구 문제 분리:
gcc --version,make --version,ld --version - 설정 문제 분리:
make mrproper && make defconfig로 최소 상태 확인 - 소스 문제 분리: 같은 커밋을 깨끗한 트리에서 다시 빌드
- 런타임 문제 분리: QEMU에서 재현되는지 먼저 확인
- 디버깅 단계 진입: GDB 브레이크포인트와 부팅 로그를 함께 확보
| 오류 메시지 예시 | 우선 점검 | 대응 |
|---|---|---|
No rule to make target ... |
빌드 트리 오염 여부 | make mrproper 후 defconfig부터 재시작(Reboot) |
fatal error: openssl/... not found |
개발 헤더 누락 | libssl-dev 또는 openssl-devel 설치 |
pahole not found |
dwarves 패키지 설치 여부 | dwarves/pahole 설치 후 재빌드 |
undefined reference ... |
툴체인/설정 불일치 | ARCH/CROSS_COMPILE/CONFIG 조합 재확인 |
| QEMU 패닉 후 즉시 종료 | 로그 확보 실패 | -nographic + panic=-1 + 로그 파일 저장 |
build.log), QEMU 부팅 로그(qemu-boot.log), 커널 설정(.config), 커밋 해시(Hash)를 항상 함께 보관하세요.
이 네 가지가 있으면 대부분의 환경 문제를 재현하고 분석할 수 있습니다.
고급 트러블슈팅
| 오류 메시지 / 증상 | 원인 | 해결 |
|---|---|---|
BTF: .tmp_vmlinux.btf: pahole ... not found |
CONFIG_DEBUG_INFO_BTF 활성화 + pahole 미설치 | sudo apt install dwarves 또는 CONFIG_DEBUG_INFO_BTF=n |
zstd: command not found |
모듈 압축에 zstd 필요 | sudo apt install zstd |
GDB Remote 'g' packet reply is too long |
GDB 아키텍처 불일치 | set arch i386:x86-64 또는 gdb-multiarch 사용 (상세) |
clangd compile_commands.json not found |
컴파일 DB 미생성 | ./scripts/clang-tools/gen_compile_commands.py 실행 |
ccache cache miss 비율 높음 |
설정 변경, 캐시 크기 부족 | ccache -M 20G, KBUILD_BUILD_TIMESTAMP 고정 |
QEMU Could not access KVM kernel module |
KVM 모듈 미로드 또는 권한 부족 | sudo modprobe kvm_intel, sudo usermod -aG kvm $USER |
KASAN BUG: KASAN: slab-out-of-bounds |
버퍼(Buffer) 오버플로(Buffer Overflow) 감지 | 보고된 스택 트레이스에서 접근 위치 확인 후 경계 검사 추가 |
LOCKDEP possible circular locking |
데드락 위험 감지 | 락 획득 순서 재검토, 보고된 체인 분석 |
Kernel panic - not syncing: Attempted to kill init! |
PID 1(init) 프로세스(Process) 종료 | initramfs의 init 스크립트가 exec /bin/sh로 끝나는지 확인 |
No working init found |
init 실행 파일 없음 | rdinit=/init 파라미터 확인, init에 실행 권한(chmod +x) 확인 |
환경 진단 스크립트
#!/bin/bash
# kernel-env-check.sh - 커널 개발 환경 진단
echo "=== 커널 개발 환경 진단 ==="
echo
# 필수 도구
echo "[필수 도구]"
for cmd in gcc make git flex bison bc; do
if command -v $cmd >/dev/null 2>&1; then
echo " ✓ $cmd: $($cmd --version 2>&1 | head -1)"
else
echo " ✗ $cmd: 미설치"
fi
done
# 라이브러리
echo
echo "[필수 라이브러리]"
for lib in libelf openssl; do
if pkg-config --exists $lib 2>/dev/null; then
echo " ✓ $lib: $(pkg-config --modversion $lib)"
else
echo " ✗ $lib: 미설치 또는 dev 패키지 필요"
fi
done
# 선택 도구
echo
echo "[선택 도구]"
for cmd in clangd ctags cscope qemu-system-x86_64 gdb ccache sparse; do
if command -v $cmd >/dev/null 2>&1; then
echo " ✓ $cmd"
else
echo " - $cmd: 미설치 (선택)"
fi
done
# KVM
echo
echo "[KVM 지원]"
if [ -e /dev/kvm ]; then
echo " ✓ /dev/kvm 존재"
if [ -r /dev/kvm ] && [ -w /dev/kvm ]; then
echo " ✓ 현재 사용자 접근 가능"
else
echo " ✗ 권한 부족: sudo usermod -aG kvm \$USER"
fi
else
echo " ✗ /dev/kvm 없음: BIOS에서 가상화 활성화 필요"
fi
# 디스크/메모리
echo
echo "[시스템 리소스]"
echo " RAM: $(free -h | awk '/Mem:/{print $2}')"
echo " 디스크 여유: $(df -h . | awk 'NR==2{print $4}')"
echo " CPU 코어: $(nproc)"
추가 팁
git worktree를 사용하면 편리합니다.
# 현재 mainline 트리에서 별도 작업 디렉토리 추가
git worktree add ../linux-mainline master
# linux-next 트리 추가
git remote add linux-next https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
git fetch linux-next master
git worktree add ../linux-next linux-next/master
안정 커널(stable)은 별도 stable remote에서 원하는 linux-6.x.y 유지보수 브랜치를 명시적으로 fetch한 뒤 worktree를 추가하세요.
make defconfig
make -j$(nproc)
qemu-system-x86_64 -kernel arch/x86/boot/bzImage \
-append "console=ttyS0 panic=-1" \
-nographic
Docker/Podman 컨테이너(Container) 개발 환경
컨테이너 기반 개발 환경은 호스트 시스템을 오염시키지 않으면서 재현 가능한 빌드 환경을 제공합니다. 팀 전체가 동일한 툴체인 버전을 사용하도록 강제할 수 있어, "내 머신에서는 빌드되는데" 문제를 완전히 차단합니다.
컨테이너 개발의 장점
| 항목 | 호스트 직접 설치 | 컨테이너 환경 |
|---|---|---|
| 재현성 | 호스트 업데이트에 따라 깨질 수 있음 | Dockerfile 고정으로 완전 재현 |
| 다중 툴체인 | 버전 충돌 위험 | 이미지별 독립 환경 |
| 정리 | 패키지 잔여물 누적 | 컨테이너 삭제로 깔끔 정리 |
| CI 연동 | CI와 로컬 환경 불일치 | 동일 이미지로 CI/로컬 통일 |
| 크로스 컴파일 | 복잡한 멀티 아키텍처 설정 | 아키텍처별 전용 이미지 |
커널 빌드용 Dockerfile
# Dockerfile.kernel-dev
FROM ubuntu:24.04
LABEL maintainer="kernel-dev"
LABEL description="Linux kernel development environment"
# 비대화형 설치
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Seoul
# 필수 빌드 도구
RUN apt-get update && apt-get install -y \
build-essential gcc g++ make \
git flex bison pkg-config \
libelf-dev libssl-dev \
bc libncurses-dev \
cpio rsync kmod \
dwarves sparse ccache \
\
# 코드 탐색
universal-ctags cscope \
clangd clang lld llvm \
\
# 가상화 & 디버깅
qemu-system-x86 qemu-system-arm \
gdb gdb-multiarch \
\
# 크로스 컴파일
gcc-aarch64-linux-gnu \
gcc-arm-linux-gnueabihf \
gcc-riscv64-linux-gnu \
\
# 유틸리티
vim tmux ripgrep \
python3 python3-pip \
curl wget sudo \
coccinelle \
\
&& rm -rf /var/lib/apt/lists/*
# ccache 설정
RUN ccache -M 20G
ENV PATH="/usr/lib/ccache:${PATH}"
# 비루트 사용자 생성
ARG USER=kdev
ARG UID=1000
RUN useradd -m -u ${UID} -s /bin/bash ${USER} \
&& echo "${USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
USER ${USER}
WORKDIR /home/${USER}/linux
CMD ["/bin/bash"]
컨테이너 빌드 및 실행
# 이미지 빌드
docker build -t kernel-dev -f Dockerfile.kernel-dev .
# 커널 소스를 마운트하여 실행
docker run -it --rm \
-v $(pwd)/linux:/home/kdev/linux \
-v kernel-ccache:/home/kdev/.cache/ccache \
--device /dev/kvm \
--name kernel-build \
kernel-dev
# Podman 사용 시 (rootless)
podman run -it --rm \
-v $(pwd)/linux:/home/kdev/linux:Z \
-v kernel-ccache:/home/kdev/.cache/ccache:Z \
--device /dev/kvm \
--userns=keep-id \
kernel-dev
# 컨테이너 안에서 빌드
make defconfig
make -j$(nproc)
# 컨테이너 안에서 QEMU 테스트
qemu-system-x86_64 \
-kernel arch/x86/boot/bzImage \
-append "console=ttyS0" \
-nographic -enable-kvm -m 2G
- 소스 코드: 호스트의 커널 소스를 바인드 마운트(Bind Mount) → 에디터는 호스트에서, 빌드는 컨테이너에서
- ccache 캐시: named volume으로 컨테이너 재생성에도 캐시 유지
- /dev/kvm: KVM 가속을 위해 디바이스 전달
- 빌드 산출물: 소스 바인드 마운트에 포함되므로 호스트에서도 접근 가능
아키텍처별 컨테이너 전략
# ARM64 크로스 빌드 전용 컨테이너
docker run -it --rm \
-v $(pwd)/linux:/home/kdev/linux \
-e ARCH=arm64 \
-e CROSS_COMPILE=aarch64-linux-gnu- \
kernel-dev bash -c "make defconfig && make -j\$(nproc)"
# docker-compose.yml로 다중 아키텍처 동시 빌드
# docker compose up --parallel
# docker-compose.yml
services:
x86-build:
image: kernel-dev
volumes:
- ./linux:/home/kdev/linux
- ccache-x86:/home/kdev/.cache/ccache
command: bash -c "make x86_64_defconfig && make -j$(nproc)"
arm64-build:
image: kernel-dev
volumes:
- ./linux:/home/kdev/linux
- ccache-arm64:/home/kdev/.cache/ccache
environment:
- ARCH=arm64
- CROSS_COMPILE=aarch64-linux-gnu-
command: bash -c "make defconfig && make -j$(nproc)"
riscv-build:
image: kernel-dev
volumes:
- ./linux:/home/kdev/linux
- ccache-riscv:/home/kdev/.cache/ccache
environment:
- ARCH=riscv
- CROSS_COMPILE=riscv64-linux-gnu-
command: bash -c "make defconfig && make -j$(nproc)"
volumes:
ccache-x86:
ccache-arm64:
ccache-riscv:
- UID 매핑(Mapping): 컨테이너 내부 UID와 호스트 UID가 다르면 소스 파일 권한 문제 발생 →
--build-arg UID=$(id -u)사용 - 빌드 산출물 소유권: 컨테이너에서 생성한 파일의 소유자가 호스트와 다를 수 있음 → Podman의
--userns=keep-id권장 - SELinux: Fedora/RHEL에서는 바인드 마운트에
:Z접미사 필요
원격 개발 환경
SSH 최적화, tmux, GNU Screen, VS Code Remote Development 설정은 별도 페이지로 분리되었습니다.
커널 설정 전략
커널 설정(.config)은 4000개 이상의 옵션으로 구성됩니다. 목적에 맞는 설정 전략을 세우면 빌드 시간 단축과 디버깅 효율 향상을 동시에 달성할 수 있습니다.
설정 도구(menuconfig, nconfig, xconfig 등)의 상세 비교는 커널 빌드 시스템 페이지를 참고하세요.
목적별 설정 전략
설정 프래그먼트 관리
프로젝트별 설정 변경을 .config 직접 수정 대신 프래그먼트 파일로 관리하면 버전 관리와 재현이 쉬워집니다.
# 디버그 프래그먼트: debug.config
cat > debug.config <<'EOF'
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
CONFIG_GDB_SCRIPTS=y
CONFIG_FRAME_POINTER=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_FS=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_LOCKDEP=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_KASAN=y
EOF
# 프래그먼트 적용: defconfig + 디버그 옵션
cd /path/to/linux
make defconfig
./scripts/kconfig/merge_config.sh .config debug.config
# 또는 KCONFIG_ALLCONFIG 사용
make KCONFIG_ALLCONFIG=debug.config alldefconfig
# 최소 QEMU 부팅 프래그먼트: qemu-minimal.config
cat > qemu-minimal.config <<'EOF'
CONFIG_PCI=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_NET=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_EXT4_FS=y
CONFIG_TMPFS=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
EOF
- 프래그먼트 파일을 Git에 커밋하여 팀과 공유
make savedefconfig로 현재 설정의 최소 diff를defconfig로 저장scripts/diffconfig로 두 .config 파일의 차이점만 추출- CI에서는
merge_config.sh로 베이스 + 프래그먼트 조합 자동화
참고자료
공식 문서
- HOWTO do Linux kernel development — 공식 커널 개발 시작 가이드
- Development Tools — 커널 개발 도구 종합 문서 (KASAN, sparse, coccinelle 등)
- Debugging kernel with GDB — QEMU+GDB 커널 디버깅 공식 가이드
- KASAN — Kernel Address Sanitizer (메모리 오류 검출)
- KCSAN — Kernel Concurrency Sanitizer (데이터 레이스 검출)
- UBSAN — Undefined Behavior Sanitizer (정의되지 않은 동작 검출)
- kmemleak — 커널 메모리 누수 검출기
- kselftest — 커널 셀프테스트 프레임워크
- ftrace — 함수 트레이싱 프레임워크 공식 문서
- Submitting Patches — 패치 제출 프로세스
- Linux Kernel Coding Style — 코딩 스타일 공식 규칙
- Kbuild Documentation — 커널 빌드 시스템(Kconfig, Makefile) 공식 문서
- Minimal Requirements — 커널 빌드에 필요한 도구 최소 버전 요구사항
개발 도구
- QEMU Documentation — QEMU 공식 문서 (커널 테스트용 가상 머신)
- virtme-ng — 현재 커널을 QEMU에서 즉시 부팅하는 빠른 테스트 도구
- clangd — LSP 기반 코드 내비게이션 (정의 이동, 참조 찾기, 자동 완성)
- ccache — 컴파일 캐시 (반복 빌드 속도 5-10배 향상)
- Clang Cross Compilation — LLVM 크로스 컴파일 가이드
- perf Examples (Brendan Gregg) — perf 활용 예제 모음
- Cscope — 대규모 C 프로젝트 심볼 탐색 도구
- Universal Ctags — 소스 코드 태그 생성기 (함수/구조체(Struct) 정의 색인)
- Coccinelle — 의미 기반 패치 도구 (코드 패턴 일괄 변환)
- Sparse — C 의미 분석 도구 (__user, __iomem 어노테이션 검사)
커뮤니티 및 학습 리소스
- KernelNewbies — 초보자 위키, 환경 설정 가이드, 버전별 변경사항
- Kernel Build (KernelNewbies) — 커널 빌드 환경 설정 단계별 안내
- LWN.net — 커널 개발 뉴스, 도구, 인프라 관련 심층 분석
- Elixir Cross Referencer — 웹에서 커널 소스 버전별 탐색
- Greg KH YouTube — 커널 개발 환경 구성 및 개발 프로세스 강의
- Linux Performance (Brendan Gregg) — 리눅스 성능 분석 도구 종합 안내
관련 문서
- 커널 빌드 시스템 — Kbuild, Kconfig, 크로스 컴파일
- 디버깅 — 커널 디버깅 기법과 도구 상세 가이드
- 개발 도구 — GCC, Clang, 정적 분석 도구 종합
- 커널 모듈 — 모듈 빌드/테스트 환경
- QEMU — 가상 머신 기반 커널 테스트 상세 가이드
- 커널 보안 — 개발 환경 보안 설정
- 소스 코드 읽기 — 개발 환경 구축 후 소스 탐색 시작하기
- 코딩 스타일 — checkpatch.pl, 들여쓰기, 네이밍, 매크로 규칙
- 커널 개발 주의사항 — 흔히 발생하는 실수와 주의사항, 해결 방법 정리
- 임베디드 빌드 시스템 — Buildroot/Yocto rootfs 구성 및 SDK 개발 환경