Linux内核开发双机调试(KGDB)

学习linux内核是很多程序员的梦想,内核错误往往会导致系统宕机,很难保留出错时的现场,对于开发linux内核和驱动调试,一般需要双机调试环境,KGDB是在内核2.6.26版本中正式支持的,可以方便调试内核和驱动。

前期准备

1.vmware虚拟机,安装centos6操作系统(内核版本2.6.32),对于学习低版本内核更合适
2.安装开发工具链 sudo yum groupinstall "Development Tools"
3.安装ncurses:sudo yum install ncurses-devel 因为make menuconfig依赖ncurses

编译内核

解压linux内核代码,进入源码目录,执行:make menuconfig

Kernel Hacking --> 
      (1)选中Compile the kernel with frame pointers 
      (2)去掉Write protect kernel read-only data structures(否则不能用软件断点)
清理以前的编译痕迹(如果需要)
make mrproper
make clean
编译内核: 
make -j4 bzImage 

编译会生成bzImage文件,对应于/boot目录下的vmlinuz文件,是压缩过的内核文件。启动加载时将该文件解压缩到内存中之后才能执行操作系统。

编译内核模块: 
make -j4 modules 

内核在运行过程中,除需要内核文件之外,还需要加载一些外围模块(例如驱动程序)等才能运行。

安装内核及模块

安装内核模块:make modules_install
安装上一步中编译的内核模块,一般都会安装到/lib/modules目录下。
安装内核:make install

[root@localhost linux-2.6.32.27]# make install
sh /root/build/linux-2.6.32.27/arch/x86/boot/install.sh 2.6.32.27 arch/x86/boot/bzImage \
                System.map "/boot"
ERROR: modinfo: could not find module xt_CHECKSUM
ERROR: modinfo: could not find module nf_defrag_ipv6
ERROR: modinfo: could not find module vmware_balloon
ERROR: modinfo: could not find module vmwgfx

这些错误可以忽略。

生成initrd.img
mkinitrd /boot/initrd-2.6.32.27.img 2.6.32.27 

启动新的内核

重启系统,选择我们刚刚编译的内核启动项,重启后,我们发现:

[root@localhost ~]# uname -a
Linux localhost.localdomain 2.6.32.27 #1 SMP Fri Mar 12 17:47:47 CST 2021 i686 i686 i386 GNU/Linux

内核已经更新

配置双机调试

做虚拟机快照,基于快照创建一台新机器,用于目标机。
目标添加串行端口(先删除打印机设备)
Linux内核开发双机调试(KGDB)
开发机也添加串口(先删除打印机设备)
Linux内核开发双机调试(KGDB)

修改grub文件

启动目标机,修改grub文件

扫描二维码关注公众号,回复: 12739244 查看本文章
[root@localhost ~]# cat /etc/grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/mapper/VolGroup-lv_root
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=1
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32.27)
        root (hd0,0)
        kernel /vmlinuz-2.6.32.27 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=128M rd_LVM_LV=VolGroup/lv_root  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet kgdboc=ttyS0,115200 kgdbwait
        initrd /initramfs-2.6.32.27.img
title CentOS 6 (2.6.32-754.el6.i686)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-754.el6.i686 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=128M rd_LVM_LV=VolGroup/lv_root  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
        initrd /initramfs-2.6.32-754.el6.i686.img

kgdboc=ttyS0,115200: 使用ttyS0,波特率115200
kgdbwait: 使 kernel 在启动过程中等待 gdb 的连接。然后重启target,系统就会暂停在kgdbwait处,等待host端的gdb连接。
修改完grub文件后,重启系统,系统将停留在:
Linux内核开发双机调试(KGDB)

启动开发机进行调试,进入内核编译目录,运行gdb ./vmlinux

(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0
Remote debugging using /dev/ttyS0
kgdb_breakpoint (new_kgdb_io_ops=0xc0a0b7d8) at kernel/kgdb.c:1721
1721 wmb(); /* Sync point after breakpoint */
(gdb) c  (继续运行)

如果目标机进入系统后,再想回到调试模式:在目标机执行:echo g > /proc/sysrq-trigger

猜你喜欢

转载自blog.51cto.com/14207158/2657966