学习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 mrpropermake 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 installsh /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_CHECKSUMERROR: modinfo: could not find module nf_defrag_ipv6ERROR: modinfo: could not find module vmware_balloonERROR: modinfo: could not find module vmwgfx

这些错误可以忽略。

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

启动新的内核

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

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

内核已经更新

配置双机调试

做虚拟机快照,基于快照创建一台新机器,用于目标机。
目标添加串行端口(先删除打印机设备)

开发机也添加串口(先删除打印机设备)

修改grub文件

启动目标机,修改grub文件

[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/sdadefault=1timeout=5splashimage=(hd0,0)/grub/splash.xpm.gzhiddenmenutitle 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.imgtitle 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文件后,重启系统,系统将停留在:

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

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

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

©著作权归作者所有:来自51CTO博客作者Lee_1985的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 【DevOps进行时】基于iOS平台的集中构建方法研究与实践
  2. 记一次Linux内核崩溃:kdump,crash,vmcore
  3. Nginx编译报错解决方法
  4. Hadoop3.x进阶:源码编译全记录
  5. LAMP分离架构部署wordpress和LogAnalyzer
  6. 安卓开发环境搭建
  7. 检测Redis编译安装之后是否正常
  8. Linux gcc使用基础
  9. Linux makefile使用基础

随机推荐

  1. Android日志输出单元测试Debug
  2. Android锁定横竖屏、splash,全屏、去除标
  3. Android TextView 中如何使用第三方字体
  4. Windows平台下搭建Android原生C/C++开发
  5. 日历视图的XML属性
  6. 短视频直播源码Android关于分屏的知识总
  7. Android JNI remote debugging
  8. android排版(布局)
  9. Android(安卓)实现遮罩
  10. android ListView GridView 单选和复选列