https://seokbeomkim.github.io/posts/build-kernel-and-busybox/
취업은 언제하나… 커널 공부를 할 게 아니라 취업을 위한 알고리즘을 공부해야 하는데 커널 해킹을 위한 환경 구축만 하고 공부하자는 것이 꼬리에 꼬리를 물게 되었다. 커널 분석을 공부하고 궁금했던 사항들을 직접 확인해보기 위해 QEMU를 이용한 환경을 구축하기로 결정했다. 다행히도 나와 같은 생각을 한 사람이 있었고 매우 자세하게 설명을 해놓았기에 금방 해결할 수 있었다. 다만, 부팅 후 램디스크만을 이용하고 루트파티션은 마운트하지 않는다는 제한은 있다.
이 문서는 참고한 페이지를 토대로 필요한 정보들을 중간에 좀 더 추가한 형태로 정리하였다. 향후 커널 분석과 토이 프로젝트들을 진행하기 위해 필요한 환경으로 실행 환경은 아래와 같다.
출처 페이지와는 다르게 필자는 맥 환경에서 커널 컴파일을 진행해야 했기 때문에 빌드를 시작하기에 앞서 docker 컨테이너를 준비하는 과정이 있었다. 맥에서 직접 크로스 컴파일러를 직접 만들어 사용하는 방법도 있지만, 시간도 오래 걸리고 빌드에 필요한 헤더 환경이 달라 도커를 사용하였다.
현재 주로 사용하는 운영체제는 macOS Mojave 10.14.5이다. 이 환경에서 리눅스 커널을 빌드하기 위해서는 GNU GCC, GLIBC 환경이 리눅스와 일치해야 하는데 커널 컴파일을 위해 필요한 헤더파일 경로부터 맞지 않은 부분이 있어 크로스 컴파일러를 준비하는 방법은 포기하고 대신, docker를 사용하기로 했다. 가상머신을 이용하는 방법도 있지만, 도커에 비해 무겁고 GUI 환경이 불필요했기에 도커를 이용해 커널 컴파일을 하는 편이 훨씬 유리하다고 생각했다.
docker를 설치했다는 가정하에, 아래와 같이 컨테이너를 만들었다. 호스트 볼륨을 컨테이너에 맵핑해주었는데 이렇게 해야 커널 해킹한 소스를 바로 빌드하여 맥에서 QEMU를 통해 확인할 수 있기 때문이다.
docker run --name kernel_builder -ti -v /Users/sukbeom/Workspaces:/kernel/ ubuntu /bin/bash
# 아래 부터는 개발 환경을 위한 패키지 설치이다.
apt update && apt upgrade
apt install vim && vim /etc/apt/sources.list # 편집기 설치 및 미러저장소 경로 설정
apt install git curl libncurses-dev wget gcc make flex build-essential bison linux-headers-generic libelf-dev openssl bc libssl-dev cpio
이제 컴파일을 위한 빌드 환경이 준비되었다. 커널 컴파일을 위한 맥에서의 경로는 $HOME/Workspaces/kernel 로 지정하고 컨테이너 내에서는 /kernel 로 접근하도록 설정하였다. 커널은 여기에서, busybox는 여기에서 받을 수 있다. 필자가 사용한 버전은 아래와 같다.
busybox란?Single executable 파일 형태로 여러 가지 유닉스 유틸리티를 제공하는 Software suite 이다. 안드로이드 상에서 리눅스와 같은 터미널 환경을 제공하는 termux 애플리케이션을 살펴보면 최초 실행 시 busybox를 설치하는 것을 알 수 있다. 임베디드 환경과 같이 아주 제한된 리소스를 가진 시스템 상에서 필요한 (셸 환경을 위한)최소한의 유틸리티만을 사용하고자 할 때 사용하는 소프트웨어라고 생각하면 된다.
원래는 커널 분석을 하던 버전(v2.6.39)으로 진행을 하고자 했으나 소스 자체가 오래되었고 GCC 7 버전을 지원하지 않아 플래그와 perl 소스에서 생기는 에러를 고쳐도 컴파일 에러가 나 버전을 바꾸었다. 추후 GCC 버전을 낮춰 다시 한번 빌드 해봐야겠다.
이제 컨테이너 환경으로 돌아가 아래와 같이 (shell)환경변수를 임시로 설정해준 뒤 차례대로 빌드해준다.
STAGE=~/Workspaces
TOP=$STAGE/custom-kernel
mkdir -p $STAGE
다운로드 한 busybox, kernel 소스의 압축을 풀어주고 아래와 같이 busybox를 설정해준다. Busybox settings -> Build BusyBox as a static binary (no shared libs) 항목에 체크해준다. (출처 링크에 가면 친절한 스크린샷과 함께 각 과정들을 자세하게 확인할 수 있다.)