head.S 를 분석하거나, main.c의 start_kernel함수를 분석하는 과정에서 특정 변수나 레지스터의 값을 확인하고 싶을 때가 있습니다. GDB를 사용하면 자신이 분석중인 커널소스를 기준으로 라인바이 라인으로 이동하며 변수나 레지스터의 값들을 확인할 수 있습니다.
단지 커널소스 분석을 위해서라면 GDB + QEMU + kernel만 있어도 됩니다. 하지만 나중을(?) 위해서 BUILDROOT rootfs를 사용하여 커맨드라인까지 떨어지는 과정을 진행하려고 합니다.
시스템 환경
이 문서 내용들은 Ubuntu 20.04에서 진행되었습니다.
QEMU + BUILDROOT(+GDB) 환경 설치
필수 패키지 설치
터미널을 열어 아래 명령을 실행합니다. qemu-system-arm의 경우 내부 패키지에 qemu-system-aarch64 바이너리가 포함되어 있습니다.
$ sudo apt install git libncurses-dev qemu-system-arm build-essential
Buildroot source 다운로드
이 문서에서가 작성된 날짜 기준으로 최신 브랜치인 2021.02.x를 가져왔습니다.
$ git clone https://github.com/buildroot/buildroot.git -b 2021.02.x
cd build root
virt 머신으로 default config 구성
$ make qemu_aarch64_virt_defconfig
kernel 5.1 분석을 위해 configuration 변경
$ make menuconfig
아래와 같이 변경후 저장합니다. 특정 커널버전 선택을 위해 5.1.x kernel header를 선택하였으며, github 주소, 특정 브랜치(v5.1), 특정 시점의 commit id를 적용하였습니다.
Toolchain --->
C library (glib)
Custom kernel headers series (5.1.x)
[*] Build cross gdb for the host
[*] TUI support
Python support (Python 3)
[*] Simulator support
Kernel --->
Kernel version (Custom Git repository)
(https://github.com/iamroot16/linux) URL of custom repository
(v5.1-study) Custom repository version
(e93c9c99a629c61837d5a7fc2120cd2b6c70dbdd) Custom kernel patches
Build
아래와 같은 명령으로 빌드를 진행합니다. 시스템에 따라 약 15~30분이 걸립니다. 제 시스템의 경우 코어가 4개라서 -j5 옵션을 주었습니다.
$ make -j5
kernel, rootfs 경로 확인
나중에 QEMU 실행과 gdb 실행을 위해 경로를 확인해둡니다. 빌드한 kernel, rootfs 이미지는 아래 경로에 있습니다.
kernel : Image, rootfs : rootfs.ext4
$ ls output/images/
toolchain, kernel source 경로 확인
$ ls output/host/bin/
$ ls output/build/linux-v5*
QEMU 실행
빌드한 kernel, rootfs를 사용하여 QEMU를 실행합니다. 옵션이 많으니 스크립트로 만들어서 실행하겠습니다.
run_qemu.sh 파일을 만들어 아래 내용을 복사합니다.
#!/bin/bash
qemu-system-aarch64 \
-kernel ./output/images/Image \
-M virt \
-smp 1 -m 1024 -cpu cortex-a57 \
-append "rw root=/dev/vda console=ttyAMA0 loglevel=8 rootwait fsck.repair=yes memtest=1" \
-drive file=./output/images/rootfs.ext4,if=none,id=hd0 \
-device virtio-blk-device,drive=hd0 \
-netdev user,id=net0,hostfwd=tcp::5022-:22 \
-device virtio-net-device,netdev=net0 \
-no-reboot \
--nographic \
아래와 같이 실행합니다.
$ chmod +x run_qemu.sh
$ ./run_qemu.sh
아래와 같이 정상적으로 부팅하는 모습을 볼 수 있습니다.
Booting Linux on physical CPU 0x0000000000 [0x411fd070]
Linux version 5.1.0 (gcc version 9.3.0 (Buildroot 2021.02.1-137-g8efa1a303f)) #1 SMP Wed May 5 22:53:05 KST 2021
Machine model: linux,dummy-virt
efi: Getting EFI parameters from FDT:
efi: UEFI not found.
On node 0 totalpages: 262144
DMA32 zone: 4096 pages used for memmap
DMA32 zone: 0 pages reserved
DMA32 zone: 262144 pages, LIFO batch:63
중략...
Starting network: udhcpc: started, v1.33.0
udhcpc: sending discover
udhcpc: sending select for 10.0.2.15
udhcpc: lease of 10.0.2.15 obtained, lease time 86400
deleting routers
adding dns 10.0.2.3
OK
Welcome to Buildroot
buildroot login:
다음장에서는 GDB를 사용해 head.S 또는 main.c의 start_kernel 분석과정을 보겠습니다.
Comments