eecdc 发表于 2015-10-11 13:35:44

xen kdb代码分析点滴

  以xen-3.4.0 debug分支的代码为例。
  

[*]earlykdb中函数调用过程分析
  
  按上次seminar中报告的分析结果,主要流程如下图所示:
  
http://onexin.iyunv.com/source/plugin/onexin_bigdata/file:///root/图片/kdbearly调用关系.jpg
  -->__start_xen --> kdb_init --> kdb_trap_immed--> int $1
  (中断处理)
  kdb_handle_trap_entry --> kdbmain --> kdb_do_cmds
  
  但是没有找到中断注册点。其实查查一下xen的源码就可以知道"$1"其实是debug中断,具体如下:
  
  (xen/include/asm-x86/processor.h)
  
  /*
* Trap/fault mnemonics.
*/
#define TRAP_divide_error      0
#define TRAP_debug             1
#define TRAP_nmi               2
#define TRAP_int3            3
#define TRAP_overflow          4
  .....
  
  另外再参考"xen/arch/x86/x86_32/entry.S"中也定义了exception的列表,
  
  ENTRY(exception_table)
      .long do_divide_error
      .long do_debug
      .long do_nmi
      .long do_int3
      .long do_overflow
  ....
  并给出了debug的入口函数:
  
  ENTRY(debug)
      pushl $TRAP_debug<<16
      jmp   handle_exception
  
  再查找一下do_debug的处理函数,见“xen/arch/x86/traps.c”
  (这里需要稍微注意一下trap的实现包括两个文件:“xen/arch/x86/traps.c”和“xen/arch/x86/x86_32/traps.c”,前者
  是x86下通用traps的处理,后者是x86架构32位体系相关traps的处理。)
  
  asmlinkage void do_debug(struct cpu_user_regs *regs)
{
    struct vcpu *v = current;

    DEBUGGER_trap_entry(TRAP_debug, regs);

    if ( !guest_mode(regs) )
    {
      if ( regs->eflags & EF_TF )
....
  
  该处理函数又调用&quot;DEBUGGER_trap_entry&quot;,这个宏的定义见“xen/include/asm-x86/debugger.h”
  
  /* The main trap handlers use these helper macros which include early bail. */
#define DEBUGGER_trap_entry(_v, _r) /
    if ( debugger_trap_entry(_v, _r) ) return;
#define DEBUGGER_trap_fatal(_v, _r) /
    if ( debugger_trap_fatal(_v, _r) ) return;
  
  最终在函数&quot;debugger_trap_entry&quot;(xen/include/asm-x86/debugger.h)的定义中可以看到
  
  static inline int debugger_trap_entry(
    unsigned int vector, struct cpu_user_regs *regs)
{
    struct vcpu *v = current;

#if defined(XEN_KDB_CONFIG)
    if (kdb_handle_trap_entry(vector, regs))
      return 1;
#endif
....
  
  这样就接上图示中的“kdb_handle_trap_entry”函数,也就是说这个中断是注册到debug,上面的文字分析了中断相关的内容。
  
  2. 键盘编码
  
  按“ctrl+/”进入kdb由下面的代码实现:
  
  static void serial_rx(char c, struct cpu_user_regs *regs)
{
    static int switch_code_count = 0;

#ifdef XEN_KDB_CONFIG
    extern volatile int kdb_session_begun;

    /* if ctrl-/ pressed and kdb handles it, return */
    if (kdb_enabled && c == 0x1c) {
      if (!kdb_session_begun) {
            if (kdb_keyboard(regs))
                return;
      } else {
            kdb_ssni_reenter(regs);
            return;
      }
    }
    if (kdb_session_begun)      /* kdb should already be polling */
      return;               /* swallow chars so they don't buffer in dom0 */
#endif
  ....
  这涉及到键盘编码问题,可以参看下面的资料:
  
  键盘扫描码
  
  3. 一些名词
  
  这涉及到一些名词:exception(例外)、interrupt(中断)、trap(陷阱)、singnal(信号),他们的区别可以参考
  http://www.oldlinux.org/oldlinux/viewthread.php?tid=1478
  http://kerneltrap.org/node/6314
  
  不过几个帖子的说法还是有冲突,和体系结构有关,例如:x86、MIPS等。在Xen中hypercall通过int80来完成,应该是trap。
             版权声明:本文为博主原创文章,未经博主允许不得转载。
页: [1]
查看完整版本: xen kdb代码分析点滴