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

  再次打开终端调试,就不会有问题了。

  介绍完毕!

 

 

    

posted @ 2021-06-12 23:51  qyzhu  阅读(203)  评论(0)    收藏  举报