配置和使用linux内核调试环境(基于虚拟机)

来源:互联网 发布:seo常用标签 编辑:程序博客网 时间:2024/06/05 00:59
内核调试环境(Linux)
本章主要介绍如何配置和使用内核调试环境。首先介绍如何配置内核环境,这是内核调
试环境的基础,接着介绍如何安装配置和使用Samba 来实现Windows 和Linux 之间的网络共
享,最后介绍一种调试 Linux 内核的机制——KGDB,包括它的安装、配置和使用。
一、 配置内核环境
实验中采用的Linux 发行版是CRUX,内核版本为2.6.15.6。
CRUX 是一个针对 i686 优化过的轻量级 Linux 发行版,它的目标是有经验的 Linux
用户。这份发行以简单化为主旨,这反映在其基于简单的tar.gz 格式的软件包系统上,以
及BSD 风格的启动脚本和相对较少的软件包收录。它的第二个着眼点则在于利用Linux 的新
特性以及新近的工具及系统库。CRUX 还有一个ports 系统来方便的安装和升级程序、软件。
CRUX 没有图形界面,会给实验照成一定的难度,但是CRUX 的轻便使得编译内核的时间
大大的减少,其他发行版如RedHat,Ferdoa 等,编译内核大概需要四五十分钟,而是用CRUX
是编译内核只用十分钟左右的时间。这是我们选择这个发行版的主要原因。当然他的自由度
高,很能锻炼动手能力也是我们选择它来作为实验系统的原因之一。
下面将详细介绍在VMWare 上配置内核环境的全过程。
首先在VMWare 中创建一个虚拟机,选择“custom(advanced)”配置方式,选择安装文
件(安装盘或者是ISO 文件),虚拟机命名为crux_gdb,作为客户机操作系统(guest
operating system)。选择安装Linux 操作系统,并选择“other 2.6.x linux kernel”版
本;网络连接选择“host-only”方式;虚拟硬盘类型最好选择“IDE”;其它采用默认值即
可。配置完成,启动虚拟机。
启动后出现选择引导哪个操作系统的提示,输入回车即开始引导CRUX 系统,这个过程
需要一两分钟。启动后用root 用户登录(初始无密码,输入root,回车即可)。
下面是对系统环境的配置:
1. 磁盘分区
在Linux 中硬盘分区是通过hd*x 或 sd*x 表示的,hd*X 一般代表IDE 硬盘,sd*x 代
表的是SCSI 硬盘。其中 * 表示的是a、b、c ... ..., x 表示的数字 1、2、3 ... ...,
用fdisk 命令给磁盘分区:
如果你选择的硬盘接口是SCSI 类型,则为/dev/sda。
实验中我们会把硬盘分成两个分区,第一个分区大小取500M,类型设置为交换区;第
二个分区占用剩余的所有空间,类型为ext3,并设置为可启动。
开始分区前,可以先按“m”显示帮助信息:
# fdisk /dev/hda
内核调试环境(Linux)
这里我们要用到n,p,t,a,w 这几个命令,先输入“p”查看磁盘的分区情况:
此时这个磁盘没有任何分区。其中 heads 是磁盘面;sectors 是扇区;cylinders 是
柱面;每个扇区大小是 512byte,也就是0.5K。
下面列表中Device 表示分区名;Boot 表示是否引导分区,用*标记的为启动分区,实
验中 hda2 是引导分区;Start 和End 分别表示分区的开始和结束cylinder(磁柱);id
和System 表示的是一个意思,即分区的类型。Id 是类型的代号,在使用fdisk 分区时,要
通过指定id 来确认分区类型(System),比如 83 为默认值,表示linux ext3 分区格式;7
表示NTFS 分区,82 表示交换分区,这个在fdisk 中要通过t 功能来指定,下面的实验中
将会提到;Blocks 表示分区的容量,单位是byte。
首先来创建第一个分区,大小为500M,具体过程如下:
q quit without saving changes 注:不保存退出;
s create a new empty Sun disklabel
t change a partition's system id 注:t 改变分区类型;
u change display/entry units
v verify the partition table
w write table to disk and exit 注:把分区表写入硬盘并退出;
x extra functionality (experts only) 注:扩展应用,专家功能;
Command (m for help): 在这里按m ,就会输出帮助,如下所示;
Command action
a toggle a bootable flag 注:设置分区为可启动
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition 注:这是删除一个分区的动作;
l list known partition types
注:l 是列出分区类型,以供我们设置相应分区的类型;
m print this menu 注:m 是列出帮助信息;
n add a new partition 注:添加一个分区;
o create a new empty DOS partition table
p print the partition table 注:p 列出分区表;
内核调试环境(Linux)
First Cylinder 表示第一个柱面,这里按下Enter,表示默认为1; Last Cylinder 表
示最后一个柱面,输入+500M,表示大小为500M;命令t 用来设置其类型为 Linux
swap/Solaris,(用l 命令可查看分区类型)。剩余的空间作为第二个分区,所以选择磁道时
默认即可,命令a 用来设置该分区为启动分区。
分区完成后,输入p 查看分区的情况:
检查无误后输入“w”保存并退出。
2. 格式化并加载分区
在创建好的分区上创建文件系统(这个过程需要2-3 分钟):
将新创建的文件系统安装在/mnt 目录上:
创建交换区:
激活交换空间
#mkswap /dev/hda1
# mount /dev/hda2 /mnt
# mkfs.ext3 /dev/hda2
内核调试环境(Linux)
3. 启动安装程序
将系统安装在/mnt 上:
开始安装后安装程序会要求你选择要安装的包、安装目录等,默认即可。安装过程需要
一两分钟。显示“INSTALL COMPLETED SUCCESSFULLY!”且按End 键查看日志的最后显示“0
error(s) found”则表示安装成功。
4. 切换根目录
其中mount –bind 命令是将一个目录的内容挂载到另一个目录上,用法是:
mount –bind olddir newdir
他和普通mount 的区别是可以将一个目录以像设备一样挂载到另一个目录上,挂载后的
目录继承了被挂载目录的所有属性,除了名称。与ln 的区别是,ln 只是创建了一个符号链
接,本质上还是属于一种文件。
mount 命令的–t 参数是用来指定文件系统的类型,格式为:
mount [-t vfstype] device dir
chroot 命令用来改变根目录,即change root,语法为:
chroot [Directory][ Command]
作用是在当执行Command 时将根目录更改到参数Directory 指定的目录。
5. 修改配置文件
/etc/fstab 是用来存放文件系统的静态信息的文件。当系统启动的时候,系统会自动
地从这个文件读取信息,并且会自动将此文件中指定的文件系统挂载到指定的目录。虽然它
的作用巨大,但它却只是一个简单的文本文件,你可以用任何你熟悉的文件编辑器(如vim)
去编辑它,但是必须有根权限才能编辑,所以在编辑之前,你必须以根用户登录或用su 命
令切换到根用户。
这里我们用vim 编辑器打开/etc/fstab。
# vim /etc/fstab
# mount –bind /dev /mnt/dev
# mount –bind /tmp /mnt/tmp
# mount -t proc proc /mnt/proc
# mount -t sysfs none /mnt/sys
# chroot /mnt /bin/bash
# setup
# swapon /dev/hda1
内核调试环境(Linux)
注:在Linux 文件中#表示注释。
在这个文件下,我们要关注的是它的六个域,分别为:<file system>、<mount point>、
<type> 、<options>、<dump>、<pass>。下面将详细介绍这六个域的详细意义。
1) <fie sysytem>。这里用来指定你要挂载的文件系统的设备名称或块信息,也可以
是远程的文件系统。 如果想把本机上的某个设备(device)挂载上来,写法如:
/dev/sda1、/dev/hda2 或/dev/cdrom,其中,/dev/sda1 表示第一个串口硬盘的
第一个分区,也可以是第一个SCSI 硬盘的第一个分区,/dev/hda1 表示第一个IDE
硬盘的第一个分区,/dev/cdrom 表示光驱。
2) <mount point>:挂载点,也就是自己找一个或创建一个dir(目录),然后把文件
系统<fie sysytem>挂到这个目录上,然后就可以从这个目录中访问要挂载文件系
统。对于swap 分区,这个域应该填写:none,表示没有挂载点。
3) <type>:这里用来指定文件系统的类型。下面的文件系统都是目前Linux 所能支持
的:adfs、befs、cifs、ext3、 ext2、ext、iso9660、kafs、minix、msdos、vfat、
umsdos、proc、reiserfs、swap、 squashfs、nfs、hpfs、ncpfs、ntfs、affs、
ufs。
4) <options>:这里用来填写设置选项,各个选项用逗号隔开。由于选项非常多,而这
里篇幅有限,所以不再作详细介绍,如需了解,请用 命令 man mount 来查看。但
在这里有个非常重要的关键字需要了解一下:defaults,它代表包含了选项
rw,suid,dev,exec,auto,nouser 和 async。
5) <dump>:此处为1 的话,表示要将整个<fie sysytem>里的内容备份;为0 的话,
表示不备份。
6) <pass>:这里用来指定如何使用fsck 来检查硬盘。如果这里填0,则不检查;挂载
点为 / 的(即根分区),必须在这里填写1,其他的都不能填写1。如果有分区填
写大于1 的话,则在检查完根分区后,接着按填写的数字从小到大依次检查下去。
同数字的<file system>同时检查。比如第一和第二个分区填写2,第三和第四个
分区填写3,则系统在检查完根分区后,接着同时检查第一和第二个分区,然后再
同时检查第三和第四个分区。
本实验中在该文件中加入如下两行:
内核调试环境(Linux)
6. 编译内核
如果内核很大的话,系统会提示你使用make bzImage 命令来编译。内核编译成功后,
会在/usr/src/linux/arch/i386/boot 目录中生成一个新内核的映像文件bzImage。而
System.map 是系统的符号表,当你编译一个新内核时,你原来的System.map 中的符号信息
就不正确了。随着每次内核的编译,就会产生一个新的System.map 文件,并且需要用该文
件取代原来的文件。所以编译完后需要把新内核的映像文件和符号表复制到相应的目录下,
才能使用新内核。
7. 安装boot loader
Boot loader(系统启动引导管理器)是在计算机启动后运行的第一个程序,负责加载、
传输控制到操作系统的内核,一旦把内核挂载,系统引导管理器的任务就算完成退出,系统
引导的其它部份,比如系统的初始化及启动过程则完全由内核来控制完成。
在X86 架构的机器中,Linux、BSD 或其它Unix 类的操作系统中GRUB、LILO 是大家最
为常用的两种多系统引导管理器。GRUB(GRand Unified Bootloader)是个默认安装的功能
强大的启动引导管理器,它有许多功能,可以使引导过程变得非常可靠。例如,它可以直接
从 fat、minix、ffs、ext2 或 reiserfs 分区读取 linux 内核,这就意味着无论怎样它总
能找到内核。所以本实验中我们采用grub 引导系统。
GRUB 的配置文档位于/boot/grub/下,文档名为menu.lst。如果需要的话,编辑这个文
件修改GRUB 配置。
# vim /boot/grub/menu.lst
# cd /usr/src/linux-2.6.15.6
# cp linux-2.6.15.6-small.config .config
# make oldconfig
# make
# make modules_install
# cp arch/i386/boot/bzImage /boot/vmlinuz
# cp System.map /boot/System.map
/dev/hda2 / ext3 defaults 1 1
/dev/hda1 swap swap defaults 0 0
内核调试环境(Linux)
其中:
default 表示默认启动哪个系统,从0 开始;每个操作系统的启动的定义都从title 开
始的,第一个title 在GRUB 的启动菜单上显示为0,第二个启动为1,以此类推;
timeout 表示在开机后,GRUB 画面出现几秒后开始以默认启动;如果在启动时,移动上
下键,则解除这一规则;
title 后面是系统的名称;
kernel 这行理解为:
kernel (boot 所在的分区)/boot/内核文件全称 root=Linux 根所位于的分区或标签。
boot 所在分区的表示中(hd0,1)是指系统第一个硬盘的第二个分区,在本实验中指的
是/dev/hda2。
设置默认情况下是从/boot/vmlinuz 启动,/dev/hda2 作为根分区,也可不做任何设置,
在开机时手动选择。
下面开始用grub 来设置引导盘的引导扇区。在root 用户下,输入 "grub",启动grub 控
制台。
在 linux 中,当谈到 "root" 文件系统时,通常是指主linux 分区。但是,grub 有它
自己的 root 分区定义。grub 的 root 分区是保存 linux 内核的分区。这可能是你的root
文件系统,也可能不是。
grub 所使用的硬盘/分区命名约定与 linux 使用的命名约定也不同。在 linux 中,第
一个硬盘的第五个分区称作 "hda5"。而 grub 把这个分区称作 "(hd0,4)"。grub 对硬盘和
分区的编号都是从 0 开始计算。另外,硬盘和分区都用逗号分隔,整个表达式用括号括起。
所以上面实验中要引导 linux 硬盘 hda2 时,输入 "root (hd0,1)"
# grub
grub> root (hd0,1)
grub> setup (hd0)
grub> quit
内核调试环境(Linux)
安装好后退出grub 控制台。
8. 重新启动
移去CDROM(VM->CDROM->disconnect),重新启动你安装好的虚拟机。
二、 配置Samba
Samba 是属于GNU Public License(简称GPL)的一种自由软件;因此,你可以合法且
免费地使用它。下载地址为:http://www.samba.org/samba/download/。
Samba 用来让UNIX 系列的操作系统与微软Windows 操作系统的SMB/CIFS(Server
Message Block/Common Internet File System)网络协定做连接。简而言之,就是在Windows
与UNIX 系列OS 之间搭起一座桥梁,让两者的资源可互通有无。当然也可实现Linux 之间的
共享。
Samba 的核心是SMB(Server Message Block)协议。SMB(Server Message Block)通信
协议是微软(Microsoft)和英特尔(Intel)在1987 年制定的协议,主要是作为Microsoft
网络的通讯协议,而Samba 则是将SMB 协议搬到UNIX 上来应用。SMB 协议是客户机/服务器
型协议,客户机通过该协议可以访问服务器上的共享文件系统、打印机及其他资源。通过
“NetBIOS over TCP/IP”使得Samba 不但能与局域网络主机分享资源,更能与全世界的电
脑分享资源;因为互联网上千千万万的主机所使用的通讯协议就是TCP/IP。SMB 是在会话层
(ession layer)和表示层(presentation layer)以及小部分应用层(application layer)
的协议。SMB 使用了NetBIOS 的API。另外,它是一个开放性的协议,允许了协议扩展——
使得它变得更大而且复杂;大约有65 个最上层的作业,而每个作业都超过120 个函数,甚
至Windows NT 也没有全部支持到。
最近微软又把 SMB 改名为CIFS(Common Internet File System), 并且加入了许多
新的特色,而Samba 亦支持了NT Lan Manager 0.12 等 SMB 的延伸协议,这是得Samba 具
有管理NT 网域的能力。
Samba 的主要功能如下:
1) 提供Windows NT 风格的文件和打印机共享 Windows 95、Windows 98、Windows NT
等以据此共享UNIX 等其他操作系统的资源,外表看起来和共享NT 的资源没有区
别。
2) 解析NetBIOS 名字IP 在Windows 网络中,为了能够利用网上资源,同时自己的资
源也能被别人所利用; 各个主机都定期地向网上广播自己的身份信息。而负责收
集这些信息为别的主机提供检索情报的服务器就被称为浏览服务器。Samba 可以有
效地完成这项功能。在跨越网关的时候Samba 还可以作WINS 服务器使用。
3) 提供SMB 客户功能,利用Samba 提供的smbclint 程序可以从UNIX 下以类似于 FTP
的方式访问Windows 的资源。
4) 备份PC 上的资源 利用一个叫smbtar 的shell 脚本,可以使用 tar 格式备份和恢
复一台远程 Windows 上的共享文件。
5) 提供一个命令行工具,在其上可以有限制地支持NT 的某些管理功能。
通俗的说就是在安装Smaba 后,系统可以在网络上共享目录或打印机,就好像一台文件
服务器或打印机服务器一样;还可以决定每一个目录和打印机由谁来使用,可以让一个人、
某些人、组和所有人访问。
在实验之前首先要确定你的网络配置是否正确。
# shutdown –r now
内核调试环境(Linux)
如果显示如下表示eth0 设备已经正常工作。如果还有其他网卡,其他网卡的状态也会
在此显示。
如果此处只有本地环路信息,则表示网络配置不正确。这种情况下:
首先你需要在Windows 系统下本地连接属性中的“Internet 连接共享”中选择“允许
其他网络用户通过此计算机的Internet 连接来连接(N)”,并在下面的“家庭网络连接(H)”
中选择“VMware Network Adapter VMNet1”,因为实验中使用的host-only 网络连接方式,
这种方式使用的是系统中的VMNet1 网络连接。
然后查看Windows 下VMNet1 的IP 地址和子网掩码,接着在虚拟机上“Edit”->“Virtual
Network Editor”中将VMNet1 的Ip 地址设置为与之同一网段,具体方法会因虚拟机版本不
同而稍有不同,这里就不作详细介绍。
然后重启系统,就可以看到网络配置成功了。
下面正式开始安装和配置Samba 了。
下载samba 最新版,文件名samba-3.0.24.tar.gz
1. 解压、编译、安装
首先在“VM”->”settings”中将“CD/DVD”选择为Samba 的安装盘或ISO 文件。启动
系统。
将光盘挂接到/mnt 目录:
将文件解压到/tmp 目录下:
然后运行/tmp/samba-3.0.24/source 目录下的设置脚本:
在这个脚本定制好系统之后,就可以开始编译Samba 了:
# make
# cd /tmp/samba-3.0.24/source
# ./configure
# cd /mnt
# tar zxvf samba-3.0.24.tar.gz –C /tmp
# mount /dev/hdc /mnt
# ifconfig
内核调试环境(Linux)
这段时间要根据你的机器配置来决定,一般情况下为十分钟左右。接着将Samba 拷贝到
/usr/local 目录下,执行此操作的必须为系统管理员(root),如果登录的用户不是管理员
可以通过su 命令切换到root。
切换到这个目录,开始安装Samba:
安装的过程需要2-3 分钟。
2. 安装smb.conf
安装目录下有很多smb.conf 的例子,但/usr/local/samba/lib 下却没有,所以必须复
制一份到该目录。
检查smb.conf 配置语法是否错误和设置是否成功:
因为是默认的smb.conf,不会有问题,命令执行后显示“Load services file OK”。
接着可以根据自己的需要配置smb.conf。
3. 配置smb.conf
找到[global],在其下面增加以下三行:
这三行设置的目的是在win 机上使用“网络邻居“共享到linux 上的文件夹和文件时,
显示汉字。
找到[home],在其下加入:
这样Samba 用户在windows 机器中登录Samba 服务器后就可以看到/usr 下的所有文件
了。
4. 增加smb 用户
一般linux 系统上都有很多用户,这里新建一个用户jack,密码为jackjack:
将该用户设置为Samba 用户,密码为jack123(注意:Samba 的密码和Linux 系统的密码是
# useradd jack –p jackjack
path=/usr
unix charset=cp936
dos charset=cp936
display charset=cp936
# vim /usr/local/smb/lib/smb.conf
# /usr/local/samba/bin/testparm
# cp /usr/local/samba-3.0.24/examples/smb.conf.default /usr/local/samba/lib
# cd /usr/local/samba-3.0.24/source
# make install
# cp –a /tmp/samba-3.0.24 /usr/local/samba-3.0.24
内核调试环境(Linux)
相互独立)。
这样就把jack 增加为Samba 用户了。为了后面实验的需要在这里还需要增加root 为
Samba 用户。
5. 启动smb 服务
在启动smb 服务前需要注意一个问题,你的电脑是否连接了打印机。如果已连接,则可
直接开启smb 服务。如果没有连接打印机,则要建立一个空的/etc/printcap 文件,否则在
启动服务时会出现“Unable to open printcap file /etc/printcap for read!”的错误。
接着启动Samba 服务。
Samba 由两个主要程序组成,它们是smbd 和nmbd。这两个守护进程在服务器启动到
停止期间持续运 行,功能各异。Smbd 和nmbd 使用的全部配置信息全都保存在smb.conf
文件中。Smb.conf 向smbd 和nmbd 两个守护进程说明输出什么 以便共享,共享输出给谁
及如何进行输出。
Samba 提供了基于CIFS 的四个服务:文件和打印服务、授权与被授权、名字解析、浏
览服务。前两项服务由smbd 提供,后两项服务则由nmbd 提供。 简单地说,smbd 进程的
作用是处理到来的SMB 软件包,为使用该软件包的资源与Linux 进行协商,nmbd 进程使主
机(或工作站)能浏览Linux 服 务器。所以启动Samba 服务器需要分别启动这两个进程:
我们可以在日志文件中查看服务启动是否成功:
启动完成,然后到win 机上,打开网上邻居的“Microsoft Windows Network”,就可以
看到linux 机子了(在你设定的组“Mygroup”下),此处需要使用Samba 用户登录才能访问。
输入“jack"和密码,就可以看到linux 机子上/usr 文件夹的内容了。
如果启动后修改了smb.conf,结束两个服务进程:
然后重复第5 条操作就可以了,不用重启。
最后就是要把Samba 设置为开机启动。Linux 中开机启动的脚本放置在/etc/rc.d 目录
下。所以我们首先要为/etc/rc.local 在/etc/rc.d 中建立一个符号链接:
然后再编辑/etc/rc.d/rc.local
在其中加入如下几行:
# vim /etc/rc.d/rc.local
# ln -s /etc/rc.local /etc/rc.d
# pkill smbd
# pkill nmbd
# cat /usr/local/samba/var/log.smbd
#cat /usr/local/samba/var/log.nmbd
# /usr/local/samba/sbin/smbd –D
# /usr/local/samba/sbin/nmbd -D
# touch /etc/printcap
# /usr/local/samba/bin/smbpasswd –a jack
内核调试环境(Linux)
在系统启动信息的最后一行,你会看到提示“Samba Server is started!”表示在开机
时Samba 已经启动。
三、 配置KGDB
调试是软件开发过程中一个必不可少的环节,在 Linux 内核开发的过程中也不可避免
地会面对如何调试内核的问题。但是,Linux 系统的开发者出于保证内核代码正确性的考虑,
不愿意在 Linux 内核源代码树中加入一个调试器。他们认为内核中的调试器会误导开发者,
从而引入不良的修正。所以对 Linux 内核进行调试一直是个令内核程序员感到棘手的问题,
调试工作的艰苦性是内核级的开发区别于用户级开发的一个显著特点。
尽管缺乏一种内置的调试内核的有效方法,但是 Linux 系统在内核发展的过程中也逐
渐形成了一些监视内核代码和错误跟踪的技术。同时,许多的补丁程序应运而生,它们为标
准内核附加了内核调试的支持。尽管这些补丁有些并不被 Linux 官方组织认可,但他们确
实功能完善,十分强大。调试内核问题时,利用这些工具与方法跟踪内核执行情况,并查看
其内存和数据结构将是非常有用的。
这里将要介绍的是Linux 内核众多调试方法中的一个——KDGB。
KGDB 程序(使用 GDB 的远程主机 Linux 内核调试器)提供了一种使用GDB 调试 Linux
内核的机制。KGDB 程序是内核的扩展,使用它可以象调试普通的应用程序那样,在内核中
进行设置断点、检查变量值、单步跟踪程序运行等操作。
使用KGDB 需要两台机器:一台作为开发机(Development Machine),另一台作为目标
机(Target Machine),。一条串行线(空调制解调器电缆)将通过机器的串口连接它们。
您希望调试的内核在测试机器上运行;GDB 在开发机器上运行。GDB 使用串行线与您要调试
的内核通信。
目前,KGDB 发布支持i386、x86_64、32-bit PPC、SPARC 等几种体系结构的调试器。
安装KGDB 调试环境需要为Linux 内核应用KDGB 补丁,补丁实现的GDB 远程调试所需要
的功能包括命令处理、陷阱处理及串口通讯3 个主要的部分。KGDB 补丁的主要作用是在Linux
内核中添加了一个调试Stub。调试Stub 是Linux 内核中的一小段代码,提供了运行GDB 的
开发机和所调试内核之间的一个媒介。GDB 和调试stub 之间通过GDB 串行协议进行通讯。
GDB 串行协议是一种基于消息的ASCII 码协议,包含了各种调试命令。当设置断点时,KGDB
负责在设置断点的指令前增加一条trap 指令,当执行到断点时控制权就转移到调试stub
中去。此时,调试stub 的任务就是使用远程串行通信协议将当前环境传送给GDB,然后从
GDB 处接受命令。GDB 命令告诉stub 下一步该做什么,当stub 收到继续执行的命令时,将
恢复程序的运行环境,把对CPU 的控制权重新交还给内核。
这个补丁的主要特点之一就是运行GDB 的主机在引导过程中连接到目标机器(运行要
被调试的内核)。这让您能够尽早开始调试。请注意,补丁为 Linux 内核添加了功能,所
以GDB 可以用来调试 Linux 内核。
实验中使用VMware 后我们只使用一台计算机就可以顺利完成KGDB 调试环境的搭建。虚
拟机中的串口连接可以采用两种方法。一种是指定虚拟机的串口连接到实际的COM 上,例如
开发机连接到COM1,目标机连接到COM2,然后把两个串口通过串口线相连接。另一种更为
简便的方法是:在较高一些版本的VMware 中都支持把串口映射到命名管道,把两个虚拟机
的串口映射到同一个命名管道。例如, 在两个虚拟机中都选定同一个命名管道
/usr/local/samba/sbin/smbd –D
/usr/local/samba/sbin/nmbd –D
echo “Samba Server is started!”
内核调试环境(Linux)
\\.\pipe\com_1,指定target 机的COM 口为server 端,并选择"The other end is a virtual
machine"属性;指定development 机的COM 口端为client 端,同样指定COM 口的"The other
end is a virtual machine"属性。这样,可以无需附加任何硬件,利用虚拟机就可以搭建
KGDB 调试环境。即降低了使用KGDB 进行调试的硬件要求,也简化了建立调试环境的过程。
下面进行KGDB 安装配置。
前面的实验中我们已经配置好Samba 服务器,现在就可以使用它了,在Windows 机器下,
用root 用户登录Samba 服务器,将文件linux-2.6.15.5-kgdb-2.4.tar.bz2 复制到crux_dbg
的/usr/src 目录下,然后转到Linux 机器下解压文件:
这时打开/usr/src 目录将会看到如下两个目录:
/usr/src/linux-2.6.15.6
/usr/src/linux-2.6.15.5-kgdb-2.4
首先要为内核打上kgdb 的支持补丁(具体可以参考patch 中README,选择需要的
patch):
按正常编译内核流程,进入make menuconfig 阶段:
在kernel hacking 中选择kernel debugging、KGDB 等选项,务必确保 选中下面的几
项:
如果有需求其它的选项也可以选上。
注意Serial port number for KGDB,默认选项是1,需要改为零。
配置好后重新编译内核:
编译内核是一个较长时间的过程, 约需要10 分钟左右。编译完成后, 将
/usr/src/linux/arch/i386/boot/bzImage 和/usr/src/linux/System.map 复制到/boot 下:
# make
 Kernel debugging
 KGDB: Console messages through gdb
Method for KGDB communication (KGDB: On generic serial port (8250))
 Simple selection of KGDB serial port
 (115200) Debug serial prot baud rate
 (0) Serial port number for KGDB
# make menuconfig
# cd /usr/src/linux-2.6.15.6
# patch –p1 < ../linux-2.6.15.5-kgdb-2.4/core-lite.patch
# patch –p1 < ../linux-2.6.15.5-kgdb-2.4/i386-lite.patch
# patch –p1 < ../linux-2.6.15.5-kgdb-2.4/8250.patch
# patch –p1 < ../linux-2.6.15.5-kgdb-2.4/eth.patch
# patch –p1 < ../linux-2.6.15.5-kgdb-2.4/i386.patch
# patch –p1 < ../linux-2.6.15.5-kgdb-2.4/core.patch
# patch –p1 < ../linux-2.6.15.5-kgdb-2.4/module.patch
# patch –p1 < ../linux-2.6.15.5-kgdb-2.4/sysrq_bugfix.patch
# tar –xvf linux-2.6.15.5-kgdb-2.4.tar.bz2
内核调试环境(Linux)
修改grub 启动项:
按照前面实验中的介绍,仿照文件中的格式,增加一个启动项,如下所示:
这时你重启系统,就可以看到CRUX_GDB 这个启动项。
实验中需要两个机器,所以这里要复制一个和crux_dbg 一样的系统,做这件事的时候
需要关闭crux_gdb。在crux_gdb 上点击右键,选择“Clone”,按照提示,选择"Create a full
clone",命名为crux_run。
然后要将这两个机器分别作为开发机和目标机。分别为两个系统增加一个串口,具体操
作为:“VM”->“settings”->“Add”->“Serial Port”,选择“output to a name pipe”
方式,其中:
crux_dbg 端选择"this end is the client", "the other end is a virtual machine"
crux_run 端选择"this end is the server", "the other end is a virtual machine"
完成设置后这两台机器就可以通过命名管道通信了。
接下来启动crux_run,在grub 菜单中选择CRUX-DBG,系统引导到"Uncompressing
Linux... OK, booting the kernel.",暂停。
启动crux_dbg,在grub 菜单中选择CRUX-IDE。登录后进入/usr/src/linux 目录:
启动gdb:
显示:
设置串口的参数:
之后gdb 显示提示信息:
(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0
Remote debugging using /dev/ttyS0
GNU gdeb 6.4
Copyright 2005 Free Software Foundation , Inc.
GDB is free software, covered by the GUN Ceneral Public License, and you are welcome to
change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for details.
This GDB was configured as “i386-redhat-linux-gnu”… Using host libthread_db library
“/lib/tls/libthread_db.so.1”.
# gdb ./vmlinux
# cd /usr/src/linux-2.6.15.6
title CRUX_GDB
kernel (hd0,0)/boot/vmlinuz-2.6.15.5-kgdb root=/dev/hda2 kgdbwait
# vim /boot/grub/menu.lst
# cp /usr/src/linux-2.6.15.6/arch/i386/boot/bzImage /boot/vmlinuz-2.6.15.5-kgdb
# cp /usr/src/linux-2.6.15.6/System.map /boot
内核调试环境(Linux)
至此,内核调试环境就配置完成了,现在就像调试应用程序那样调试内核了。
Breakpoint () at kernel/kgdb.c:1212
1212 atomic_set(&kgdb_setting_breakpoint,0);
Warning: shared library handler failed to enable breakpoint
(gdb)