Linux内核:安装kdb

来源:互联网 发布:qq炫舞神域名片底图 编辑:程序博客网 时间:2024/05/25 05:37

一、下载kdb

        kdb以补丁的形式打包到Linux内核源码中。

        文件名:kdb-v4.4-2.6.32-common-6.bz2

                      kdb-v4.4-2.6.32-x86-6.bz2

        下载地址:ftp://oss.sgi.com/www/projects/kdb/download

二、打包kdb补丁到内核源码

将kdb补丁包放到Linux内核源码目录下:/usr/src/linux-2.6.32

2.1 解压缩kdb文件

        bzip2  -d  kdb-v4.4-2.6.32-common-6.bz2 
        bzip2  -d  kdb-v4.4-2.6.32-x86-6.bz2 

2.2 打包kdb文件
        patch  -p1  <  kdb-v4.4-2.6.32-common-6
        patch  -p1  <  kdb-v4.4-2.6.32-x86-6

三、配置Linux内核参数(使用KDB)

3.1 进入内核参数配置页面

        cd  /usr/src/linux-2.6.32

        make  menuconfig

3.2 设置内核参数

        Kernel hacking --->



        保存退出,即可看到.config。

3.3 查看内核参数

        vim  .config


        确保.config文件选项有如下:
            CONFIG_KDB=y
            CONFIG_KDB_MODULES=n
            CONFIG_KDB_OFF=n  (y、n均可)
            CONFIG_KDB_CONTINUE_CATASTROPHIC=0
            CONFIG_KDB_USB=y
            CONFIG_KDB_KDUMP=y
            CONFIG_KALLSYMS=y
            CONFIG_FRAME_POINTER=y

四、编译中可能遇到的问题

        以下错误是Linux 2.6.32内核中的错误。

        (参考资料,Linux 2.6.3.32内核编译安装kdb-v4.4-2.6.32)

4.1 错误:/arch/x86/kernel/traps.c

        错误:


        解决办法:

        去掉arch/x86/kernel/traps.c 文件中,415行的“}”。

4.2  错误:drivers/usb/host/ehci-hcd.c

        错误:


        解决办法:

                打一个手写的补丁,自己取名:ehci-q--echi_qh--patch

                patch  -p1  <  ehci-q--echi_qh--patch

        补丁ehci-q--echi_qh--patch中的内容:

diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.cindex dca7b17..52b4651 100644--- a/drivers/usb/host/ehci-q.c+++ b/drivers/usb/host/ehci-q.c@@ -594,6 +594,7 @@ qh_completions_kdb(struct ehci_hcd *ehci, struct ehci_qh *qh, struct urb *kdburb intdo_status = 0; u8state; u32halt = HALT_BIT(ehci);+struct ehci_qh_hw*hw = qh->hw;          /* verify params are valid */         if (!qh || !kdburb)@@ -612,6 +613,11 @@ qh_completions_kdb(struct ehci_hcd *ehci, struct ehci_qh *qh, struct urb *kdburb qh->qh_state = QH_STATE_COMPLETING; stopped = (state == QH_STATE_IDLE); + rescan:+last = NULL;+last_status = -EINPROGRESS;+qh->needs_rescan = 0;+ /* remove de-activated QTDs from front of queue.  * after faults (including short reads), cleanup this urb  * then let the queue advance.@@ -621,7 +627,6 @@ qh_completions_kdb(struct ehci_hcd *ehci, struct ehci_qh *qh, struct urb *kdburb struct ehci_qtd*qtd; struct urb*urb; u32token = 0;-intqtd_status;  qtd = list_entry (entry, struct ehci_qtd, qtd_list); urb = qtd->urb;@@ -651,10 +656,10 @@ qh_completions_kdb(struct ehci_hcd *ehci, struct ehci_qh *qh, struct urb *kdburb                                         spin_unlock (&ehci->lock);  count++;+last_status = -EINPROGRESS; } ehci_qtd_free (ehci, last); last = NULL;-last_status = -EINPROGRESS; }  /* ignore urbs submitted during completions we reported */@@ -663,7 +668,7 @@ qh_completions_kdb(struct ehci_hcd *ehci, struct ehci_qh *qh, struct urb *kdburb  /* hardware copies qtd out of qh overlay */ rmb ();-token = hc32_to_cpu(ehci, qtd->hw_token);+token = hc32_to_cpu(ehci, hw->hw_token);  /* always clean up qtds the hc de-activated */ if ((token & QTD_STS_ACTIVE) == 0) {@@ -710,37 +715,60 @@ qh_completions_kdb(struct ehci_hcd *ehci, struct ehci_qh *qh, struct urb *kdburb /* token in overlay may be most current */ if (state == QH_STATE_IDLE && cpu_to_hc32(ehci, qtd->qtd_dma)-== qh->hw_current)-token = hc32_to_cpu(ehci, qh->hw_token);+== hw->hw_current)+token = hc32_to_cpu(ehci, hw->hw_token);  /* force halt for unlinked or blocked qh, so we'll  * patch the qh later and so that completions can't  * activate it while we "know" it's stopped.  */-if ((halt & qh->hw_token) == 0) {+if ((halt & hw->hw_token) == 0) { halt:-qh->hw_token |= halt;+hw->hw_token |= halt; wmb (); } } -/* remove it from the queue */-qtd_status = qtd_copy_status(ehci, urb, qtd->length, token);-if (unlikely(qtd_status == -EREMOTEIO)) {-do_status = (!urb->unlinked &&-usb_pipecontrol(urb->pipe));-qtd_status = 0;+if (likely(last_status == -EINPROGRESS)) {+                        last_status = qtd_copy_status(ehci, urb,+                                        qtd->length, token);+                        if (last_status == -EREMOTEIO+                                        && (qtd->hw_alt_next+                                                & EHCI_LIST_END(ehci)))+                                last_status = -EINPROGRESS;++                        /* As part of low/full-speed endpoint-halt processing+                         * we must clear the TT buffer (11.17.5).+                         */+                        if (unlikely(last_status != -EINPROGRESS &&+                                        last_status != -EREMOTEIO)) {+                                /* The TT's in some hubs malfunction when they+                                 * receive this request following a STALL (they+                                 * stop sending isochronous packets).  Since a+                                 * STALL can't leave the TT buffer in a busy+                                 * state (if you believe Figures 11-48 - 11-51+                                 * in the USB 2.0 spec), we won't clear the TT+                                 * buffer in this case.  Strictly speaking this+                                 * is a violation of the spec.+                                 */+                                if (last_status != -EPIPE)+                                        ehci_clear_tt_buffer(ehci, qh, urb,+                                                        token);+} }-if (likely(last_status == -EINPROGRESS))-last_status = qtd_status;  if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { last = list_entry (qtd->qtd_list.prev, struct ehci_qtd, qtd_list); last->hw_next = qtd->hw_next; }++/* remove qtd; it's recycled after possible urb completion */ list_del (&qtd->qtd_list); last = qtd;++/* reinit the xacterr counter for the next qtd */+qh->xacterrs = 0; }  /* last urb's completion might still need calling */@@ -767,6 +795,21 @@ halt: ehci_qtd_free (ehci, last); } +        /* Do we need to rescan for URBs dequeued during a giveback? */+        if (unlikely(qh->needs_rescan)) {+                /* If the QH is already unlinked, do the rescan now. */+                if (state == QH_STATE_IDLE)+                        goto rescan;+               +                /* Otherwise we have to wait until the QH is fully unlinked.+                 * Our caller will start an unlink if qh->needs_rescan is+                 * set.  But if an unlink has already started, nothing needs+                 * to be done.+                 */+                if (state != QH_STATE_LINKED)+                        qh->needs_rescan = 0;+        }+ /* restore original state; caller must unlink or relink */ qh->qh_state = state; @@ -774,21 +817,26 @@ halt:  * it after fault cleanup, or recovering from silicon wrongly  * overlaying the dummy qtd (which reduces DMA chatter).  */-if (stopped != 0 || qh->hw_qtd_next == EHCI_LIST_END(ehci)) {+if (stopped != 0 || hw->hw_qtd_next == EHCI_LIST_END(ehci)) { switch (state) { case QH_STATE_IDLE: qh_refresh(ehci, qh); break; case QH_STATE_LINKED:-/* should be rare for periodic transfers,- * except maybe high bandwidth ...- */-if ((cpu_to_hc32(ehci, QH_SMASK)-& qh->hw_info2) != 0) {-intr_deschedule (ehci, qh);-(void) qh_schedule (ehci, qh);-} else-unlink_async (ehci, qh);+/* We won't refresh a QH that's linked (after the HC+                         * stopped the queue).  That avoids a race:+                         *  - HC reads first part of QH;+                         *  - CPU updates that first part and the token;+                         *  - HC reads rest of that QH, including token+                         * Result:  HC gets an inconsistent image, and then+                         * DMAs to/from the wrong memory (corrupting it).+                         *+                         * That should be rare for interrupt transfers,+                         * except maybe high bandwidth ...+                         */++                        /* Tell the caller to start an unlink */+                        qh->needs_rescan = 1; break; /* otherwise, unlink already started */ }

五、编译内核

        参考:http://blog.csdn.net/guowenyan001/article/details/38704775

六、启动KDB

6.1 激活KDB

        echo "1" >/proc/sys/kernel/kdb

6.2 启动KDB

        1. KDB处于激活状态,内核中有紧急情况时,会自动调用KDB。

        2. 按下Pause键,手动调用KDB。(需要在单用户模式下 ,sudo init 1进入单用户模式)(参考资料,KDB使用2)


参考资料:

        Linux内核调试器内幕:http://www.ibm.com/developerworks/cn/linux/l-kdbug/

        KDB使用2:http://blog.csdn.net/cybertan/article/details/6574023(单用户模式下,按下Pause,手动调用KDB)

        Linux 2.6.3.32内核编译安装kdb-v4.4-2.6.32:http://babybandf.blog.163.com/blog/static/61993532010715990178/   (解决2个错误问题)

0 0