9

gdb和qemu调试Linux内核

 3 years ago
source link: http://taowusheng.cn/2020/12/23/20201223%20gdb%E5%92%8Cqemu%E8%B0%83%E8%AF%95%E5%86%85%E6%A0%B8%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

gdb和qemu调试Linux内核

之前学习了利用KGDB双机调试内核,这种方式需要在两个主机上,通过串口线进行连接,或者是通过VMware开启两个虚拟机进行调试,对机器要求相对高一些。通过qemu创建虚拟机,然后利用gdb进行调试相对更轻量级一点。

我先在centos7下面配置调试环境,但是centos7下没有qemu_system_x86等命令,所以需要重新编译qemu源码再进行安装,再加上各种依赖问题,于是转用ubuntu进行配置,过程简单了许多。

  • vmware创建ubuntu14.04
    处理器设置多核、勾选虚拟化引擎、硬盘空间尽量大一点(20G+)
  • Linux-3.10.0

下载源码,配置编译选项。

su root #直接用root用户

tar -xzvf ./linux-3.10.0.tar.gz
cd linux-3.10.0/
make menuconfig #提示缺失软件用apt install安装即可

保证以下项为选中:

kernel hacking -- Kernel debugging
Compile the kernel with debug info
Compile the kernel with frame pointers
保存退出


make bzImage -j16
#-j多线程编译,可设置虚拟机内核数量或2倍,2倍貌似更快一些。
#bzImage会生成到arch/x86/boot/目录下
#vmlinux生成在/linux-3.10.0/目录下

bzImage是vmlinuz经过gzip压缩后的文件,适用于大内核
vmlinux是ELF文件,即编译出来的最原始的文件。
vmlinuz应该是由ELF文件vmlinux经过OBJCOPY后,并经过压缩后的文件
zImage是vmlinuz经过gzip压缩后的文件,适用于小内核

安装qemu

apt安装

apt install qemu

busybox制作磁盘镜像

1.下载busybox源码
2.编译bysybox

tar -xjvf busybox-1.31.1.tar.bz2
cd ./busybox-1.31.1/
make menuconfig

进入 Settings
勾选 Build static binary (no shared libs)

make install -j16
之后会生成_install目录,里面有linux常用的工具

3.制作磁盘镜像文件

cd /root/xxx
qemu-img create qemu_rootfs.img 10g

其中qemu_rootfs.img是文件名,10g是磁盘大小,根据需要修改。

创建ext4文件系统

mkfs.ext4 qemu_rootfs.img

挂载img文件到宿主系统:

cd /root/xxx
mkdir qemu_rootfs
sudo mount -o loop qemu_rootfs.img qemu_rootfs

-o loop的意思是将qemu_rootfs.img作为硬盘文件,挂载在qemu_rootfs目录下
挂载之后就可以在qemu_rootfs里面对qemu_rootfs.img进行操作了

4.配置磁盘镜像文件,先将_install目录下的文件全部拷贝到qemu_rootfs

cd qemu_rootfs
cp /xxx/busybox/_install/* -rf ./

再创建一些常用目录和文件

cd qemu_rootfs
mkdir proc sys dev etc etc/init.d

新建etc/init.d/rcS,内容如下:

#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s

然后修改rcS文件权限,加上x。当busybox的init运行起来后,就会运行这个/etc/init.d/rcS脚本。
最后将磁盘镜像从qemu_rootfs上卸载

umount qemu_rootfs

gdb调试

1.如果在调试内核时,报Remote ‘g’ packet reply is too long的error,可以重新编译gdb修复bug.
2.qemu启动内核

启动命令比较长,可以设置一个启动脚本
cd /linux-3.10.0
vim boot.sh
内容如下:
###
#!/bin/sh

qemu-system-x86_64 \
-kernel bzImage \
-hda qemu_rootfs.img \
-append "root=/dev/sda rootfstype=ext4 rw nokaslr"\ #这里nokaslr是关闭地址随机化,不关无法用gdb调试
-s -S # -s的意思是等待外面gdb的链接,默认开启1234端口进行监听;-S是在内核的入口打断点。
###

给boot脚本增加执行权限
chmod +x boot.sh
./boot.sh
之后会见到新生成的qemu窗口

3.新开终端,用gdb连接内核

gdb vmlinux
gdb> target remote localhost:1234

4.例如在do_fork()函数打断点,进行调试。

b do_fork
c
去qemu窗口,执行一些操作出发do_fork()函数

Share 0 Comments


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK