用户操作
[即时聊天] [发私信] [加为好友]
fudan_abcID:fudan_abc
214267次访问,排名326好友0人,关注者38
fudan_abc的文章
原创 226 篇
翻译 0 篇
转载 0 篇
评论 326 篇
最近评论
yzdai:知道了,是SCSI设备号,CH,...等
yzdai:粗过了一遍.很棒很棒是不用多说.有些调用例就更好了.不是fs而是系统的调用例,比如禁止/允许USB/SCSI端口或设备,或取参数.还有漏掉的图.
zlzdsp或楼主有WORD/PDF请发一下或放在CSDN上.
"...,比如/dev/sda,然后读写这个文件就可以了"是对的.
"没有命令界面"是说没有console,要在自启动文件里自动运行应用程序.那也一样.<……
yzdai:粗过了一遍.很棒很棒是不用多说.有些调用例就更好了.不是fs而是系统的调用例,比如禁止/允许USB/SCSI端口或设备,或取参数.还有漏掉的图.
zlzdsp或楼主有WORD/PDF请发一下或放在CSDN上.
"...,比如/dev/sda,然后读写这个文件就可以了"是对的.
"没有命令界面"是说没有console,要在自启动文件里自动运行应用程序.那也一样.<……
yzdai:在过度疲劳的工作中看到楼主的文章,失笑了多回了.
虽然没太懂,也没来得及看完.我借助它解决了SCSI 设备号固定于硬端口的问题.
赞一个: 是金子总是要发光的.
yzdai:sd 2:0:0:0: Attached scsi removable disk sda
请问上面的 2:0:0:0 的含义?
文章分类
收藏
    相册
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky

    原创 kdb代码分析(六)收藏

    新一篇: kdb代码分析(七) | 旧一篇: kdb代码分析(五)

    我们带着这个参数回到kdb()里面去看,我们会发现,cpu都会跳到kdba_main_loop().这个函数定义于arch/i386/kdb/kdbasupport.c

        577 /*

        578  * kdba_main_loop

        579  *

        580  *      Do any architecture specific set up before entering the main kdb loop.

        581  *      The primary function of this routine is to make all processes look the

        582  *      same to kdb, kdb must be able to list a process without worrying if the

        583  *      process is running or blocked, so make all process look as though they

        584  *      are blocked.

        585  *

        586  * Inputs:

        587  *      reason          The reason KDB was invoked

        588  *      error           The hardware-defined error code

        589  *      error2          kdb's current reason code.  Initially error but can change

        590  *                      acording to kdb state.

        591  *      db_result       Result from break or debug point.

        592  *      regs            The exception frame at time of fault/breakpoint.  If reason

        593  *                      is SILENT or CPU_UP then regs is NULL, otherwise it should

        594  *                      always be valid.

        595  * Returns:

        596  *      0       KDB was invoked for an event which it wasn't responsible

        597  *      1       KDB handled the event for which it was invoked.

        598  * Outputs:

        599  *      Sets eip and esp in current->thread.

        600  * Locking:

        601  *      None.

        602  * Remarks:

        603  *      none.

        604  */

        605

        606 int

        607 kdba_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error,

        608                kdb_dbtrap_t db_result, struct pt_regs *regs)

        609 {

        610         int ret;

        611         kdb_save_running(regs);

        612         ret = kdb_main_loop(reason, reason2, error, db_result, regs);

        613         kdb_unsave_running(regs);

        614         return ret;

        615 }

    这个函数的核心部分自然是kdb_main_loop(),不过在它之前在它之后的这两个函数也有理由引起我们的注意.定义于kdb/kdbsupport.c:

        782 /*

        783  * kdb_save_running

        784  *

        785  *      Save the state of a running process.  This is invoked on the current

        786  *      process on each cpu (assuming the cpu is responding).

        787  * Inputs:

        788  *      regs    struct pt_regs for the process

        789  * Outputs:

        790  *      Updates kdb_running_process[] for this cpu.

        791  * Returns:

        792  *      none.

        793  * Locking:

        794  *      none.

        795  */

        796

        797 void

        798 kdb_save_running(struct pt_regs *regs)

        799 {

        800         struct kdb_running_process *krp = kdb_running_process + smp_processor_id();

        801         krp->p = current;

        802         krp->regs = regs;

        803         krp->seqno = kdb_seqno;

        804         krp->irq_depth = hardirq_count() >> HARDIRQ_SHIFT;

        805         kdba_save_running(&(krp->arch), regs);

        806 }

        807

        808 /*

        809  * kdb_unsave_running

        810  *

        811  *      Reverse the effect of kdb_save_running.

        812  * Inputs:

        813  *      regs    struct pt_regs for the process

        814  * Outputs:

        815  *      Updates kdb_running_process[] for this cpu.

        816  * Returns:

        817  *      none.

        818  * Locking:

        819  *      none.

        820  */

        821

        822 void

        823 kdb_unsave_running(struct pt_regs *regs)

        824 {

        825         struct kdb_running_process *krp = kdb_running_process + smp_processor_id();

        826         kdba_unsave_running(&(krp->arch), regs);

        827         krp->seqno = 0;

        828 }

    有这么一个结构体以及相应的数组,结构体定义于include/linux/kdbprivate.h:

        428 /* Save data about running processes */

        429

        430 struct kdb_running_process {

        431         struct task_struct *p;

        432         struct pt_regs *regs;

        433         int seqno;                              /* kdb sequence number */

        434         int irq_depth;                          /* irq count */

        435         struct kdba_running_process arch;       /* arch dependent save data */

        436 };

    这其中struct kdba_running_process则定义于include/asm-i386/kdbprivate.h:

        159 /* Arch specific data saved for running processes */

        160

        161 struct kdba_running_process {

        162         long esp;       /* CONFIG_4KSTACKS may be on a different stack */

        163 };

    熟悉x86体系结构的同志们一定不会对esp陌生.传说中的栈指针嘛.

    kdb_save_runningkdb_unsave_running内部调用了一对函数,它们都来自include/asm-i386/kdbprivate.h:

        165 static inline

        166 void kdba_save_running(struct kdba_running_process *k, struct pt_regs *regs)

        167 {

        168         k->esp = current_stack_pointer;

        169 }

        170

        171 static inline

        172 void kdba_unsave_running(struct kdba_running_process *k, struct pt_regs *regs)

        173 {

        174 }

    进一步跟踪你会发现,current_stack_pointer其实就是esp寄存器,不信你来看include/asm-i386/thread_info.h:

         87 /* how to get the current stack pointer from C */

         88 register unsigned long current_stack_pointer asm("esp") __attribute_used__;

    标准的gcc内联汇编,相比kernel中众多的内联汇编语句,这句算是最好理解的了.

    那么到这里基本上我们就知道了,kdb_save_runningkdb_unsave_running的作用无非就是在真正进入kdb之前保存之前那个进程的一些基本信息以及在从kdb出来以后及时的恢复之.

    最后需要提醒一下的是,kdb_running_process不仅仅是结构体的名字,它还是一个数组的名字,该数组定义于kdb/kdbsupport.c:

        780 struct kdb_running_process kdb_running_process[NR_CPUS];

    对于smp来说,有几个处理器这个数组就有几个元素,对于up来说,自然就是一个成员.kdb_save_runningkdb_unsave_running中都有用到这个数组名,以它为起始地址去计算与某个CPU相关的那个struct kdb_running_process结构体变量,并让krp指向它.

    这时候我们就可以全力关注kdb_main_loop().用下半身想想也知道这个函数必然定义于kdb/kdbmain.c:

       1506 /*

       1507  * kdb_main_loop

       1508  *

       1509  * The main kdb loop.  After initial setup and assignment of the controlling

       1510  * cpu, all cpus are in this loop.  One cpu is in control and will issue the kdb

       1511  * prompt, the others will spin until 'go' or cpu switch.

       1512  *

       1513  * To get a consistent view of the kernel stacks for all processes, this routine

       1514  * is invoked from the main kdb code via an architecture specific routine.

       1515  * kdba_main_loop is responsible for making the kernel stacks consistent for all

       1516  * processes, there should be no difference between a blocked process and a

       1517  * running process as far as kdb is concerned.

       1518  *

       1519  * Inputs:

       1520  *      reason          The reason KDB was invoked

       1521  *      error           The hardware-defined error code

       1522  *      reason2         kdb's current reason code.  Initially error but can change

       1523  *                      acording to kdb state.

       1524  *      db_result       Result code from break or debug point.

       1525  *      regs            The exception frame at time of fault/breakpoint.  If reason

       1526  *                      is SILENT or CPU_UP then regs is NULL, otherwise it

       1527  *                      should always be valid.

       1528  * Returns:

       1529  *      0       KDB was invoked for an event which it wasn't responsible

       1530  *      1       KDB handled the event for which it was invoked.

       1531  * Locking:

       1532  *      none

       1533  * Remarks:

       1534  *      none

       1535  */

       1536

       1537 int

       1538 kdb_main_loop(kdb_reason_t reason, kdb_reason_t reason2, int error,

       1539               kdb_dbtrap_t db_result, struct pt_regs *regs)

       1540 {

       1541         int result = 1;

       1542         /* Stay in kdb() until 'go', 'ss[b]' or an error */

       1543         while (1) {

       1544                 /*

       1545                  * All processors except the one that is in control

       1546                  * will spin here.

       1547                  */

       1548                 KDB_DEBUG_STATE("kdb_main_loop 1", reason);

       1549                 while (KDB_STATE(HOLD_CPU)) {

       1550                         /* state KDB is turned off by kdb_cpu to see if the

       1551                          * other cpus are still live, each cpu in this loop

       1552                          * turns it back on.

       1553                          */

       1554                         if (!KDB_STATE(KDB)) {

       1555                                 KDB_STATE_SET(KDB);

       1556                         }

       1557                 }

       1558                 KDB_STATE_CLEAR(SUPPRESS);

       1559                 KDB_DEBUG_STATE("kdb_main_loop 2", reason);

       1560                 if (KDB_STATE(LEAVING))

       1561                         break;  /* Another cpu said 'go' */

       1562

       1563                 if (!kdb_quiet(reason))

       1564                         kdb_wait_for_cpus();

       1565                 /* Still using kdb, this processor is in control */

       1566       &nbs