首页 > 其他分享 >使用qemu搭建ARM64调试环境,支持文件共享,支持gdb调试

使用qemu搭建ARM64调试环境,支持文件共享,支持gdb调试

时间:2022-12-13 20:36:32浏览次数:88  
标签:文件共享 -- work leon gdb so dev Linux 调试


环境

主机ubuntu版本: 20.04
qemu模拟处理器:ARM64
Linux内核版本:https://www.kernel.org/ 最新版

step1:安装编译工具链

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

查看版本号

leon@leon:~/work$ aarch64-linux-gnu-gcc -v
Using built-in specs.
COLLECT_GCC=aarch64-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/aarch64-linux-gnu/9/lto-wrapper
Target: aarch64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.3.0-10ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --without-target-system-zlib --enable-libpth-m2 --enable-multiarch --enable-fix-cortex-a53-843419 --disable-werror --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=aarch64-linux-gnu --program-prefix=aarch64-linux-gnu- --includedir=/usr/aarch64-linux-gnu/include
Thread model: posix
gcc version 9.3.0 (Ubuntu 9.3.0-10ubuntu1)

step2:安装qemu

sudo apt-get install qemu-system-arm

查看版本:

leon@leon:~/work$ qemu-system-aarch64 --version
QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.16)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
leon@leon:~/work$

step3:制作根文件系统rootfs

3.1 下载busybox源码:

官网:​​http://busybox.net/downloads/​​ 下载最新版本即可,这里

tar jxvf busybox-1.33.1.tar.bz2

3.2 配置busybox

指定编译工具

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

打开静态库编译选项

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

如果报错:

<command-line>: fatal error: curses.h: No such file or directory
compilation terminated.

安装ncurses库

sudo apt-get install libncurses5-dev libncursesw5-dev

3.3 编译

make
make install

PS:编译过程报错的话,把相应项去掉即可;

编译完成,在busybox生成_install目录

3.4 补充rootfs目录结构

(1) 根目录添加etc、dev和lib目录

etc目录:

leon@leon:~/work/Linux/busybox-1.33.1/_install$ ls
bin linuxrc sbin usr
leon@leon:~/work/Linux/busybox-1.33.1/_install$ mkdir etc dev lib
leon@leon:~/work/Linux/busybox-1.33.1/_install$ ls
bin dev etc lib linuxrc sbin usr
leon@leon:~/work/Linux/busybox-1.33.1/_install$

在etc分别创建文件:

leon@leon:~/work/Linux/busybox-1.33.1/_install/etc$ cat profile 
#!/bin/sh
export HOSTNAME=myQEMU
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
leon@leon:~/work/Linux/busybox-1.33.1/_install/etc$ cat 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
leon@leon:~/work/Linux/busybox-1.33.1/_install/etc$ cat inittab 
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r

指定挂载的文件系统

leon@leon:~/work/Linux/busybox-1.33.1/_install/etc/init.d$ cat 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
leon@leon:~/work/Linux/busybox-1.33.1/_install/etc/init.d$

dev目录:

leon@leon:~/work/Linux/busybox-1.33.1/_install/dev$ sudo mknod console c 5 1
leon@leon:~/work/Linux/busybox-1.33.1/_install/dev$ sudo mknod null c 1 3
leon@leon:~/work/Linux/busybox-1.33.1/_install/dev$

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

leon@leon:~/work/Linux/busybox-1.33.1/_install/lib$ cp /usr/aarch64-linux-gnu/lib/*.so*  -a .
leon@leon:~/work/Linux/busybox-1.33.1/_install/lib$ ls
ld-2.31.so libdl-2.31.so libnsl.so libnss_nisplus-2.31.so libSegFault.so
ld-linux-aarch64.so.1 libdl.so libnsl.so.1 libnss_nisplus.so libstdc++.so.6
libanl-2.31.so libdl.so.2 libnss_compat-2.31.so libnss_nisplus.so.2 libstdc++.so.6.0.28
libanl.so libgcc_s.so.1 libnss_compat.so libnss_nis.so libthread_db-1.0.so
libanl.so.1 libgomp.so.1 libnss_compat.so.2 libnss_nis.so.2 libthread_db.so
libasan.so.5 libgomp.so.1.0.0 libnss_dns-2.31.so libpcprofile.so libthread_db.so.1
libasan.so.5.0.0 libitm.so.1 libnss_dns.so libpthread-2.31.so libtsan.so.0
libatomic.so.1 libitm.so.1.0.0 libnss_dns.so.2 libpthread.so libtsan.so.0.0.0
libatomic.so.1.2.0 liblsan.so.0 libnss_files-2.31.so libpthread.so.0 libubsan.so.1
libBrokenLocale-2.31.so liblsan.so.0.0.0 libnss_files.so libresolv-2.31.so libubsan.so.1.0.0
libBrokenLocale.so libm-2.31.so libnss_files.so.2 libresolv.so libutil-2.31.so
libBrokenLocale.so.1 libmemusage.so libnss_hesiod-2.31.so libresolv.so.2 libutil.so
libc-2.31.so libm.so libnss_hesiod.so librt-2.31.so libutil.so.1
libc.so libm.so.6 libnss_hesiod.so.2 librt.so
libc.so.6 libnsl-2.31.so libnss_nis-2.31.so librt.so.1
leon@leon:~/work/Linux/busybox-1.33.1/_install/lib$

step4 编译内核

(1)下载代码:

#我从torvalds的仓库fork了一个分支,方便自己添加注释笔记
git clone https://github.com/luteresa/linux.git

(2) 指定编译工具:

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

配置内核:
这里采用ARM公司提供的Versatile Express开发平台模拟;

sudo cp ../busybox-1.33.1/_install/  ./_install_arm64 -a
cp arch/arm/configs/vexpress_defconfig .config
make menuconfig

添加hotplug支持:

Device Drivers                                                                                              
-> Generic Driver Options
-> Support for uevent helper
(/sbin/hotplug) path to uevent helper

添加initramfs的支持:

General setup --->
[*]Initial RAM filesystem and RAM disk(initramfs/initrd) support(_install_arm64) Initramfs souce file(s)

内核页分别配置为

Kernel Features  --->
Page size(4KB) --->
Virtual address space size(48-bit)--->

编译:

make all -j8

在内核根目录下添加共享目录

mkdir kmodules

启动Linux:

qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine type=virt -m 1024 -smp 4 -kernel arch/arm64/boot/Image --append "rdinit=/linuxrc root=/dev/vda rw console=ttyAMA0 loglevel=8"  -nographic --fsdev local,id=kmod_dev,path=$PWD/kmodules,security_model=none -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_mount

-cpu指定模拟的cpu为 cortex-a57,
-m 1024 指定内存大小为1G,
-smp4指定模拟的系统为4核处理器 ,
-kernel指定启动的内核镜像,
–append指定传递的命令行参数,
后面的选项指定共享目录已经使用的9P协议。

报错:

mount: mounting debugfs on /sys/kernel/debug failed: No such file or directory

内核配置加上CONFIG_DEBUG_FS=y :

Kernel hacking  ---> 
Generic Kernel Debugging Instruments --->
[*] Debug Filesystem

step5: 使用模拟磁盘

上述initramfs的方式,将根文件系统打包到内核源码,运行时都是在内存中,可以操作,但系统重启就会丢失,下面用模拟磁盘方式挂载根文件系统。
制作磁盘文件:

dd if=/dev/zero of=rootfs_ext4.img bs=1M count=1024
mkfs.ext4 rootfs_ext4.img
mkdir -p tmpfs
sudo mount -t ext4 rootfs_ext4.img tmpfs/ -o loop
sudo cp -af _install_arm64/* tmpfs/
sudo umount tmpfs
chmod 777 rootfs_ext4.img

rootfs_ext4.img就是即将用来挂载的磁盘;
再次启动内核:

qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine type=virt -m 1024 -smp 4 -kernel arch/arm64/boot/Image --append "noinitrd root=/dev/vda rw console=ttyAMA0 loglevel=8"  -nographic -drive if=none,file=rootfs_ext4.img,id=hd0 -device virtio-blk-device,drive=hd0 --fsdev local,id=kmod_dev,path=$PWD/kmodules,security_model=none -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_mount

传递给内核的命令行参数变化了,添加了noinitrd选项,这样就会挂载我们自己的模拟磁盘。

[root@myQEMU ]# df -mh
Filesystem Size Used Available Use% Mounted on
/dev/root 975.9M 12.8M 895.9M 1% /
tmpfs 496.1M 0 496.1M 0% /tmp
tmpfs 496.1M 0 496.1M 0% /dev
kmod_mount 981.8G 32.5G 899.4G 3% /mnt
[root@myQEMU ]#

这样在文件系统的读写,就会存在磁盘,重启后,数据不会丢失。

step6: qemu与主机ubuntu文件共享

前面已经支持了主机和qemu上的系统共享目录,这个目录就是kmodules目录:
通过mount可以查看被挂载到了qemu上的系统的/mnt目录下

[root@myQEMU mnt]# mount
/dev/root on / type ext4 (rw,relatime)
proc on /proc type proc (rw,relatime)
tmpfs on /tmp type tmpfs (rw,relatime)
sysfs on /sys type sysfs (rw,relatime)
tmpfs on /dev type tmpfs (rw,relatime)
kmod_mount on /mnt type 9p (rw,sync,dirsync,relatime,access=client,trans=virtio)
devpts on /dev/pts type devpts (rw,relatime,mode=600,ptmxmode=000)

在ubuntu的kmodules目录,创建一个文件hello.c

#include <stdio.h>

int main(int argc, char **argv)
{
printf("Hello World,Qemu!\n");

return 0;
}

在qemu查看

[root@myQEMU mnt]# cat /proc/cpuinfo  > cpu.txt
[root@myQEMU mnt]# cat hello.c
#include <stdio.h>
int main(int argc, char **argv)
{
printf("Hello World,Qemu!\n");
return 0;
}
random: fast init done
[root@myQEMU mnt]#

在ubuntu编译,

aarch64-linux-gnu-gcc  hello.c

在qemu运行,

[root@myQEMU mnt]# ./a.out 
Hello World,Qemu!
[root@myQEMU mnt]#

可见,在共享目录,可以执行含动态库的应用程序;

step7:内核模块测试:

Makefile文件,

KERNEL_DIR ?= ~/work/Linux/linux
obj-m := module_test.o
modules:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean
install:
cp *.ko $(KERNEL_DIR)/kmodules

驱动测试文件model_test.c,

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int __init module_test_init(void)
{
printk("---module_test_init\n");
return 0;
}

static void __exit module_test_exit(void)
{
printk("---module_test_exit\n");
}


module_init(module_test_init);
module_exit(module_test_exit);
MODULE_LICENSE("GPL");

在ubuntu上交叉编译

leon@leon:~/work/Linux/linux/kmodules$ make
make -C ~/work/Linux/linux M=/home/leon/work/Linux/linux/kmodules modules
make[1]: Entering directory '/home/leon/work/Linux/linux'
CC [M] /home/leon/work/Linux/linux/kmodules/module_test.o
MODPOST /home/leon/work/Linux/linux/kmodules/Module.symvers
CC [M] /home/leon/work/Linux/linux/kmodules/module_test.mod.o
LD [M] /home/leon/work/Linux/linux/kmodules/module_test.ko
make[1]: Leaving directory '/home/leon/work/Linux/linux'
leon@leon:~/work/Linux/linux/kmodules$

在qemu加载驱动

[root@myQEMU mnt]# insmod module_test.ko 
---module_test_init.
[root@myQEMU mnt]# rmmod module_test
---module_test_exit.
[root@myQEMU mnt]#

可见,内核模块正常运行了。

step8:gdb调试

安装arm-none-eabi-gdb
​​​https://askubuntu.com/questions/1243252/how-to-install-arm-none-eabi-gdb-on-ubuntu-20-04-lts-focal-fossa​

sudo apt-get install gdb-multiarch

qemu模拟端启动内核:

qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine type=virt -m 1024 -smp 4 -kernel arch/arm64/boot/Image --append "rdinit=/linuxrc root=/dev/vda rw console=ttyAMA0 loglevel=8"  -nographic --fsdev local,id=kmod_dev,path=$PWD/k_shared,security_model=none -device virtio-9p-device,fsdev=kmod_dev,mount_tag=kmod_mount  -S  -s

X86启动gdb:

$ gdb-multiarch --tui vmlinux
(gdb)target remote localhost:1234  //通过1234端口远程连接到qemu端
(gdb)b start_kernel //在内核的start_kernel设置断点
(gdb)c

如图,gdb接管linux内核,在断点处(start_kernel)暂停,即可通过gdb来调试内核。

使用qemu搭建ARM64调试环境,支持文件共享,支持gdb调试_qemu文件共享


标签:文件共享,--,work,leon,gdb,so,dev,Linux,调试
From: https://blog.51cto.com/u_7784550/5935033

相关文章

  • VS编译器实用调试技巧
    一、Debug和Release的区别debug通常称为调试版本,它包含调试信息,并且不做任何优化,便于程序员调试程序。release称为发布版本,他往往是进行了各种优化,使得程序在代码大小和运行......
  • 【生产】钉钉告警安装 以及调试
    ​​前提条件Prometheus+Grafana+alertmanager+邮件​​钉钉告警安装下载去官网下载​​prometheus-webhook-dingtalk-2.1.0.linux-amd64.tar.gz​​wgethttps://github.c......
  • Linux GDB Debugging
    LinuxGDBDebuggingCatalog1.GDBIntroduction2.GDB基本命令 1.GDBIntroductionGDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具,GDB主......
  • 使用 IDA 和 windbg 调试 LNK1123 转换到 COFF 期间失败:文件无效或损坏(中)
    使用IDA和windbg调试LNK1123转换到COFF期间失败:文件无效或损坏(中)原总结排错processmonitorvsIDAwindbg调试rcCVT1101LNK1123前言在​​上一篇文章​​​中,我们......
  • 记一次 .NET 程序的性能优化实战(4)—— .NET 源码查看及使用 vs 调试
    记一次.NET程序的性能优化实战(4)——.NET源码查看及使用vs调试原总结工具调试dotNETpart4regex正则表达式vsdnspy前言在前面三篇文章中应该已经把​​.NET​​中正......
  • 虚拟机UOS和windows文件共享
    统信uos系统访问windows共享文件夹步骤:1、找到网络邻居中的window网络(刚开始一打开就为空,我以为是装饰,一直没有用),并双击打开,如下图所示;2、在打开的文件夹里选择右上角的......
  • 【分享】FD js本地调试文件替换后CROS跨域错误
    <table><tr><tdbgcolor=orange>本文所有教程及源码、软件仅为技术研究。不涉及计算机信息系统功能的删除、修改、增加、干扰,更不会影响计算机信息系统的正常运行。不得将代......
  • 【分享】FD js本地调试文件替换后CROS跨域错误
    本文所有教程及源码、软件仅为技术研究。不涉及计算机信息系统功能的删除、修改、增加、干扰,更不会影响计算机信息系统的正常运行。不得将代码用于非法用途,如侵立删!FDjs......
  • [linux下c++ debug神器]vscode+gdb(debug console下使用)
    不推荐直接用gdb推荐用vscode+gdb(debugconsole下使用)二者可以优势互补:vscode为gdb提供图形化显示,gdb为vscode提供任意的内存可视化和汇编语句显示。经测试,GDB下命......
  • STM32开发之 VS Code + GDB下载调试
    写在前面:本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。在完成上一篇的ST......