kdb代码分析(一)

这是一个很冷门的话题,它受关注的程度永远也比不上陈冠希老师的摄影作品.不过人在江湖身不由己,因为工作原因我不得不接触它,不得不了解一点kdb的代码.

Kdb,也叫kernel debugger.Linux系统的内核调试器,它是一个开源工具,乃是SGI公司开发的.kdb适用于调试内核空间的程序代码,譬如进行设备驱动程序调试,内核模块的调试.OfficialLinux kernel并不包含kdb,所以我们必须从sgi的网站上去下载kdb.关于如何安装如何使用kdb,并非本系列文章的重点.实际上,关于kdb的入门,关于kdb的应用,许多年前,当我还在复旦念书的时候,当我才刚学会几个简单的Unix命令的时候,我就注意到网络上有人发表过这类文章了,所以介绍kdb,推广kdb,并不是我写此文的目的.我所写的是针对kdb本身的分析,针对的是kdb的源代码,或者说kdb的实现.

Linux内核每隔一段时间就会发布一个最新的版本,kdb则会相应的发布与之匹配的补丁.比如你Linux发布了2.6.10kernel,那么我sgi这边就发布针对2.6.10kernel的补丁.你发布了2.6.20kernel,我就发布针对你2.6.20的补丁.比如我之前为了看2.6.22.1kernel,我就下载了针对2.6.22.1的补丁,或者叫做patch.一共有三个patch:

localhost:/usr/src # ls kdb-v4.4-2.6.22-*

kdb-v4.4-2.6.22-common-1 kdb-v4.4-2.6.22-i386-1 kdb-v4.4-2.6.22-x86_64-1

这三个patch有多长呢:

localhost:/usr/src # wc -l kdb-v4.4-2.6.22-*

17943 kdb-v4.4-2.6.22-common-1

14753 kdb-v4.4-2.6.22-i386-1

14249 kdb-v4.4-2.6.22-x86_64-1

46945 total

我的神,46945.

第一个patch是最基本的patch.

第二个patch是针对i386.

第三个patch是针对x86_64.

如果你只对i386感兴趣,那么只关注前两个patch就可以了.

首先我们就来看一下这个commonpatch.这个patch开门见山的介绍了它对内核中哪些文件进行了修改,或者增加了哪些文件.

---

Documentation/kdb/kdb.mm | 492 +++++

Documentation/kdb/kdb_bp.man | 197 ++

Documentation/kdb/kdb_bt.man | 228 ++

Documentation/kdb/kdb_env.man | 46

Documentation/kdb/kdb_ll.man | 134 +

Documentation/kdb/kdb_md.man | 136 +

Documentation/kdb/kdb_ps.man | 96

Documentation/kdb/kdb_rd.man | 170 +

Documentation/kdb/kdb_sr.man | 68

Documentation/kdb/kdb_ss.man | 109 +

Documentation/kdb/slides | 1382 ++++++++++++++

Makefile | 1

drivers/char/keyboard.c | 10

drivers/hid/usbhid/hid-core.c | 20

drivers/hid/usbhid/usbkbd.c | 15

drivers/serial/8250.c | 53

drivers/serial/8250_early.c | 34

drivers/serial/sn_console.c | 73

drivers/usb/host/ohci-hcd.c | 47

drivers/usb/host/ohci-pci.c | 10

drivers/usb/host/ohci-q.c | 62

fs/proc/mmu.c | 16

fs/proc/proc_misc.c | 114 +

include/linux/console.h | 5

include/linux/dis-asm.h | 347 +++

include/linux/kdb.h | 166 +

include/linux/kdbprivate.h | 485 +++++

include/linux/sysctl.h | 1

init/main.c | 32

kdb/ChangeLog | 1672 +++++++++++++++++

kdb/Makefile | 28

kdb/kdb_bp.c | 619 ++++++

kdb/kdb_bt.c | 179 +

kdb/kdb_cmds | 32

kdb/kdb_id.c | 236 ++

kdb/kdb_io.c | 671 ++++++

kdb/kdbmain.c | 4034 ++++++++++++++++++++++++++++++++++++++++++

kdb/kdbsupport.c | 1134 +++++++++++

kdb/modules/Makefile | 14

kdb/modules/kdbm_pg.c | 645 ++++++

kdb/modules/kdbm_sched.c | 57

kdb/modules/kdbm_task.c | 199 ++

kdb/modules/kdbm_vm.c | 841 ++++++++

kdb/modules/kdbm_x86.c | 1096 +++++++++++

kdb/modules/kdbm_xpc.c | 1105 +++++++++++

kernel/exit.c | 3

kernel/kallsyms.c | 22

kernel/module.c | 19

kernel/printk.c | 14

kernel/sched.c | 79

kernel/signal.c | 49

mm/hugetlb.c | 19

mm/swapfile.c | 22

53 files changed, 17330 insertions(+), 8 deletions(-)

Kdb一个很突出的特点就是它牵涉的模块倍儿多.很明显,这其中有两个文件可能是我们故事的起点.一个是init/main.c,一个是kdb/kdbmain.c.

我们先看这个patchinit/main.c的修改.

4909 Index: linux/init/main.c

4910 ===================================================================

4911 --- linux.orig/init/main.c

4912 +++ linux/init/main.c

4913 @@ -66,6 +66,10 @@

4914 #include <asm/smp.h>

4915 #endif

4916

4917 +#ifdef CONFIG_KDB

4918 +#include <linux/kdb.h>

4919 +#endif /* CONFIG_KDB */

4920 +

4921 /*

4922 * This is one of the first .c files built. Error out early if we have compiler

4923 * trouble.

4924 @@ -187,6 +191,26 @@ static const char *panic_later, *panic_p

4925

4926 extern struct obs_kernel_param __setup_start[], __setup_end[];

4927

4928 +#ifdef CONFIG_KDB

4929 +static int __init kdb_setup(char *str)

4930 +{

4931 + if (strcmp(str, "on") == 0) {

4932 + kdb_on = 1;

4933 + } else if (strcmp(str, "on-nokey") == 0) {

4934 + kdb_on = 2;

4935 + } else if (strcmp(str, "off") == 0) {

4936 + kdb_on = 0;

4937 + } else if (strcmp(str, "early") == 0) {

4938 + kdb_on = 1;

4939 + kdb_flags |= KDB_FLAG_EARLYKDB;

4940 + } else

4941 + printk("kdb flag %s not recognised/n", str);

4942 + return 0;

4943 +}

4944 +

4945 +__setup("kdb=", kdb_setup);

4946 +#endif /* CONFIG_KDB */

4947 +

4948 static int __init obsolete_checksetup(char *line)

4949 {

4950 struct obs_kernel_param *p;

4951 @@ -606,6 +630,14 @@ asmlinkage void __init start_kernel(void

4952 pgtable_cache_init();

4953 prio_tree_init();

4954 anon_vma_init();

4955 +

4956 +#ifdef CONFIG_KDB

4957 + kdb_init();

4958 + if (KDB_FLAG(EARLYKDB)) {

4959 + KDB_ENTER();

4960 + }

4961 +#endif /* CONFIG_KDB */

4962 +

4963 #ifdef CONFIG_X86

4964 if (efi_enabled)

4965 efi_enter_virtual_mode();

很明显,增加了两个函数kdb_setup()kdb_init().kdb_setup()的作用是让你在启动的时候可以传递一个类似于”kdb=on”或者”kdb=off”的内核参数,换言之,它相当于一个开关,给你提供了一种选择,在启动系统的时候你就可以选择打开kdb或者索性关掉kdb.如果你选择了kdb=off,那么就相当于艳照门事件之前陈冠希老师把他的硬盘格式化掉,后面所有的故事都不可能再发生了.

你可能感兴趣的:(DB)