• Hello Stock

Linux kernel head.S, main.c 분석하기 (1) (GDB + QEMU + BUILDROOT)

최종 수정일: 2021년 5월 7일

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 분석과정을 보겠습니다.

조회수 449회댓글 0개

관련 게시물

전체 보기