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,那么就相当于艳照门事件之前陈冠希老师把他的硬盘格式化掉,后面所有的故事都不可能再发生了.

 

你可能感兴趣的:(linux,struct,compiler,makefile,patch,代码分析)