在之前有写如何使用vmware + ubuntu + qemu + busybox + gdb 调试linux x86内核,由于日常使用的系统是arm64内核,所以总结一下使用qemu调试arm64。

1、参考文档

其实在搭建这个环境的时候,折腾了很久,参考其他文档一直有一些奇奇怪怪的问题,最后在这篇文章的帮助下成功搭建,感谢分享。

VSCode+GDB+Qemu调试ARM64 lin架构ux内核

2、安装编译工具链

首先需要确保ubuntu网络连接正常,可参考:关于多个ubuntu虚拟HTTP机同时联网的问题变量类型有哪些

由于Ubuntu变量英语是X86架构,为了编译arm64的文件,需要安装交叉编译工具链:

sudo apt-get install gcc-aarch64-linux-gnu
sudo apt-get install libncurses5-dev  build-essential git bison flex libssl-dev

3、制作根文件系统

wget  https://busybox.net/downloads/busybox-1.34.1.tar.bz2
tar -xjf busybox-1.34.1.tar.bz2
mv busybox-1.34.1 busybox-1.34.1-arm64

打开静态库编译选项:

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

指定编译工具:

export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-

编译:

make
make install

编译完http协议成,在busybox目录下生成_in变量名的命名规则stall目镜像翻转怎么弄录:

vmware + ubuntu + qemu + busybox + gdb 调试linux arm64内核

为了init进程能正常启动, 需要再额外进行一些配置。

根目录添加etc、dev和lib目录
idle@ubuntu:~/study/busybox-1.34.1-arm64/_install$ mkdir etc dev lib

vmware + ubuntu + qemu + busybox + gdb 调试linux arm64内核

在etc分别创建文件:

idle@ubuntu:~/study/busybox-1.34.1-arm64/_install$ cd etc/
$ vim profile
#!/bin/sh
export HOSTNAME=idle
export USER=root
export HOME=/home
export PS1="[$USER@$HOSTNAME W]# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
$ vim inittab
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
$ vim fstab
#device  mount-point    type     options   dump   fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
debugfs /sys/kernel/debug debugfs defaults 0 0
kmod_mount /mnt 9p trans=virtio 0 0
$ mkdir init.d
cd init.d
vim rcS
$ cat init.d/rcS
mkdir -p /sys
mkdir -p /tmp
mkdir -p /proc
mkdir -p /mnt
/bin/mount -a
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
chmod 777 init.d/rcS
idle@ubuntu:~/study/busybox-1.34.1-arm64/_install/etc$ ls
fstab  init.d  inittab  profile

这里对这几个文件做一点说明:

  1. busybox 作为linuxrc启动后, 会读取/etc/profile, 这里面设置了一些环境变量名和shell的属性
  2. 根据/etc/fstab提供的挂载Linux信息, 进行文件系统的挂载
  3. busybox 会从 /etc/inittab中读取sysinit并执行, 这里sysinit指向了/etc/init.d/rcS
  4. /etc/init.d/rcS 中 ,mdev -s 这条命令很重要, 它会扫描/sys目录,查找字符设备和块设备,并在/dev下mknod

dev目录:

idle@ubuntu:~/study/busybox-1.34.1-arm64/_install$ cd dev
$ sudo mknod console c 5 1

这一步很重要, 没有console这个文件, 用户态的输变量泵出没法打印到串口上

lib目录:拷贝lib库,支持动态架构编译的应用程序运行

idle@ubuntu:~/study/busybox-1.34.1-arm64/_install$ cd lib
cp /usr/aarch64-linux-gnu/lib/*.so*  -a .

vmware + ubuntu + qemu + busybox + gdb 调试linux arm64内核

4、编译内核

linux源码获取 ,选择linux-4.9.镜像干部130.tar.xz,解压到linux-4.9.130-arm64

idle@ubuntu:~/study/linux-4.9.130-arm64$ vim arch/arm64/configs/defconfig
# 添加如下配置:
CONFIG_DEBUG_INFO=y 
CONFIG_INITRAMFS_SOURCE="./root"
CONFIG_INITRAMFS_ROOT_UID=0
CONFIG_INITRAMFS_ROOT_GID=0
make defconfig ARCH=arm64

CONFIG_DEBUG_INFO是为了方httpwatch便调试,CONFIG_IN变量值ITRAMFS_SOURCE是指定kernel ramdisk的位置,这样指定之变量名后ramdisk会直接被编译到kerHTTPnel 镜像中。根据arch/arm64/configs/defc变量类型有哪些onfig 文件会生成.config。

我们将之前制作好的根文件系统cp到root目录下:

cp -r ../busybox-1.34.1-arm64/_install root

查看linux-4.9.130-ar变量之间的关系m64/root/dev下是否有console文件,没有的话在dev目录下使用sud镜像人生o mknod cons架构图怎么制作ole c 5 1再创建一遍。

执行编译:

make ARCH=arm64 Image -j8  CROSS_COMPILE=aarch64-linux-gnu-

这里指定target为Image 会只编译kernel, 不会编译modules, 这样会增加编译速度。

5、下载qemu

需要注意的,qemu最好源码编译, 用apt-get直接安装的qemu可能版本过低,导致无法启动arm64内核。选用使用4.2.1版本的qemu:

apt-get install build-essential zlib1g-dev pkg-config libglib2.0-dev binutils-dev libboost-all-dev autoconf libtool libssl-dev libpixman-1-dev libpython-dev python-pip python-capstone virtualenv
wget https://download.qemu.org/qemu-4.2.1.tar.xz
tar xvJf qemu-4.2.1.tar.xz
cd qemu-4.2.1
./configure --target-list=x86_64-softmmu,x86_64-linux-user,arm-softmmu,arm-linux-user,aarch64-softmmu,aarch64-linux-user --enable-kvm
make 
sudo make install

如果下载有问题,可查看网络与slinux必学的60个命令ources.list配置源。

编译完成之后http://192.168.1.1登录,查看linux常用命令qemu架构工程师-aarch64 版本:

idle@ubuntu:~/study$ qemu-aarch64 -version
qemu-aarch64 version 4.2.1
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers

6、启动linux内核

idle@ubuntu:~/study/linux-4.9.130-arm64$ qemu-system-aarch64 -m 512M -smp 4 -cpu cortex-a57 -machine virt -kernel arch/arm64/boot/Image -append "rdinit=/linuxrc nokaslr console=ttyAMA0 loglevel=8" -nographic -s

这里对于参数做一些解释:

  • -m 512M内存为512M
  • -smp 44核
  • -cpu cortex-a57cpu 为cortex-a57
  • -kernelkernel镜像文件
  • -appe架构师证书nd传给kernel 的cmhttp协议dl变量与函数ine参数。其中rdinit指定了init进程;noka架构师证书slr 禁止内核起始地址随机化,这个很重要, 否则GDB调试可能有问题;chttp://192.168.1.1登录onsole=ttyAMA镜像投屏0指定了串口,没有这一步就看不到linux的输出;
  • -nographic禁止图形输出
  • -s监听gdb端口, gdb程序可以通过1Linux234这个端口连上来。

vmware + ubuntu + qemu + busybox + gdb 调试linux arm64内核