调试Linux内核环境MenuOS系统
一、实验简介
本文采用自己搭建环境的方式对gdb进行了模拟。
(1)工具介绍
1)QEMU介绍
QEMU是一个主机上的VMM(virtual machine monitor),通过动态二进制转换来模拟CPU,并提供一系列的硬件模型,使guest os认为自己和硬件直接打交道,其实是同QEMU模拟出来的硬件打交道,QEMU再将这些指令翻译给真正硬件进行操作。通过这种模式,guest os可以和主机上的硬盘,网卡,CPU,CD-ROM,音频设备和USB等设备进行交互。
2)BusyBox介绍
Busybox中包含了linux中的很多指令,Busybox是一个开源项目,遵循GPL v2协议。Busybox将众多的UNIX命令集合进一个很小的可执行程序中,可以用来替代GNU fileutils、shellutils等工具集。Busybox中各种命令与相应的GNU工具相比,所能提供的选项比较少,但是也足够一般的应用了。
(2)建立环境的几个重要步骤
1)安装编译工具链。
2)安装qemu模拟器
3)编译arm架构内核
4)测试qemu是否正常启动
5)制作文件系统,本实验采用下载下来的根文件系统
6)启动系统,测试gdb的服务端和客户端。
嵌入式开发由以下几个步骤完成。
(3)gdbServer原理
目标机器需要运行程序和 gdbserver,宿主机器需要编译环境代码和 gdb。当完成设置时,gdbserver开始监听1234端口,这个端口号应该是用来和宿主机进行通讯。
嵌入式Linux的GDB调试环境由Host和Target两部分组成,Host端使用arm-linux-gdb,Target Board端使用gdbserver。调试时,应用程序在嵌入式目标系统上运行,而gdb调试在Host端。gdb调试的时候,pc机上的gdb向开发板上的gdbserver发出命令,而开发板上的gdbserver就会向应用程序发出信号,使应用程序停下来或者完成其他一些工作。
host是运行gdb的机器
target是运行gdbserver的机器
gdbserver提供一个网络服务,gdb
remote到gdbserver上后进行调试
二、配置内核
1、下载linux内核
利用linux内核镜像的镜像源,能够利用更快的下载。
https://mirror.bjtu.edu.cn/kernel/linux/kernel/
对下载的文件进行解压处理
xz -d linux-5.0.1.tar.xz tar -xvf linux-5.0.1.tar cd linux-5.0.1
在安装内核时需要相应的编译环境,安装内核编译工具。
sudo apt install build-essential flex bison libssl-dev libelf-dev libncurses-dev 对内核进行设置并编译。 make defconfig make menuconfig Kernel hacking—>Compile-time checks and compiler options ---> [*] Compile the kernel with debug info make编译。
在这里可以使用 /etc/apt/sources.list进行配置,更换源后使用更新sudo apt-get update。
最后使用启动qemu进行配置文件,启动内核,发现内核能进行编译但是不能进行正常的初始化。
三、制作根文件系统
1、方法一:由制作好的MenuOS
make defconfig #按照默认值生成.config make i386_defconfig #生成32位x86的配置文件,x86_64_defconfig为64为配置
原有的根文件系统对应的linuxkernel是针对的3.18版本,需要将其修改成对应的5.1.0版本。
cd menu
sudo apt-get install libc6-dev-i386 # 在64位环境下编译32位需安装
修改qemu进行配置时,需要对qemu文件进行配置。
其中对makefile文件进行了修改:
Vi makefile qemu -kernel ./linux-5.0.1/arch/x86/boot/bzImage -initrd ./rootfs.img -s -S qemu -kernel LinuxKernel/linux-5.0.1/arch/x86/boot/bzImage -initrd ../rootfs.img make rootfs##制作根文件系统。 qemu-system-x86_64 -kernel linux-5.0.1/arch/x86_64/boot/bzImage -initrd rootfs.img
发现QEMU正常启动。
2、方法二:采用Busybox并制作根文件系统影像
下载对应的包
wget https://busybox.net/downloads/busybox-1.30.1.tar.bz2 tar -xvf busybox-1.30.1.tar.bz2 make help可以得到一些编译busybox的帮助信息 make defconfig
make menuconfig修改如下配置:
enable:Settings –> build options –> build busybox as a static binary(no share libs)
make dd if=/dev/zero of=rootfs.img bs=1M count=128 mkfs.ext4 rootfs.img mkdir rootfs sudo mount -o loop rootfs.img rootfs
在busybox目录下
sudo make CONFIG_PREFIX=../rootfs/ install
在../rootfs/etc/network/interfaces添加lo设备,可以直接拷贝ubuntu下的/etc/network/interfaces
sudo umount rootfs qemu-system-x86_64 -kernel linux-5.0.1/arch/x86_64/boot/bzImage -hda rootfs.img -append "root=/dev/sda init=/bin/ash"
此方法与方法一得到的结果相同
四、构建Linux内核的gdb调试环境
创建客户端
qemu-system-x86_64 -kernel linux-5.0.1/arch/x86_64/boot/bzImage -hda rootfs.img -append "root=/dev/sda init=/init nokaslr" -s -S
可以看到在新打开的qemu虚拟机上,整个是一个黑屏,此时qemu在等待gdb的连接
关于-s和-S选项的说明
-S freeze CPU at startup (use ’c’ to start execution)
-s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项
nokaslr KASLR是kernel address space layout randomization的缩写
Gdb server在需安装的开发版上配置信息
在gdb界面中targe remote之前加载符号表
file linux-5.0.1/vmlinux
当按下c进行控制时,qemu显示界面如图所示。
在gdb界面中设置断点
break start_kernel #断点的设置可以在target remote之前,也可以在之后
在设置好start_kernel处断点并且target remote之后可以继续运行,则在运行到start_kernel的时候会停下来,等待gdb调试命令的输入,可以使用list来显示断点处相关的源代码
此后可以继续设置新的断点,...
下面在在start_kernel、sys_socketcall位置设置了断点。
五、测试hello hi程序
安装具有hello 和hi 项目的git文件git clone https://github.com/mengning/linuxnet.git
设置linux-5.0.1然后进入 menu,我们写了一个脚本 rootfs,运行 make rootfs,脚本就可以帮助我们自动编译、自动生成根文件系统,还会帮我们运行起来 MenuOS 系统。
详细命令如下:
cd ~/LinuxKernel git clone https://github.com/mengning/linuxnet.git cd linuxnet/lab2 make cd ../../menu/ make rootfs
其中lab2是已编辑好的tcp程序,包含一个hello和hi文件。
此时观察makefile文件,发现其中存在hello.c文件已经被静态链接。
qemu -kernel ./linux-5.0.1/arch/x86/boot/bzImage -initrd rootfs.img -s –S
其中我们增加了命令 replyhi,功能是回复 hi 的 TCP 服务。gdbserver在等待客户端(host)发送信息
参考:GDBserver的使用https://www.cnblogs.com/blogs-of-lxl/p/10462262.html