qemu-system-aarch64调试linux-4.12内核

借助Linux操作系统中已有的工具,比如mkinitramfs构建rootfs

前提条件
(0) arm64物理服务器或虚拟机
(1) qemu-2.11.1: qemu-system-aarch64
(2) busybox-1.31.1
(3) 内核版本为linux-4.12

安装qemu

由于qemu的编译过程中存在-CFLAGS=-O2-g将不允许debug信息的出现,因此需要在./configure的时候添加–enable-debug(或–enable-debug --enable-debug-info)选项.为方便以后调试Qemu源码,本次安装将开启debug模式,即在配置选项中增加–enable-debug和–enable-debug-info选项

# ./configure --target-list=aarch64-softmmu, aarch64-linux-user --enable-debug --enable-debug-info

安装busybox

BusyBox配置选项:

# make menuconfig

并有如下设置:
Busybox Settings —>
— Build Options
[*] Build BusyBox as a position independent executable
编译安装

# make -j$(nproc)
# make install -j$(nproc)

制作根文件系统

1. 利用Linux操作系统提供的工具mkinitramfs

# mkinitramfs -o initramdisk

产生制作完成的根文件系统initramdisk,但该文件相对来说还是大了些,接下来将使用自制initramfs的方式创建根文件系统initramfs。

2. 利用busybox制作根文件系统
前提是已经安装了busybox

# cat gen_initramfs.sh
#!/bin/bash
ROOTFS=rootfs
BUSYBOX=$(find busybox* -maxdepth 0 -type d)
SYSROOT=$(gcc --print-sysroot)
GLIBC_VERSION=$(ldd --version | head -1 | cut -d' ' -f5)
DYNAMIC_LIB_PATH_64=/lib/aarch64-linux-gnu

rm -rf $ROOTFS
mkdir -p ${ROOTFS}/{proc,sys,dev,etc,etc/init.d,lib,lib64,mnt,tmp,go}

cat > $ROOTFS/etc/init.d/rcS <<EOF
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s
ifconfig lo up
EOF

chmod +x $ROOTFS/etc/init.d/rcS

cat > $ROOTFS/etc/inittab <<EOF
# /etc/inittab
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
EOF

chmod +x $ROOTFS/etc/inittab

cp -rP ${BUSYBOX}/_install/* ${ROOTFS}

cp -rP ${DYNAMIC_LIB_PATH_64}/libc-${GLIBC_VERSION}.so ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/libc.so.6 ${ROOTFS}/lib64/

cp -rP ${DYNAMIC_LIB_PATH_64}/libm-${GLIBC_VERSION}.so ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/libm.so.6 ${ROOTFS}/lib64/

cp -rP ${DYNAMIC_LIB_PATH_64}/librt-${GLIBC_VERSION}.so ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/librt.so.1 ${ROOTFS}/lib64/

cp -rP ${DYNAMIC_LIB_PATH_64}/libpthread-${GLIBC_VERSION}.so ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/libpthread.so.0 ${ROOTFS}/lib64/

cp -rP ${DYNAMIC_LIB_PATH_64}/ld-${GLIBC_VERSION}.so ${ROOTFS}/lib64/
cp -rP ${DYNAMIC_LIB_PATH_64}/ld-linux-x86-64.so.1 ${ROOTFS}/lib64/

cd ${ROOTFS}
ln -sf linuxrc init
find . | cpio -o --format=newc > ../initramfs

编译Linux内核

# make menuconfig
# make –j$(nproc)

需要重点关注两个文件:vmlinuxImage,分别位于
(1) linux-4.12/vmlinux
(2) linux-4.12/arch/arm64/boot/Image

调试Linux内核

以根文件系统方式启动

# qemu-system-aarch64 -smp 4 -M virt -cpu cortex-a57 -nographic -m 2048M -kernel linux-4.12/arch/arm64/boot/Image -append "console=ttyAMA0" -initrd initramdisk

调试内核
1. 默认添加gdbserver tcp::1234,命令之后添加参数选项 ‘-s’

# qemu-system-aarch64 -nographic  -m 2048M -smp 4 -M virt -cpu host -enable-kvm -kernel linux-4.12/arch/arm64/boot/Image -initrd initramfs -append "console=ttyAMA0 init=/linuxrc rw" -s
# gdb -tui linux-4.12/vmlinux

该方式采用参数选项“-s”,默认添加“gdbserver tcp::1234”的方式,相当于在执行命令时已经启动了gdbserver和监听端口1234,在使用gdb 调试vmlinux时,只需要在gdb中输入"target remote :1234",即可启动调试。

2. 额外添加gdbserver tcp::1234, 命令行之后添加参数选项 ‘-S’

# qemu-system-aarch64 -nographic  -m 2048M -smp 4 -M virt -cpu host -enable-kvm -kernel linux-4.12/arch/arm64/boot/Image -initrd initramfs -append "console=ttyAMA0 init=/linuxrc rw" -S

需要执行两步:
(1) 执行该命令后,需要按组合键“Ctrl + A + C”切换到Monitor模式,并输入gdbserver tcp::1234,然后按Enter键,出现“Waiting for gdb connection on device ‘tcp::1234’”;
(2) 另开一个terminal,在该处执行如下命令

# gdb -tui linux-4.12/vmlinux

然后在加载完内核调试文件后,输入"target remote :1234",对应(1)中设置的端口1234。
两步骤设置完成后,接下来就可以根据需要调试代码。
在这里插入图片描述

参考链接

感谢相关作者!!!
Linux aarch64 编译 & qemu 搭建实验平台.
Linux内存管理之—环境搭建(在QEMU上运行Linux 5.4.0)
ramdisk文件系统制作和移植

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐