Ubuntu14.04+QEMU Debug Kernel-3.16.2
本文档主要记录如何在ubuntu-14.04上一步一步建立起利用qemu调试kernel-3.16.2的环境的。
1 源码包准备
kernel-3.16.4 #被debug的内核
busybox-1.30.0.tar.bz2 #用于制作mini rootfs
以上两个源码包均可到对应的官方网站上下载。
2 环境准备
2.1) 更换阿里云软件源,这个apt-get的时候更快一点。位置在:/etc/apt/sources.list, 替换里面的内容即可,在替换之前,记得首先保存备份。
2.2)安装一系列工具包
# apt-get install -y build-essential vsftpd openssh-server kernel-package libncurses5-dev libssl-dev bison libelf-dev
# apt-get install -y vim gcc-multilib tree dos2unix git manpages-dev
# apt-get qemu
安装完vsftpd,记得修改/etc/vsftpd.conf文件,至此,环境就准备好了。
3 编译内核
解压源文件,进入目录。
#make x86_64_defconfig
#make menuconfig
KGDB: kernel debugger (KGDB [=y])
Symbol: KGDB_SERIAL_CONSOLE [=y]
同时在block device里面要配置支持 ram block, 支持initrd
生成 .config文件之后,修改Makefile文件,把“-O2”改成“-O1” , " :%s/O2/O1/g "
# make -j4
4 制作最小根文件系统
解压busybox文件,进入相应目录.
# make defconfig
# make menuconfig # 配置改成静态编译。
# make
# make install # 会在目录下面生成一个“_install” 目录,里面就包含了我们所需要的核心文件
在busybox的上层目录下面建立rootfs目录。
# cp * ../rootfs/ -frd
进入到rootfs目录,开始制作根文件系统镜像。
4.1)核心步骤
# mkdir sys proc dev tmp mnt dev lib lib64 etc/init.d -p
1)在etc/init.d中创建名为rcS的脚本,rcS脚本中填入以下内容:
1 #!/bin/sh
2 mount -t sysfs none /sys
3 mount -t proc none /proc
4 echo /sbin/mdev > /proc/sys/kernel/hotplug
5 /sbin/mdev -s
2)创建inittab文件
直接把busybox/examples/inittab文件copy到rootfs/etc目录下,然后删掉一些不用的东西。
3)生成initrd.gz文件
# dd if=/dev/zero of=/tmp/initrd bs=1024 count=4096 # 制作一个4M的空白文件
# losetup /dev/loop0 /tmp/initrd # 映射到loop设备上;
# mkfs.ext2 /dev/loop0 # 创建文件系统;
# mount /dev/loop0 /mnt/
# cp _what_you_like_ /mnt/ # 复制需要的文件;
# umount /mnt/
# losetup -d /dev/loop0
# gzip -9 /tmp/initrd
至此,mini rootfs就做好啦。把它copy到 linux-3.16.2 目录中。
5 启动qemu
需要登陆两个shell 终端,
在shell 终端1 运行如下命令: # qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd ./initrd.gz -m 512 -s -S
参数解释:-S,停止运行,等待远程gdb连接,-s, 开启gdbserver服务。
在shell终端2 运行如下命令:
# gdb vmlinux
# target remote localhost:1234
此时gdb就连接上啦。此时就可以像普通gdb一样debug了。
例如: (gdb) b start_kernel
(gdb) c
此时,会报一个错误出来: "remote 'g' packet reply is too long", 我们需要更换gdb的版本到gdb7.8.
6.1 更换gdb
#cd gdb-7.8/gdb
#vim remote.c +
按照如图所示修改代码【针对7.8版本】:

代码如下:
if (buf_len > 2 * rsa->sizeof_g_packet) { rsa->sizeof_g_packet = buf_len ; for (i = 0; i < gdbarch_num_regs (gdbarch); i++) { if (rsa->regs->pnum == -1) continue; if (rsa->regs->offset >= rsa->sizeof_g_packet) rsa->regs->in_g_packet = 0; else rsa->regs->in_g_packet = 1; } }
安装gdb
在主目录gdb-7.8下依次运行命令:
#./configure
# make
# make install
# gdb -v //查看gdb的版本是否是7.8
再次打开终端调试,就不会有问题了。
介绍完毕!

浙公网安备 33010602011771号