이전에는 buildroot
으로 rootfs
를 만들어 QEMU
로 커널을 디버깅했다. 하지만 커널 디버깅만 하기에 buildroot
는 너무 무겁다. (빌드도 오래 걸리고 부팅 시간도 길다.) 따라서 이번에는 busybox
를 통해 minimal 한 rootfs
를 구성한 뒤, 이를 QEMU
로 디버깅 해볼 것이다.
busybox
다운로드 받기https://busybox.net/downloads/?C=M;O=D
위 링크로 들어가면 busybox
를 다운로드 받을 수 있다. 필자는 Last modified 로 정렬해서 (글을 작성하는 시점인 25년 07월 05일 기준) 가장 최신 버전인 busybox-1.37.0.tar.bz2
를 다운로드 받았다.
wget https://busybox.net/downloads/busybox-1.37.0.tar.bz2
tar -xf busybox-1.37.0.tar.bz2
rm busybox-1.37.0.tar.bz2
mv busybox-1.37.0 busybox
압축을 풀고 압축파일을 삭제하였다.
sysroot
) 필자는 arm64
커널을 디버깅 할 예정이기 때문에 rootfs
의 바이너리도 aarch64
로 빌드해야 한다. 필자의 호스트 머신은 x86_64
이므로 크로스 컴파일이 필요하다. 여기서부터는 배포판마다 진행 과정이 약간씩은 다를 수 있으나 큰 줄기는 같다. 필자는 Fedora Linux 42 (Workstation Edition) x86_64
를 기준으로 서술한다.
sudo dnf install gcc-aarch64-linux-gnu gcc-c++-aarch64-linux-gnu
sudo dnf install binutils-aarch64-linux-gnu
sudo dnf install sysroot-aarch64-fc42-glibc
busybox
를 빌드하기 위해선 sysroot
패키지가 필요한데 여기에서 sysroot
이란, 크로스 컴파일 툴체인이 default
로 인식하는 header
와 library
의 논리적인 root directory
를 의미한다. (출처: https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html)
Fedora
의 경우, aarch64-linux-gnu
가 aarch64-redhat-linux
의 경로와 통합되어 있지 않기 때문에 직접 sys-root
을 이어줘야 한다. 어찌보면 이러한 패키지 디렉토리 구조가 sysroot
의 취지에 잘 들어맞는다고 볼 수도 있다.
ln -s /usr/aarch64-redhat-linux/sys-root/fc42/usr /usr/aarch64-redhat-linux/sys-root/usr
ln -s /usr/aarch64-redhat-linux/sys-root /usr/aarch64-linux-gnu/sys-root
mkdir build
make O=build/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
우선 defconfig
명령어를 입력하고 몇 가지 에러를 수정해야 한다. 가장 먼저 해야 하는 일은 menuconfig
에서 발생하는 버그를 수정하는 것이다.
이것은 ncurses-devel
패키지를 설치해도 발생하는 문제로 scripts/kconfig/lxdialog/check-lxdialog.sh
라는 쉘 스크립트의 내용을 수정해야 해결할 수 있다. 50번째 라인을 아래와 같이 수정한다:
make O=build/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
수정한 뒤에 menuconfig
을 입력하면 정상적으로 다이얼로그가 나오는 것을 확인할 수 있다.
그 다음으로 할 일은 몇 가지 설정을 변경하는 것이다:
Networking Utilities -> tc [ ]
Settings -> Build static binary (no shared libs) [*]
Settings -> SHA1 [ ] : Use hardware accelerated instructions if possible
Settings -> SHA256 [ ] : Use hardware accelerated instructions if possible
다음과 같이 언/체크한다.
networking/tls_aesgcm.c
파일에 9~11 번 라인을 추가로 작성해준다. LONG_BIT
가 정의되지 않아서 발생하는 문제인데 그냥 직접 정의해도 별 문제 없다.
rootfs
생성make O=build/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
경고가 조금 발생하긴 하지만 빌드는 문제없이 잘 된다. 이제 make install
을 통해 rootfs
를 생성하면 된다.
make O=build/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- CONFIG_PREFIX=install/ install
이제 build/install
디렉토리로 들어가면 bin
, linuxrc
, sbin
, usr
디렉토리를 확인할 수 있다.
initramfs
만들기이제 이 rootfs
에 몇 가지 파일과 디렉토리를 추가해볼 것이다.
mkdir proc sys dev etc etc/init.d
ln -s bin/busybox init
touch etc/init.d/rcS
chmod +x etc/init.d/rcS
etc/init.d/rcS
파일의 내용을 이하와 같이 구성한다:
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
exec /bin/sh
최종적으로 다음과 같이 구성하면 끝난다. 이제 이 파일들을 그러모아서 하나의 initramfs
파일을 만들면 된다.
find . | cpio -o -H newc | gzip > ../../initramfs.cpio.gz
QEMU
로 실행하기qemu-system-aarch64 -M virt -cpu cortex-a57 -kernel <Image> -nographic -initrd <initramfs.cpio.gz>
끝!