QEMU에서 브레이크 안걸고 리눅스 커널을 실행하면 rootfs가 없다고 나온다.
여러 가지 방법으로 rootfs를 만들 수 있는데, 그 중 가장 간단한 busybox를 이용한 방법을 정리하였다.
호스트 머신은 x86_64 Ubuntu이며, 타겟 머신은 aarch64이다.
Busybox를 Git에서 내려받는다.
apt update
apt install -y git
git clone git://busybox.net/busybox.git
cd busybox
빌드할 Busybox의 버전을 정해야 하는데, 아래 명령어로 최근 10개의 버전을 확인할 수 있다.
git branch -a --sort=-committerdate | grep "stable" | head -10
2022년 9월 13일 기준 실행하면 아래와 같이 출력된다.
remotes/origin/1_35_stable
remotes/origin/1_33_stable
remotes/origin/1_34_stable
remotes/origin/1_32_stable
remotes/origin/1_31_stable
remotes/origin/1_30_stable
remotes/origin/1_29_stable
remotes/origin/1_28_stable
remotes/origin/1_24_stable
아래 명령어를 이용하여 원하는 버전으로 전환할 수 있다.
git checkout 1_35_stable
빌드에 필요한 패키지를 설치한다.
apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu \
cscope libssl-dev libncurses-dev \
autoconf automake autotools-dev curl libmpc-dev libmpfr-dev \
libgmp-dev gawk build-essential bison flex texinfo \
gperf libtool patchutils bc zlib1g-dev libexpat-dev \
cpio
한 줄씩 따라서 입력한다.
defconfig를 수행한다.
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
실행하면 아래와 같이 출력된다.
HOSTCC scripts/basic/fixdep
HOSTCC scripts/basic/split-include
HOSTCC scripts/basic/docproc
...
Circular Buffer support (FEATURE_IPC_SYSLOG) [Y/n/?] (NEW) y
Circular buffer size in Kbytes (minimum 4KB) (FEATURE_IPC_SYSLOG_BUFFER_SIZE) [16] (NEW) 16
Linux kernel printk buffer support (FEATURE_KMSG_SYSLOG) [Y/n/?] (NEW) y
menuconfig를 수행한다.
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
Busybox 빌드 시에는 menuconfig에서 아래 두 가지를 수행해야 한다.
2번은 원한다면 설정을 바꾸어도 되고, 그냥 경로만 확인해도 된다.
실행하면 아래와 같이 출력된다.
HOSTLD scripts/kconfig/mconf
HOSTCC scripts/kconfig/lxdialog/checklist.o
HOSTCC scripts/kconfig/lxdialog/inputbox.o
HOSTCC scripts/kconfig/lxdialog/lxdialog.o
HOSTCC scripts/kconfig/lxdialog/menubox.o
HOSTCC scripts/kconfig/lxdialog/msgbox.o
HOSTCC scripts/kconfig/lxdialog/textbox.o
HOSTCC scripts/kconfig/lxdialog/util.o
HOSTCC scripts/kconfig/lxdialog/yesno.o
HOSTLD scripts/kconfig/lxdialog/lxdialog
scripts/kconfig/mconf Config.in
#
# using defaults found in .config
#
*** End of configuration.
*** Execute 'make' to build the project or try 'make help'.
make를 수행한다.
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
실행하면 아래와 같이 출력된다.
SPLIT include/autoconf.h -> include/config/*
GEN include/bbconfigopts.h
GEN include/common_bufsiz.h
...
Library m is needed, can't exclude it (yet)
Library resolv is needed, can't exclude it (yet)
Final link with: m resolv
마지막 줄에 can't exclude it
라고 뜨길래 에러인 줄 알았는데, 찾아보니 아니라고 한다.
make install을 수행한다.
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- install
실행하면 아래와 같이 출력된다.
./_install//bin/arch -> busybox
./_install//bin/ash -> busybox
./_install//bin/base32 -> busybox
...
--------------------------------------------------
You will probably need to make your busybox binary
setuid root to ensure all configured applets will
work properly.
--------------------------------------------------
아까 menuconfig에서 install 경로가 _install
인 것을 확인했다.
_install
디렉토리 안에 보면 산출물이 생성된 것을 볼 수 있다.
cd _install
ls
마무리 작업을 진행하고 rootfs를 만들면 된다.
_install
안에서 나머지 디렉토리들을 만들어준다.
mkdir -p dev etc/init.d home/root lib mnt proc root sys tmp usr/lib var
그리고 아래 명령어들을 실행한다.
echo -e '#!/bin/bash\nmount -t proc none /proc\nmount -t sysfs none /sys\n/sbin/mdev -s' > etc/init.d/rcS
chmod +x etc/init.d/rcS
find . | cpio -o --format=newc > ../rootfs.cpio
cd ..
gzip -c rootfs.cpio > ~/rootfs.cpio.gz
cd ~
그러면 사용자 home 디렉토리에 rootfs.cpio.gz가 생성된 것을 볼 수 있다.
빌드해놓은 커널 이미지가 있다면 QEMU로 rootfs와 함께 실행해볼 수 있다.
apt install qemu qemu-system-aarch64
qemu-system-aarch64 \
-M virt \
-cpu cortex-a57 \
-smp 1 \
-m 512 \
-nographic \
-kernel ./Image \
-initrd ./rootfs.cpio.gz \
-append "rdinit=/linuxrc console=ttyAMA0" \
-device virtio-scsi-device
입력하면 QEMU가 실행이 되는 것을 볼 수 있는데,
갑자기 컴퓨터에서 QEMU가 멈춰서...
실행 결과를 첨부할 수가 없게 되었다..!