Linux 系统基本的调节-kgdb

转自:http://www.ibm.com/developerworks/cn/linux/l-kdb/index.html

调剂是软件开发过程遭到一个必备的环,在 Linux
内核开发的过程被也不可避免地会当什么样调节内核的问题。但是,Linux
系统的开发者出于保证基础代码是的设想,不甘于以 Linux
内核源代码树被参加一个调试器。他们以为根本中之调试器会误导开发者,从而引入破的匡正[1]。所以对
Linux
内核进行调试一直是只叫内核程序员发困难的题材,调试工作之艰苦性是外核级的开支区别为用户级开发的一个显著特点。

尽管缺少一栽内置的调试内核的有效性方式,但是 Linux
系统于根本发展的经过遭到呢日趋形成了有些监视内核代码和谬误跟踪的技术。同时,许多之补丁程序出现,它们也规范基础附加了基础调试之支持。尽管这些补
丁有些并无为 Linux
官方组织确认,但他们实在功能完善,十分精锐。调试内核问题时常,利用这些工具及法跟踪内核执行情况,并查看该内存和数据结构将凡老大管用的。

正文将率先介绍 Linux
内核上的局部本代码监视与谬误跟踪技术,这些调试和钉办法为所求的运用条件与使用方法要各有不同,然后主要介绍三种
Linux 内核的源代码级的调试方法。

  1. Linux 系统外核级软件之调剂技术

printk()
是调剂内核代码时不过常用之同种技术。在本代码中之一定岗位在printk()
调试调用,可以直接把所关切的音讯由打印及屏幕上,从而可以洞察程序的履路径和所关切的变量、指针等消息。
Linux 内核调试器(Linux kernel debugger,kdb)是 Linux
内核的补丁,它提供了平等种于系能运作时对内核内存和数据结构进行检讨的点子。Oops、KDB在篇章掌握
Linux
调试技术产生详尽介绍,大家可参考。
Kprobes
提供了一个强行进入任何内核例程,并打中断处理器无打扰地采集信息之接口。使用
Kprobes
可以轻松地搜集处理器寄存器和全局数据结构等调试信息,而随便需对Linux内核频繁编译和启动,具体行使方法,请参见下
Kprobes
调试内核。

上述介绍了拓展Linux内核调试以及跟踪时的常用技术与艺术。当然,内核调试以及跟的道还不断上述关联的这些。这些调试技术之一个联合的特
点在于,他们都非能够提供源代码级的行之有效的基业调试手段,有些只能称之为错误跟踪技术,因此这些艺术还只好提供个别的调节能力。下面将介绍三栽实用的源代码
级的根本调试方法。

回页首

  1. 利用KGDB构建Linux内核调试环境

kgdb提供了扳平栽采取 gdb调试 Linux
内核的体制。使用KGDB可以形象调试普通的应用程序那样,在基本中展开安装断点、检查变量值、单步跟踪程序运行等操作。使用KGDB调试时需要少令机械,
一大作为开发机(Development Machine),另一样高作为目标机(Target
Machine),两宝机械里通过串口或者因为极端网口相连。串口连接线是一律清RS-232接口的电缆,在其里面两端的第2底(TXD)与第3底(RXD)
交叉相连,第7脚(接地脚)直接相接。调试过程中,被调剂的基石运行在对象机上,gdb调试器运行于开发机上。

当下,kgdb发布支持i386、x86_64、32-bit
PPC、SPARC等几种体系布局的调试器。有关kgdb补丁的下载地址见参考资料[4]。

2.1 kgdb的调剂原理

安kgdb调试环境亟待也Linux内核应用kgdb补丁,补丁实现的gdb远程调试所欲的作用包括命令处理、陷阱处理同串口通讯3独主
要之局部。kgdb补丁的要作用是在Linux内核中补充加了一个调节Stub。调试Stub是Linux内核中的一致粗截代码,提供了运行gdb的开发机
和所调试内核之间的一个红娘。gdb和调试stub之间通过gdb串行协议进行报道。gdb串行协议是千篇一律种基于消息的ASCII码协议,包含了各种调试命
令。当装断点时,kgdb负责在安断点的指令前加一漫漫trap指令,当执行到断点时控制权就变换至调试stub中失。此时,调试stub的任务便是
使用远程串行通信协议将目前环境传送给gdb,然后于gdb处接受命令。gdb命令告诉stub下一致步该做什么,当stub收到继续执行的通令时,将卷土重来
程序的运转环境,把针对CPU的控制权重新交还给基础。

图片 1

2.2 Kgdb的安装以及安装

下我们以为Linux 2.6.7外查处为例详细介绍kgdb调试环境的树立过程。

2.2.1娇生惯养硬件准备

以下软硬件配置取自笔者进行考的体系部署情况:

图片 2

kgdb补丁的本子遵循如下命名模式:Linux-A-kgdb-B,其中A表示Linux的内核版本号,B为kgdb的版本号。以考以的kgdb补丁为条例,linux内核的版本为linux-2.6.7,补丁版本也kgdb-2.2。

大体连接好串口线后,使用以下命令来测试两尊机械里串口连接情况,stty命令可以针对串口参数进行安装:

于development机上实施:

 

stty ispeed 115200 ospeed 115200 -F /dev/ttyS0

 

当target机上执行:

 

stty ispeed 115200 ospeed 115200 -F /dev/ttyS0

 

以developement机上推行:

 

echo hello > /dev/ttyS0

 

每当target机上执行:

 

cat /dev/ttyS0

 

如若串口连接没有问题的语在以在target机的屏幕及展示”hello”。

2.2.2 安装及配置

脚我们用以kgdb补丁到Linux内核,设置基础选项并编译内核。这上头的素材相对较少,笔者这里为起详细的介绍。下面的劳作以开发机(developement)上开展,以地方介绍的试验环境呢例,某些具体步骤在实际的环境被或使开适度的更动:

I、内核的布与编译

 

[root@lisl tmp]# tar -jxvf linux-2.6.7.tar.bz2
[root@lisl tmp]#tar -jxvf linux-2.6.7-kgdb-2.2.tar.tar
[root@lisl tmp]#cd inux-2.6.7

 

告参考目录补丁包中文件README给来之求证,执行对承诺系布局的补丁程序。由于考试在i386体系布局及落成,所以只需要装一下补
丁:core-lite.patch、i386-lite.patch、8250.patch、eth.patch、core.patch、
i386.patch。应用补丁文件时,请以kgdb软件包内series文件所指定的各个,否则可能会见带预想不到的题目。eth.patch文件是
选择因最网口作为调剂之连接端口时需利用的补丁

利用补丁的通令如下所示:

 

[root@lisl tmp]#patch -p1 <../linux-2.6.7-kgdb-2.2/core-lite.patch 

 

比方基本是,那么以补丁时应当不见面面世任何问题(不会见生*.rej文件)。为Linux内核添加了补丁之后,需要进行基本的配备。内核的配备好按照你的习惯选择安排Linux内核的随机一种植办法。

 

[root@lisl tmp]#make menuconfig

 

当基础配置菜单的Kernel hacking选项中挑选kgdb调试项,例如:

 

  [*] KGDB: kernel debugging with remote gdb
       Method for KGDB communication (KGDB: On generic serial port (8250))  --->  
  [*] KGDB: Thread analysis 
  [*] KGDB: Console messages through gdb
[root@lisl tmp]#make
  

 

编译内核之前要留意Linux目录下Makefile中的优化增选,默认的Linux内核的编译都以-O2底优化级别进行。在斯优化级别之
下,编译器要针对性基础中的某些代码的实施各个进行改动,所以在调节时会见产出程序运行与代码顺序不平等的动静。可以管Makefile中之-O2抉择项改成吗
-O,但不得去丢-O,否则编译会出问题。为了要编译后的木本带有调试信息,注意在编译内核的当儿用添加-g选项。

不过,当选择”Kernel debugging->Compile the kernel with debug
info”选项后安排体系以自行打开调试选项。另外,选择”kernel debugging with
remote gdb”后,配置体系以电动打开”Compile the kernel with debug
info”选项。

基础编译完成后,使用scp命令进行以相关文书拷贝到target机上(当然也足以以其它的网络工具,如rcp)。

 

[root@lisl tmp]#scp arch/i386/boot/bzImage root@192.168.6.13:/boot/vmlinuz-2.6.7-kgdb
[root@lisl tmp]#scp System.map root@192.168.6.13:/boot/System.map-2.6.7-kgdb

 

假设系统启动使所待之某些设备驱动没有编译进基本的情形下,那么还待履行如下操作:

 

[root@lisl tmp]#mkinitrd /boot/initrd-2.6.7-kgdb 2.6.7
[root@lisl tmp]#scp initrd-2.6.7-kgdb root@192.168.6.13:/boot/ initrd-2.6.7-kgdb

 

II、kgdb的启动

以将编译出之基本拷贝的到target机器之后,需要安排体系引导程序,加入内核的启动选项。以下是kgdb内核引导参数的征:

图片 3

如表中所陈述,在kgdb
2.0版后基本的指引参数已经和以前的本子有所不同。使用grub引导程序时,直接拿kgdb参数作为基石vmlinuz的引导参数。下面给闹引导器的布示范。

 

title 2.6.7 kgdb
root (hd0,0)
kernel /boot/vmlinuz-2.6.7-kgdb ro root=/dev/hda1 kgdbwait kgdb8250=1,115200

 

以使用lilo作为引导程序时,需要将kgdb参放在由append修饰的语中。下面被闹用lilo作为指引器时的配置示范。

 

image=/boot/vmlinuz-2.6.7-kgdb
label=kgdb
    read-only
    root=/dev/hda3
append="gdb gdbttyS=1 gdbbaud=115200"

 

保存好上述配置后再度起动电脑,选择启动带调试信息的基石,内核将以不久之周转后在创造init内核线程之前住下来,打印出以下信息,并等候开发机的连续。

Waiting for connection from remote gdb…

于付出机上执行:

 

gdb
file vmlinux
set remotebaud 115200
target remote /dev/ttyS0

 

里头vmlinux是靠为源代码目录下编译出来的Linux内核文件之链接,它是从未有过通过压缩的木本文件,gdb程序于该公文中拿走各种符号地址信息。

如此,就同对象机上的kgdb调试接口建立了维系。一旦确立联网后,对Linux内的调试工作以及对日常的采取程序的调节就无啊界别了。任何时刻都可透过键入ctrl+c打断目标机的尽,进行具体的调节工作。

当kgdb
2.0事先的版本中,编译内核后当arch/i386/kernel目录下还见面变动可执行文件gdbstart。将该公文拷贝到target机器的/boot目录下,此时无论是需改变基础的起步配置文件,直接利用命令:

 

[root@lisl boot]#gdbstart -s 115200 -t /dev/ttyS0

 

足以KGDB内核引导启动完成后建立开发机与目标机之间的调节联系。

2.2.3 通过网络接口进行调试

kgdb也支撑使用以太网接口作为调试器的连年端口。在对Linux内核应用补丁包时,需采取eth.patch补丁文件。配置外核时在Kernel
hacking中选择kgdb调试项,配置kgdb调试端口为因太网接口,例如:

 

[*]KGDB: kernel debugging with remote gdb
Method for KGDB communication (KGDB: On ethernet)  ---> 
( ) KGDB: On generic serial port (8250)
(X) KGDB: On ethernet

 

除此以外利用eth0网口作为调剂端口时,grub.list的布如下:

 

title 2.6.7 kgdb
root (hd0,0)
kernel /boot/vmlinuz-2.6.7-kgdb ro root=/dev/hda1 kgdbwait kgdboe=@192.168.
5.13/,@192.168. 6.13/ 

 

任何的长河及行使串口作为连续端口时之安装过程同样。

在意:尽管可以动用以尽网口作为kgdb的调节端口,使用串口作为连续端口更加简便易行易行,kgdb项目组推荐应用串口作为调剂端口。

2.2.4 模块的调节方法

基本而加载模块的调试具有该特殊性。由于内核模块中各段的地址是在模块加载进基本的时段才最终确定的,所以develop机的gdb无法得到
各种符号地址信息。所以,使用kgdb调试模块所欲解决之一个题材是,需要经过某种方式获得可加载模块的尾声加载地址信息,并拿这些消息在到gdb环
境中。

I、在Linux 2.4基础中的内核模块调试方法

每当Linux2.4.x水源中,可以运用insmod -m命令输出模块的加载信息,例如:

 

[root@lisl tmp]# insmod -m hello.ko >modaddr

 

查阅模块加载信息文件modaddr如下:

 

.this           00000060  c88d8000  2**2
.text           00000035  c88d8060  2**2
.rodata         00000069  c88d80a0  2**5
……
.data           00000000  c88d833c  2**2
.bss            00000000  c88d833c  2**2
……

 

在这些消息遭受,我们关心的光生4独段子的地方:.text、.rodata、.data、.bss。在development机上以以上地方信息在到gdb中,这样就算可以展开模块功能的测试了。

 

(gdb) Add-symbol-file hello.o 0xc88d8060 -s .data 0xc88d80a0 -s 
.rodata 0xc88d80a0 -s .bss 0x c88d833c

 

这种方式也存在必然之欠缺,它不克调节模块初始化的代码,因为这时模块初始化代码都推行了了。而一旦无履模块的加载又力不从心取模块插入地址,更不容许在模块初始化之前设置断点了。对于这种调试要求可利用以下替代方式。

于target机上用上述方式赢得模块加载的地址信息,然后还用rmmod卸载模块。在development机上以沾的模块地址信息导入
到gdb环境面临,在基础代码的调用初始化代码之前安装断点。这样,在target机上再次插入模块时,代码用当履行模块初始化之前已下来,这样就是可以采用
gdb命令调试模块初始化代码了。

除此以外一种植调试模块初始化函数的点子是:当插入内核模块时,内核模块机制以调用函数sys_init_module(kernel/modle.c)执行针对内核模块的初始化,该函数将调用所插入模块的初始化函数。程序代码片断如下:

 

…… ……
    if (mod->init != NULL)
        ret = mod->init();
……  ……

 

在该语句上安断点,也会当履模块初始化之前停下来。

II、在Linux 2.6.x基石中之内核模块调试方法

Linux
2.6后的基石中,由于module-init-tools工具的改动,insmod命令不再支持-m参数,只有使其它的法门来博取模块加载到根本的地点。通过分析ELF文件格式,我们解程序中各段的义如下:

.text(代码段):用来存放可执行文件的操作指令,也就是说是她是可执行程序在外存种的镜像。

.data(数据段):数据段用来存放可执行文件中一度初始化全局变量,也就算是存放程序静态分配的变量和全局变量。

.bss(BSS段):BSS段包含了程序中不初始化全局变量,在内存中
bss段全部置零。

.rodata(只读段):该段保存着就读数据,在过程映象中布局不可写的段落。

通过当模块初始化函数中放置一下代码,我们得很易地取模块加载到内存中的地址。

 

……
int bss_var;
static int hello_init(void)
{
printk(KERN_ALERT "Text location .text(Code Segment):%p\n",hello_init);
static int data_var=0;
printk(KERN_ALERT "Data Location .data(Data Segment):%p\n",&data_var);
printk(KERN_ALERT "BSS Location: .bss(BSS Segment):%p\n",&bss_var);
……
}
Module_init(hello_init);

 

这边,通过当模块的初始化函数中补充加相同段子简单的次,使模块于加载时打印出当根本中之加载地址。.rodata段的地点可以经过执行命令readelf
-e hello.ko,取得.rodata于文书中之偏移量并加上段的align值得出。

为了使读者会再次好地进行模块的调剂,kgdb项目还发布了部分剧本程序能够自行探测模块的插入并自动更新gdb中模块的记号信息。这些本子程序的干活原理同前面说的工作经过相似,更多之音讯请看参考资料[4]。

2.2.5 硬件断点

kgdb提供对硬件调试寄存器的支撑。在kgdb中得以装三栽硬件断点:执行断点(Execution
Breakpoint)、写断点(Write Breakpoint)、访问断点(Access
Breakpoint)但未支持I/O访问的断点。
目前,kgdb对硬件断点的支持是经过宏来实现之,最多足装4单硬件断点,这些巨大的用法如下:

图片 4

在多少情况下,硬件断点的利用对基本的调节是深好之。有关硬件断点的定义及求实的运用说明见参考资料[4]

2.3.在VMware中搭建调试环境

kgdb调试环境需要动用有限宝微机分别出任development机和target机,使用VMware后我们一味使同样贵电脑就得顺利完成kgdb调试环境之搭建。以windows下的环境呢例,创建两玉虚拟机,一台作为开发机,一台作为目标机。

2.3.1虚拟机之间的串口连接

虚拟机中之串口连接可以使简单种植艺术。一种是点名虚拟机的串口连接至骨子里的COM上,例如开发机连接到COM1,目标机连接到COM2,然后
把有限独串口通过串口线相连接。另一样种植更加便利的主意是:在比高一些本子的VMware中还支持将失误口映射到命名管道,把简单个虚拟机的串口映射到和一个命名
管道。例如,在少只虚拟机中还选定同一个命名管道
\\.\pipe\com_1,指定target机的COM口为server端,并选”The other end
is a virtual
machine”属性;指定development机的COM口端为client端,同样指定COM口的”The
other end is a virtual machine”属性。对于IO
mode属性,在target上当选”Yield CPU on
poll”复选择框,development机不选择。这样,可以无需附加其他硬件,利用虚拟机就得搭建kgdb调试环境。
即降低了采取kgdb进行调试之硬件要求,也简化了成立调试环境之过程。

图片 5

2.3.2 VMware的使技术

VMware虚拟机是于占资源的,尤其是象上面那样以Windows中采用简单玉虚拟机。因此,最好为系统安排512M上述之内存,每令虚
拟机至少分配128M的内存。这样的硬件要求,对目前主流配置的PC而言并无是过强之要求。出于系统特性的设想,在VMware中尽量以字符界面进行调
试工作。同时,Linux系统默认情况下开了sshd服务,建议采取SecureCRT登陆到Linux进行操作,这样可产生比好之用户用界面。

2.3.3 在Linux下的虚拟机中以kgdb

对以Linux下面用VMware虚拟机的景,笔者没有开了其实的探索。从常理上而言,只需要在Linux下要创造同华虚拟机作为
target机,开发机的劳作好当事实上的Linux环境遭到展开,搭建调试环境的过程和地方所陈述之进程看似。由于单独需要创造同光虚拟机,所以用
Linux下之虚拟机搭建筑kgdb调试环境对系特性的求比较逊色。(vmware已经生产了Linux下的本)还得以development机上相当
使用一些其他的调试工具,例如功能重新精的cgdb、图形界面的DDD调试器等,以有益内核的调试工作。

图片 6

2.4 kgdb的一些特征与不足

运kgdb作为根本调试环境最充分之贫乏在针对kgdb硬件环境之渴求较高,必须采用有限宝微机分别作target和
development机。尽管用虚拟机的道可以就所以相同贵PC即会搭建调试环境,但是本着网外点的属性也提出了定的渴求,同时也长了搭建调试
环境时复杂程度。另外,kgdb内核的编译、配置也比较复杂,需要肯定之技巧,笔者就举行的时刻啊是花费了许多周折。当调试过程结束晚常,还用更打所
要发布的根本。使用kgdb并无克开展全程调试,也就是说kgdb并无可知用于调试系统一样开始之初始化引导过程。

然,kgdb是一个毋庸置疑的水源调试工具,使用它可进行针对性根本的到调试,甚至足以调节内核的中止处理程序。如果当一些图形化的开发工具的援手下,对根本的调剂将还有益于。

回页首

  1. 以SkyEye构建Linux内核调试环境

SkyEye是一个开源软件项目(OPenSource
Software),SkyEye项目的对象是于通用的Linux和Windows平台上模拟常见的嵌入式处理器体系。SkyEye实现了一个指令级的硬
件模拟平台,可以效仿多种嵌入式开发板,支持多CPU指令集。SkyEye 的为主是
GNU 的 gdb 项目,它将gdb和 ARM
Simulator很好地组成在了并。加入ARMulator
的力量下,它便足以来仿真嵌入式开发板,在其上面不仅可调节硬件让,还好调剂操作系统。Skyeye项目即都于嵌入式系统出世界取得了异常大
的放开。

3.1 SkyEye的装置以及μcLinux内核编译

3.1.1 SkyEye的安装

SkyEye的安不是本文要介绍的要害,目前曾闹大量之材料对这开展了介绍。有关SkyEye的设置及下的情要查阅参考资料
[11]。由于skyeye面目主要用来嵌入式系统领域,所以于skyeye上时常应用的是μcLinux系统,当然使用Linux作为skyeye上使用
行的系啊是可以的。由于介绍μcLinux
2.6于skyeye上编译的连带材料并无多,所以下进行详细介绍。

3.1.2 μcLinux 2.6.x的编译

若是在SkyEye中调剂操作系统内核,首先须使受调剂内核能当SkyEye所模拟的开发板上科学运行。因此,正确编译待调试操作系统内核并
配置SkyEye是进展基本调试之率先步。下面我们坐SkyEye模拟基于Atmel
AT91X40底开发板,并运行μcLinux 2.6乎例介绍SkyEye的现实调试方法。

I、安装交叉编译环境

先期安装交叉编译器。尽管在有的材料被证实以工具链arm-elf-tools-20040427.sh
,但是出于arm-elf-xxx与arm-linux-xxx对宏及链接处理的差,经验证明使用arm-elf-xxx工具链在链接vmlinux的
最后阶段将会拧。所以这边我们采用的陆续编译工具链是:arm-uclinux-tools-base-gcc3.4.0-20040713.sh,关
于该交叉编译工具链的下载地址请参见[6]。注意以下步骤太好用root用户来推行。

 

[root@lisl tmp]#chmod +x  arm-uclinux-tools-base-gcc3.4.0-20040713.sh
[root@lisl tmp]#./arm-uclinux-tools-base-gcc3.4.0-20040713.sh

 

设置交叉编译工具链之后,请保管工具链安装路径是于系统PATH变量中。

II、制作μcLinux内核

取得μcLinux发布包之一个顶易之办法是直访问uClinux.org站点[7]。该站点发布的根本版本可能无是风靡的,但若能够找到
一个流行的μcLinux补丁以及查找一个应和之Linux内核版本来制作一个风靡的μcLinux内核。这里,将下这种办法来打造时的μcLinux
内核。目前(笔者记录编写这篇时),所能够获的披露包之摩登版本是uClinux-dist.20041215.tar.gz。

下载uClinux-dist.20041215.tar.gz,文件之下载地址请参见[7]。

下载linux-2.6.9-hsc0.patch.gz,文件的下载地址请参见[8]。

下载linux-2.6.9.tar.bz2,文件的下载地址请参见[9]。

现咱们沾了所有的linux-2.6.9源代码,以及所需要的根本补丁。请准备一个发2GB空间的目录里来就以下制作μcLinux内核的经过。

 

[root@lisl tmp]# tar -jxvf uClinux-dist-20041215.tar.bz2
[root@lisl uClinux-dist]# tar -jxvf  linux-2.6.9.tar.bz2
[root@lisl uClinux-dist]# gzip -dc linux-2.6.9-hsc0.patch.gz | patch -p0 

 

要么用:

 

[root@lisl uClinux-dist]# gunzip linux-2.6.9-hsc0.patch.gz 
[root@lisl uClinux-dist]patch -p0 < linux-2.6.9-hsc0.patch

 

实行以上过程后,将以linux-2.6.9/arch目录下生成一个补丁目录-armnommu。删除原来μcLinux目录里之linux-2.6.x(即杀linux-2.6.9-uc0),并拿我们打好补丁的Linux内核目录更名为linux-2.6.x。

 

[root@lisl uClinux-dist]# rm -rf linux-2.6.x/
[root@lisl uClinux-dist]# mv linux-2.6.9 linux-2.6.x

 

III、配置和编译μcLinux内核

以只有是由于调试μcLinux内核的目的,这里没生成uClibc库文件与romfs.img文件。在揭示μcLinux时,已经预置了少数常用嵌入式开发板的配置文件,因此此一直利用这些安排文件,过程如下:

 

[root@lisl uClinux-dist]# cd linux-2.6.x
[root@lisl linux-2.6.x]#make ARCH=armnommu CROSS_COMPILE=arm-uclinux- atmel_
deconfig

 

atmel_deconfig文件是μcLinux发布时提供的一个配备文件,存放于目录linux-2.6.x
/arch/armnommu/configs/中。

 

[root@lisl linux-2.6.x]#make ARCH=armnommu CROSS_COMPILE=arm-uclinux-
oldconfig

 

下编译配置好的木本:

 

[root@lisl linux-2.6.x]# make ARCH=armnommu CROSS_COMPILE=arm-uclinux- v=1

 

诚如情况下,编译将胜利结束并在Linux-2.6.x/目录下生成未经压缩的μcLinux内核文件vmlinux。需要留意的凡为了调节μcLinux内核,需要开辟内核编译的调节选项-g,使编译后的基石带有调试信息。打开编译选项之艺术可以选取:

“Kernel debugging->Compile the kernel with debug
info”后以自动打开调试选项。也得以一直修改linux-2.6.x目录下之Makefile文件,为其打开调试开关。方法如下:。

 

CFLAGS  += -g 

 

太易并发的题材是摸索不至arm-uclinux-gcc命令的荒谬,主要由是PATH变量中从来不
包含arm-uclinux-gcc命令所在目录。在arm-linux-gcc的缺省安装情况下,它的装目录是/root/bin/arm-linux-tool/,使用以下命令将路径加至PATH环境变量中。

 

Export PATH=$PATH:/root/bin/arm-linux-tool/bin

 

IV、根文件系统的打造

Linux内核在起步的经常的最后操作有是加载根文件系统。根文件系统中存放了嵌入式
系统运用的享有应用程序、库文件以及另组成部分需使用的劳务。出于文章篇幅的考虑,这里不打算介绍根文件系统的制作方法,读者可以查一些别的系材料。值得注意的是,由安排文件skyeye.conf指定了装到基本中之清文件系统。

3.2 使用SkyEye调试

编译完μcLinux内核后,就得在SkyEye中调剂该ELF执行文件格式的本了。前面都说罢用SkyEye调试内核和使用gdb调试运用程序的法子一致。

内需提醒读者的是,SkyEye的布局文件-skyeye.conf记录了效仿的硬件配备与效仿执行行为。该配置文件是SkyEye系统中同样
个及其关键之公文,很多左与异常情况的起都和该公文有关。在装置配备SkyEye出错时,请首先检查该配置文件然后又拓展其它的做事。此时,所有的准
备工作一度完成,就可以开展基础的调剂工作了。

3.3应用SkyEye调试内核的表征以及不足

在SkyEye中得以拓展针对Linux系统内核的全程调试。由于SkyEye目前要支撑基于ARM内核的CPU,因此一般而言要运用交叉
编译工具编译待调试之Linux系统内核。另外,制作SkyEye中采取的基石编译、配置过程比较复杂、繁琐。不过,当调试过程结束晚不论需重新制造所假设发
布的本。

SkyEye只是对网硬件进行了必然水平达之效仿,所以当SkyEye与实际硬件环境相比较而言还是时有发生得的歧异,这对部分同硬件紧密有关的调节可能会见生肯定之影响,例如驱动程序的调节。不过对绝大多数软件之调试,SkyEye已经提供了精度足够的仿了。

SkyEye的产一个靶是与eclipse结合,有矣图形界面,能也调试和查看源码提供有有利于。

回页首

  1. 使用UML调试Linux内核

User-mode
Linux(UML)简单说来即是于Linux内运行的Linux。该档是设Linux内核成为一个周转于
Linux
系统之上单独的、用户空间的进程。UML并无是运作于某种新的硬件系统布局如上,而是运行于冲
Linux
系统调用接口所实现的虚拟机。正是由UML是一个用Linux作为用户空间进程运行的风味,可以动用UML来开展操作系统内核的调节。有关UML的牵线
请查阅参考资料[10]、[12]。

4.1 UML的装和调节

UML的装置需要同雅运行Linux
2.2.15之上,或者2.3.22之上的I386机器。对于2.6.8及其以前版本的UML,采用简单种植样式披露:一种植是因RPM包的样式发布,一栽是为
源代码的形式提供UML的设置。按照UML的证明,以RPM形式提供的安包比老且会时有发生成千上万问题。以二进制形式发布的UML包并无含所要之调试信
息,这些代码在通告时就开了档次不同之优化。所以,要惦记使UML调试Linux系统内核,需要使用最新的UML
patch代码和对应版本的Linux内核编译、安装UML。完成UML的补丁之后,会以arch目录下产生一个um目录,主要的UML代码都在该目录
下。

起2.6.9本后(包含2.6.9版的Linux),User-Mode
Linux已经随Linux内核源代码树一起发布,它存放于arch/um目录下。

编译好UML的内核之后,直接使用gdb运行已编译好的基本即可进行调节。

4.2利用UML调试系统基本的表征及不足

手上,用户模式 Linux
虚拟机也存一定之局限性。由于UML虚拟机是基于Linux系统调用接口的道实现的虚拟机,所以用户模式基本不克看主机系统上的硬件装置。因
此,UML并无切合为调试那些处理实际硬件的驱动程序。不过,如果所编写的基石程序不是硬件让,例如Linux文件系统、协议栈等情事,使用UML作为
调试工具要一个毋庸置疑的选料。

回页首

  1. 本调试配置选

为了方便调试和测试代码,内核提供了许多跟基本调试相关的配备选项。这些选择大部分且以基础配置编辑器的木本开发(kernel
hacking)菜单项中。在根本配置目录树菜单的其它地方也还有部分只是配备的调剂选项,下面将本着她们发早晚之介绍。

Page alloc debugging :CONFIG_DEBUG_PAGEALLOC:

未使该选项时,释放的外存页将从今本地址空间受到移出。使用该选项后,内核推迟移
出内存页的长河,因此会察觉内存泄漏的错误。

Debug memory allocations :CONFIG_DEBUG_SLAB:

欠打开该选择时,在基础执行内存分配之前将实施多种类型检查,通过这些品种检查只是
以发现如内核过量分配还是无初始化等悖谬。内核将会晤以历次分配内存前后时设置有些警告值,如果这些价值发生了变那么内核就会见理解内存已经为操作了并让有明确的提拔,从而使各种隐晦的不当变得容易受钉。

Spinlock debugging :CONFIG_DEBUG_SPINLOCK:

开辟这个选项时,内核将能发现spinlock未初始化及各种其他的一无是处,能用来破除有些死锁引起的缪。

Sleep-inside-spinlock checking:CONFIG_DEBUG_SPINLOCK_SLEEP:

打开该选择时,当spinlock的主人要睡觉时会见履行相应的检查。实际上就调用者目前从不睡眠,而仅仅是存在睡眠的可能时为会见被闹提示。

Compile the kernel with debug info :CONFIG_DEBUG_INFO:

打开该选择时,编译出的根本将会晤含有全体之调试信息,使用gdb时用这些调试信息。

Stack utilization instrumentation :CONFIG_DEBUG_STACK_USAGE:

该选择用于跟踪内核栈的浩起荒谬,一个基本栈溢出错误的肯定的观是出oops错
误却未曾排有系统的调用栈信息。该选项将如基本进行栈溢出检查,并要本进行栈使用的统计。

Driver Core verbose debug messages:CONFIG_DEBUG_DRIVER:

欠选择位于”Device drivers-> Generic Driver
Options”下,打开该选择使得本驱动核心发生大量的调试信息,并以她们记录及系统日志中。

Verbose SCSI error reporting (kernel size +=12K)
:CONFIG_SCSI_CONSTANTS:

拖欠选择位于”Device drivers/SCSI device
support”下。当SCSI设备出错时根本将受闹详细的错信息。

Event debugging:CONFIG_INPUT_EVBUG:

开辟该选择时,会以输入子系统的错误与持有事件都输出及系统日志中。该选项在发出了详细的输入报告的以,也会促成一定的安全题材。

如上基础编译选项需要读者根据自己所开展的基础编程的其实情况,灵活选择。在利用上述介绍的老三栽源代码级的基石调试工具时,一般用选择CONFIG_DEBUG_INFO选项,以要编译的水源包含调试信息。

回页首

  1. 总结

上面介绍了片调试Linux内核的计,特别是事无巨细介绍了三种植源代码级的基础调试工具,以及搭建这些本调试环境的不二法门,读者可因自己之景从中作出选择。

调节工具(例如gdb)的周转都需操作系统的支持,而此刻根本由于一些误的代码而非能够是履行针对系统的管制功能,所以对水源的调试要下一些破例的道开展。以上介绍的老三种植源代码级的调节方法,可以概括为以下简单栽政策:

I、为基本增加调试Stub,利用调试Stub进行长距离调试,这种调试策略要target及development机器才会就调试任务。

II、将虚拟机技术及调节工具相结合,使Linux内核在虚拟机中运作从而使调试器对根本进行调试。这种方针要制造符合当虚拟机中运作的系基本。

出于不同之调剂策略决定了进行调剂时不同之做事原理,同时为形成了各种调节方法不同之软硬件需求及各自的特色。

此外,需要说明的凡水源调试能力的控好特别程度达到取决经验和针对全体操作系统的入木三分理解。对系基本的一应俱全透彻的晓,将能够以深可怜程度及加速针对Linux系统内核的开支及调节。

对系基本的调试技术以及道毫无仅仅上面介绍所涉嫌的情,这里只是介绍了一些常常来看跟听到方法。在Linux内核向前向上的以,内核的调剂技术也于频频的前行。希望以上介绍的片主意会对读者出暨学Linux有所帮助。

回页首

参考资料

[1] http://oss.sgi.com/projects/kdb/

[2]
http://www.ibm.com/developerworks/cn/linux/sdk/l-debug/index.html

[3] http://www.ibm.com/developerworks/cn/linux/l-kdbug/

[4] http://www.ibm.com/developerworks/cn/linux/l-kprobes.html

[5] http://kgdb.linsyssoft.com/downloads.htm

[6] ftp://166.111.68.183

[8] http://www.uclinux.org/pub/uClinux/dist/

[9]
http://opensrc.sec.samsung.com/download/linux-2.6.9-hsc0.patch.gz

[10] http:// www.kernel.org

[11] http://user-mode-linux.sourceforge.net/

[12] http://www.ibm.com/developerworks/cn/linux/l-skyeye/part1/

[13]
http://www.ibm.com/developerworks/cn/views/linux/tutorials.jsp?cv_doc_id=84978

回页首

参考文献

[1]Robert Love Linux kernel development机械工业出版社

[2]陈渝 源代码开发之嵌入式系统软件分析及实施 北京航空航天大学出版社

[3]Alessandro Rubini Linux device driver 2se Edition O’Reilly

[4]Jonathan Corbet Linux device driver 3rd Edition O’Reilly

[5]李善平 Linux内核源代码分析好全 机械工业出版社

 

作者简介

李树雷,清华大学计算机系硕士研究生,主要从操作系统及中间件的钻。通过lisl03@mails.tsinghua.edu.cn
可以跟他联络

陈渝, 清华大学,通过 yuchen@tsinghua.edu.cn 可以和他关系。

发表评论

电子邮件地址不会被公开。 必填项已用*标注