Linux内核调试和工具使用.docx
- 文档编号:10945097
- 上传时间:2023-02-23
- 格式:DOCX
- 页数:30
- 大小:1.01MB
Linux内核调试和工具使用.docx
《Linux内核调试和工具使用.docx》由会员分享,可在线阅读,更多相关《Linux内核调试和工具使用.docx(30页珍藏版)》请在冰豆网上搜索。
Linux内核调试和工具使用
Linux内核调试和工具使用
1.摘要
Linux内核调试跟普通用户态c程序调试的工作有点不同,如果所添加或修改代码是以模块形式加载于内核,则除了编码过程中包含的头文件、各种锁、信号量不同外,跟用户态的c程序的调试工作也没什么差别;但如果所修改代码是必须直接加入内核,并且会随linux系统启动而启动,则为了更容易调试,免于因代码错误系统死机而无法获得bug环境,就得使用kgdb远程调试或通过串口信将打印信息打印到另一台机子上。
本文主要介绍在虚拟机上进行linux内核调试时一些常用工具的使用和可能经常会遇到的一些问题的解决方法。
编写此份文档的目的是为了不让一部分同事对linux内核编译从未知开始摸索(将花费大量时间),提高工作效率。
本文档知识量不高,主要是针对从未接触过linux内核编码的同事使用。
2.Linux内核中编码注意项事
1.不同版本的内核源码,相同模块中的部分代码可能不同,如一些头文件或接口所在位置或参数可能不同,因此在编码前要确定在哪一个版本中编码,否者在不同版本进行代码移植时出现莫名其妙的bug是件令人头痛的事情。
Linux的内核源码放在/usr/src/或/usr/src/kernels中,查看当前系统所使用的内核的命令是:
uname–r
3.调试相关工具使用简介
3.1.samba工具共享文件夹
Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成。
samba是一个工具套件,在Unix上实现SMB(ServerMessageBlock)协议,或者称之为NETBIOS/LanManager协议.SMB协议通常是被windows系列用来实现磁盘和打印机共享.
1.安装samba工具时,首先要确保虚拟机与pc能够相互ping通,虚拟机有自己的的ip,同时虚拟机的连接模式是bridged,虚拟机不能上外网没关系。
Pc:
虚拟机:
2.如果是redhat的linxu系统,一般都装好了samba的图形界面软件,我用的是centos,是redhat其中一个版本,所以也有带。
如果没有装这个软件,可以到网上下载,安装资料很多,也有命令操作的,但比较不方便。
4.在打开samba服务器软件中进行简单的设置,指定要共享的目录,在“访问”页中可以设置访问密码,如果只在自己电脑使用也可以不设置。
5.注销下用户(虚拟机中的linux),然后在服务配置中启动samba的服务,在smb的框框打勾并启动它:
6.这时候在pc的windows系统就能访问到虚拟机共享的目录了,在我的电脑->工具栏->映射网络驱动器中将共享目录映射成一个网络驱动器,就可以像本地磁盘一样访问了:
3.2.使用VMware-tools工具共享
VMmware自带一个工具可实现虚拟机系统与pc系统进行文件共享,无论虚拟机装的是linux系统还是windows或其他系统。
不过要实现该功能前必须确定Vmware软件所在目录有对应系统vmare-tools的镜像文件,如linux.iso。
下面介绍如何实现虚拟机linux系统与pc进行文件共享方法。
1.准备工作
在虚拟机linux系统启动后,选择菜单VM->InstallVMwareTools将安装文件linux.iso载入光驱,这时在linux系统中的光盘驱动器会显示出Vmware-tools的安装软件包,例如VMwareTools-8.1.4-227600.tar.gz(不同版本文件名略有不同)。
2.安装软件包
注意应该安装后者,即VMwareTools-8.1.4-227600.tar.gz。
打开终端,在命令行中通过命令进行安装。
(1)将软件包拷贝到临时文件夹
cpVMwareTools-5.5.2-29772.tar.gz/tmp
(2)进入/tmp文件夹
cd/tmp
(3)解压软件
tarzxfVMwareTools-5.5.2-29772.tar.gz
这时/tmp下回出现一个叫vmware-tools-distrib的文件夹
(4)进入vmware-tools-distrib
cdvmware-tools-distrib
(5)安装软件
./vmware-install.pl
后面的步骤中会出现很多让你选择的项,一路回车即可。
安装成功之后会显示Enjoy–theVMwareteam。
3.共享文件夹
软件包安装好之后,需要在Window下共享文件夹以便在Linux下可以访问。
选择菜单VM->Settings,在弹出的VirtualMachineSettings对话框中选择Options属性页,在Settings中选择SharedFolers来设置共享文件夹,后面的步骤太简单就不说了。
4.在Linux中查看共享文件
进入/mnt,你会发现这里多了一个名为hgfs的文件夹,这个目录下就可以找到你在Windows下的共享的文件。
3.3.扩容虚拟机磁盘容量
一般我们在安装一台虚拟机时,一开始给它分配的硬盘空间不会很多,比如8G或更少,但在工作中可能因为编译升级内核、装载工具时,原先分配的空间被使用完,需要更多的硬盘空间。
这时候除了重装一个虚拟机外,我们可以使用在线扩容磁盘空间容量的方法实现。
以下介绍两种扩容方法:
a.要扩容虚拟机的硬盘容量,首先要让虚拟机能检查到它有额外的硬盘空间可以使用,这里有两种方法来增加虚拟机的硬盘容量
a)使用Vmware-tools工具增加硬盘容量,这种方式比较简单。
1,点击工具栏VM->setting,在Hardware页点击Add按钮,选择HardDisk增加一个磁盘,后面操作看你磁盘的实际分配情况了,可按如下图设置:
可按实际需求增加一个或多个磁盘(做raid磁盘阵列就是这样增加磁盘的):
b)上图出现了好多硬盘,可能有人看了烦,那么这里就介绍另一种方法,直接对一个虚拟硬盘进行扩容,这个方法复杂点。
1,首先要使用vmware的自带工具vmware-vdiskmanager.exe,我们可以在windos的命令行中进入到vmware的安装目录,也就是vmware-vdiskmanager.exe所在目录,执行vmware-vdiskmanager-x20Gb“OtherLinux2.6.xkernel-cl3.vmdk”
其中-x20Gb表示扩大至20Gb,详细帮助输入vmware-vdiskmanager回车即可查看。
OtherLinux2.6.xkernel-cl3.vmdk为虚拟硬盘完整路径名,路径中含空格,所以需用引号引起来。
若你有两个vmdk文件,其中一个比另一个多-flat,如RedHatLinux.vmdk和RedHatLinux-flat.vmdk,选择不带-flat的那个。
命令敲完会显示虚拟磁盘扩容的执行进度,这个过程比较慢,耐心等待。
2,虚拟磁盘扩容成功后,会显示如下信息,表示磁盘扩容成功,可以看到我们硬盘已经扩容到20G:
3,虚拟磁盘扩容成功后只表示这个磁盘有20G的容量,但除了之前的8G已经被使用,剩下的12G是未被使用的原始空间,也没有没分区,必须先将其分区后linux系统才能发现该部分磁盘空间,这里就用到了分区工具,这里使用的是gparted-live-0.6.4-1.iso(下载地址
4,首先按F2进入虚拟机的BIOS设置(如果进不去一直按Ctrl+Alt+Insert键,然后快速按F2,或者在工具栏选择WM->power->powerontoBIOS),将虚拟机的启动方式首选为cd启动(待分区调整结束后需改回原样,或将HardDrive调作第一启动项):
5,进入系统后按默认选择GPartedLive(Defaultsettings),直接Enter。
6,默认不更改keymap,直接Enter。
7,系统语言设置,输入26,回车。
注:
26表示简体中文。
8,选择图形系统模式,按默认的(0),直接回车。
9,这时候就进入磁盘分区界面,可以显示当前虚拟机有多少个磁盘以及分区的情况(右边的12G是我已分区完并加入逻辑卷的,本来是一片白色的空磁盘空间):
b,使用gparted分区工具的好处是能够动态扩容某一格式的文件系统大小,也就是如果我硬盘里还有未被分区的磁盘空间,我们可以直接增加到已有分区中(方法很简单,操作时按照提示就可完成)。
还有另一种简单方法是创建一个某种文件系统类型的磁盘分区,并在linux系统中将其mount到一个文件夹中使用。
1,但如果一个分区的文件系统使用的是lvm格式,那么就不能使用这个工具直接扩展它的大小,必须在linux系统中进行扩容,因为centos系统就是使用lvm管理分区,我们就介绍lvm的扩容方法,所以这里就直接将空闲的12G空间直接右击->新建,格式化成一个无文件系统的分区/dev/sda3,也就如下图的/dev/sda4(/dev/sda3在先前已被我加入到逻辑卷中了,所以文件系统会显示lvm2)
2,退出系统,双击Exit,选择shutdown,OK。
提示取出CD,恢复VMwareWorkstationBIOS第一启动项为硬盘启动。
3,进入系统后,打开终端,显示当前的硬盘信息,会发现新创建的一个分区/dev/sda3:
4,现在我们将新创建的分区sda3加入到已有的逻辑卷中,这里涉及到LVM的基础知识,想了解更多的可以google学习。
下面是简单操作:
pvcreate/dev/sda3/*初始化一个物理卷*/
vgextendVolGroup00/dev/sda3/*将这个物理卷添到逻辑卷组中*/
lvextend-L+12G/dev/VolGroup00/LogVol00/*将该逻辑卷组中的一个逻辑卷扩容12G*/
resize2fs/dev/VolGroup00/LogVol00/*重新设置文件系统大小*/
5,操作完后使用df命令查看磁盘使用情况,可以看到磁盘逻辑卷已经扩容成功:
3.4.打印内核调试信息方法
在调试linux内核代码时,我们经常会用printk将调试信息打印到终端上,但如果我们调试的代码会随内核启动时一起启动,或者调试模块时出bug死机了,这时就不能查看死机前打印的全部信息了。
下面就介绍将内核调试信息打印到另一台虚拟机上。
1,首先要clone或重新安装一台虚拟机,两台内核版本可以不一致。
要调试内核代码的虚拟机叫做目标机,用于查看调试信息的虚拟机叫做调试机(暂且随kgbd的叫法),目标机要增加一个串口设备,配置如下:
而开发机也要增加一个串口设备,配置如下:
2,进入目标机的/boot/grub/grub.conf,这是linux系统的启动引导配置文件,将某个内核的调试信息输出到终端重定向输出到串口,如下图:
3,进入调试机,打开一个终端确认一下系统是否已经安装minicom,如果没有请自行安装。
4,配置minicom(需要root用户),执行minicom–s后出现配置界面
使用向下键选择serialportsetup(串口设置),按回车出现设置界面
按A,设置串口设备为/dev/ttyS0
按E:
设置为115200。
按F:
设置为No
按回车,保存设定,回到主菜单,可以选择Savesetupasdf1(设为默认配置)。
设置完成后选择Exit退出
5,直接输入minicom,就可以像使用Windows的超级终端一样操作了。
我们还可以将当前信息保存到一个文件中作为bug信息使用,按住ctrl+A+L:
4.Linux内核升级与kgdb调试环境的搭建
4.1.linux内核升级
Linux内核升级的关键是要配置好makefile的config文件,根据不同环境我们对内核可能需要添加或删除一些模块,这就要具体问题具体分析。
这里只介绍简单的内核升级,我们在升级前直接将旧内核的.config文件拷贝到新内核源码中(在/usr/src/kernels/对应内核版本目录就好)。
1,终端进入要升级的内核源码目录下,敲makemenuconfig配置config文件,以下是几个配置点,其他都不用操作,按原先内核配置就可。
(1)LoadableModulesupport选项中,选上“Moduleunloading”和“Automatickernelmoduleloading”这两项;
(2)DeviceDrivers--->BlockDevices中选上“Loopbackdevicesupport”;
DeviceDrivers--->Multi-devicesupport(RAIDandLVM)处要选上“devicemapper support”;
DeviceDrivers--->Graphicssupport,一定要选上“Supportforframebufferdevices”;
DeviceDrivers --->USBsupport --->选上“USBMassStoragesupport”(如果是在实环境中,想要更多USB支持,就全选吧。
我的是在虚拟机中,用不着了)
DeviceDrivers --->;Networkdevicesupport --->Ethernet(10or100Mbit) ---><*> AMDPCnet32PCIsupport
(3)Filesystem--->(以下9个选项是关于ext2和ext3文件系统配置,全部选上)
Secondextendedfssupport
Ext2extendedattributes
Ext2POSIXAccessControlLists
Ext2SecurityLabels
Ext3journallingfilesystemsupport
Ext3extendedattributes
Ext3POSIXAccessControlLists
Ext3SecurityLabels
JBD(ext3)debuggingsupport
Filesystem--->DOS/FAT/NTFilesystems --->选上“NTFSfilesystemsupport”;
注意:
ext2和ext3文件系统配置很重要,也是必需的,如果对Ext3、Ext2文件的支持直接编译进内核,在你reboot时机器就会当掉,出现如下错误信息:
kernelpanic:
noinitfound,trypassinginit=optiontokernel.....
或者是:
VFS:
Cannotopenrootdevice"hdxy"orunknow-block(0,0)
Pleaseappendacorrect"root="bootoption
kernelpanic:
VFS:
Unabletomountrootfsonunknown-block(0,0)
或者是:
mount:
error19mountingext3
pivotroot:
pivot_root(/sysroot,/sysroot/initrd)failed:
2
umount/initrd/procfail:
2
Freeingunusedkernelmemory:
244kfreed
Kernelpanic–notsyncing:
Noinitfound.Trypassinginit=optiontokernel
(4)如果你在vmware下编译内核,硬盘用的是scsi的,以下三个选项必选:
DeviceDrivers---><*>SCSIdevicesupport (此项不选的话,下面两项就选择不上)
DeviceDrivers---><*>SCSIdevicesupport---><*>SCSIdisksupport
DeviceDrivers---><*>SCSIdevicesupport--->SCSIlow-leveldrivers---><*>;BusLogicSCSIsupport
2,执行以下命令编译该内核:
makebzImage&&makemodules&&makemodules_install&&makeinstall
3,编译完成后可以修改启动项,以决定启动选项,我们可以将我们升级的内核当成默认的启动项:
4.2.kgdb调试环境的搭建
kgdb实用程序是基于gdb的调试器,允许双机远程调试内核和内核模块驱动。
kgdb可帮助在内核代码中放置断点,这样就可以逐步通过断点来观察变量等操作。
我们可以利用两台虚拟机对修改的内核模块代码进行调试。
1,首先要确定你的内核版本,2.6.25以前的内核是没有添加kgdb补丁包的,必须要手动下载和添加对应内核版本的补丁包,如2.6.15.5的内核对应的kgdb是/linux-2.6.15.5-kgdb-2.4。
同样,首先将其解压后放入到/usr/src/目录下。
然后进入内核目录内,为内核打上kgdb的支持补丁,具体可以参考patch中README,选择需要得patch:
#cd/usr/src/linux-2.6.15.5
#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
2,添加完kgdb补丁后需要重新编译内核,在makemenuconfig只要修改以下内容(前提是你的.config已经配置完成,否者可以根据4.1内容重新配置)
Kernelhacking---两个KGDB选项(选上),另外,SerialportnumberforKGDB,默认选项是1,需要将其改为0。
3,重新编译内核,命令跟4.1一致。
编译完成后进入/boot/grub/grub.conf,修改启动项
title Red Hat Linux (2.6.18.8)
root (hd0,0)
kernel /vmlinuz-2.6.18.8 ro root=/dev/VolGroup00/LogVol00kgdbwaitkgdb8250=0,115200
initrd /initrd-2.6.18.8.img
4,linux2.6.25内核版本因为已经包含kgdb模块,因此不要打补丁,但配置makefile的config文件有所不同:
CONFIG_EXPERIMENTAL=y
Location:
->Generalsetup
->Promptfordevelopmentand/orincompletecode/drivers
CONFIG_KGDB=y
Location:
->Kernelhacking
->KGDB:
kerneldebugger
CONFIG_KGDB_SERIAL_CONSOLE=y(使用串口进行通信)
Location:
->Kernelhacking
->KGDB:
kerneldebugger
->KGDB:
usekgdbovertheserialconsole
CONFIG_DEBUG_RODATA=n
该选项是将内核的一些内存区域空间设置为只读,这样可能导致kgdb的
设置软断点功能失效。
所以推荐将该选项关闭。
最后将这两项打上*号:
CONFIG_DEBUG_INFO=y
该选项可以使得编译的内核包含一些调试信息,使得调试更容易。
CONFIG_FRAME_POINTER=y
该选项将使得内核使用帧指针寄存器来维护堆栈,从而就可以正确地执行堆栈回溯,即函数调用栈信息。
设置完成后,可以查看.config对应配置确保有如下配置:
CONFIG_DEBUG_RODATA=n
CONFIG_FRAME_POINTER=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDB_KDB=y
CONFIG_KDB_KEYBOARD=y
5,当编译完后,进行虚拟机clone,生成一个相同内核的开发机,同时目标机与开发机的串口设备配置与3.4内容一致。
6,当编译完后,修改启动项,跟2.6..25以前的内核版本有点不同,它的配置命令如下:
7,重新启动内核,这时候目标机将会处于等待gdb连接的状况:
8,这时候进入开发机内核源码主目录下启动gdb:
Gdb./vmlinux
设置串口速率:
(gdb)setremotebaud115200
连接到被调试机:
(gdb)targetremote/dev/ttyS0
9,若连接成功,则开发机屏幕显示如下(不同版本显示可能有所不同):
Remotedebuggingusing/dev/ttyS0
breakpoint()atkgdbstub.c:
1005
1005atomic_set(&kgdb_setting_breakpoint,0);
warning:
sharedlibraryhandlerfailedtoenablebreakpoint
(gdb)
输入以下命令,设置符号文件的搜索路径:
(gdb)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 内核 调试 工具 使用