返回

基于qemu+gdb,调试aarch64 linux内核

 

在之前搭建好aarch64工作环境的基础上,可以进行一系列开发调试工作,本文记录在qemu上使用gdb调试aarch64架构的linux内核代码。

调试环境

  • rootfs: 基于BusyBox 1.34.1,自制
  • linux: 6.0.12
  • qemu: 7.2.0
  • gdb: 12.1
  • 运行环境:win11下的wsl2

linux 编译

wget https://mirrors.edge.kernel.org/pub/linux/kernel/v6.x/linux-6.0.12.tar.gz
tar -xvf linux-6.0.12.tar.gz
cd linux-6.0.12
make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 defconfig

关闭地址随机化

make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 menuconfig

Kernel Features --->
	[ ] Randomize the address of the kernel image

编译

make -j64

自制rootfs根文件系统

编译 busybox

# 下载
wget https://busybox.net/downloads/busybox-1.34.1.tar.bz2
tar xvf busybox-1.34.1.tar.bz2
cd busybox-1.34.1

# aarch64 config
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig

# 设置为静态链接
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig

Settings  --->
		[*] Build static binary (no shared libs)

# 编译
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j64

制作rootfs

# 创建一个大小为64M,格式为ext4的rootfs镜像
dd if=/dev/zero of=rootfs.img bs=1M count=64
mkfs.ext4 rootfs.img

# 将rootfs镜像挂载到rootfs目录(挂载点),方便操作镜像内容
make rootfs
sudo mount -t ext4 -o loop rootfs.img ./rootfs

# 将编译好的busybox安装到rootfs中,其实大部分也是复制操作,只是make install会根据根目录下的Makefile中的install目标,来执行指定操作。
sudo make install CONFIG_PREFIX=./rootfs
cd rootfs

# 创建必要的系统目录
sudo mkdir proc dev etc home mnt tmp run sys dev/pts dev/shm
# 复制必要的自启动脚本
sudo cp -r ../examples/bootfloppy/etc/* etc/

# 解挂载
cd ..
sudo umount rootfs

run

/home/hyrtee/qemu/qemu-7.2.0/build/qemu-system-aarch64 \
	-machine virt -cpu cortex-a57 -machine type=virt -nographic -smp 4 -m 2048 \
	--kernel /home/hyrtee/qemu/linux-6.0.12/arch/arm64/boot/Image \
	--initrd /home/hyrtee/qemu/busybox-1.34.1/rootfs.img \
	--append 'root=/dev/ram init=/linuxrc console=ttyAMA0 nokaslr'

debug

add -s -S at qemu boot parameters, run qemu.

/home/hyrtee/qemu/qemu-7.2.0/build/qemu-system-aarch64 \
	-machine virt -cpu cortex-a57 -machine type=virt -nographic -smp 4 -m 2048 -s -S \
	--kernel /home/hyrtee/qemu/linux-6.0.12/arch/arm64/boot/Image \
	--initrd /home/hyrtee/qemu/busybox-1.34.1/rootfs.img \
	--append 'root=/dev/ram init=/linuxrc console=ttyAMA0 nokaslr'

open a new terminal, input:

gdb-multiarch --ex "target remote:1234"

(gdb) add-symbol-file ~/qemu/linux-6.0.12/vmlinux
(gdb) b start_kernel
(gdb) c

Q&A

VFS: Unable to mount root fs on unknown-block(1,0)

you may need reconfig kernel, run make menuconfig at kernel root dir, then set the following config:

-> Device Drivers
  │ -> Block devices
	<*>   RAM block device support
	│ │ (16)    Default number of RAM disks
	│ │ (131072) Default RAM disk size (kbytes)

then set root=/dev/ram at kernel command line.

Requested init /init failed (error -8)

busybox should be built to Arm64 platform, instead of x86-64 default. So rebuild and re-compile it.

refs

https://www.expoli.tech/articles/2023/07/05/QEMU-debugging-Linux-kernel-environment-construction#8d170449343c448d8b2938544218c788

https://ibug.io/blog/2019/04/os-lab-1/

http://loverpi.wikidot.com/faq:sbc:libre-aml-s805x-minimal-rootfs

http://loverpi.wikidot.com/faq:sbc:libre-aml-s805x-minimal-rootfs

Licensed under CC BY-NC-SA 4.0
Built with Hugo
主题 StackJimmy 设计
© Licensed Under CC BY-NC-SA 4.0