在之前搭建好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://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