ºìÁªLinuxÃÅ»§
Linux°ïÖú

LinuxÔ´´úÂëÔĶÁ±Ê¼Ç£­£­Ó²¼þÖжÏ

·¢²¼Ê±¼ä:2006-09-25 10:40:15À´Ô´:ºìÁª×÷Õß:ͯѫ
¡¡¡¡LinuxÓ²¼þÖжÏ

¡¡¡¡Linux ÖÐ¶ÏºÍÆäËû²Ù×÷ϵͳµÄÖжϴ¦ÀíÒ»Ñù£¬ÒªÇóÓÐÓ²¼þºÍÈí¼þµÄÖ§³Ö¡£LinuxµÄºÃ´¦¾ÍÊÇ¿ÉÒÔ¿´µ½ºËÐÄ´¦ÀíÖжϵÄÒ»¾ÙÒ»¶¯£¬ÒÔ϶ÔlinuxµÄÖжϻúÖÆ×öÏêϸµÄ·ÖÎö¡£

¡¡¡¡Ê×ÏȶÔlinuxÖÐÄÜ´¦ÀíµÄÖжϷÖÀࣺ

¡¡¡¡1£®ÎïÀíÓ²¼þÉ豸²úÉúµÄÖжϣ¬ÕâЩÉ豸ÓëÖ÷°åÉϵÄi8259AÖжϿØÖÆÆ÷ÏàÁ¬£¬¾ßÌåµÄÁ¬½Ó¿ÉÒÔÕÒ±¾¡¶¼ÆËã»ú×é³ÉÔ­Àí¡·¿´¿´¡£linuxÖпÉÒÔ´¦ÀíµÄÓÐ16¸öÖжϺţ¬µ«Õâ²¢²»ÒâζlinuxÖ»ÄÜ´¦Àí16¸öÍâÉèÖжÏÇëÇó£¬Êµ¼ÊÉÏÐí¶àÍâÉèÊÇ¿ÉÒÔ¹²ÏíÖжϺţ¬Õâ¸öÒªÇó²Ù×÷ϵͳµÄÈí¼þÖ§³Ö£¬ÔÚºóÃæ¿ÉÒÔ¿´µ½linuxÊÇÈç¹û´¦Àí¡£

¡¡¡¡2£®Òì³££¬Òì³£ÊÇÎÞ·¨Ô¤²âµÄÒâÍâ¡£Èç±»0³ý¡¢È±Ò³£º

[code]¡¡¡¡set_trap_gate(0,÷_error);
¡¡¡¡set_trap_gate(1,&debug);
¡¡¡¡set_intr_gate(2,&nmi);
¡¡¡¡set_system_gate(3,&int3); /* int3-5 can be called from all */
¡¡¡¡set_system_gate(4,&overflow);
¡¡¡¡set_system_gate(5,&bounds);
¡¡¡¡set_trap_gate(6,&invalid_op);
¡¡¡¡set_trap_gate(7,&device_not_available);
¡¡¡¡set_trap_gate(8,&double_fault);
¡¡¡¡set_trap_gate(9,&coprocessor_segment_overrun);
¡¡¡¡set_trap_gate(10,&invalid_TSS);
¡¡¡¡set_trap_gate(11,&segment_not_present);
¡¡¡¡set_trap_gate(12,&stack_segment);
¡¡¡¡set_trap_gate(13,&general_protection);
¡¡¡¡set_trap_gate(14,&page_fault);
¡¡¡¡set_trap_gate(15,&spurious_interrupt_bug);
¡¡¡¡set_trap_gate(16,&coprocessor_error);
¡¡¡¡set_trap_gate(17,&alignment_check);
¡¡¡¡set_trap_gate(18,&machine_check);
¡¡¡¡set_trap_gate(19,&simd_coprocessor_error);
¡¡¡¡
¡¡¡¡set_system_gate(SYSCALL_VECTOR,&system_call);
¡¡¡¡
¡¡¡¡/*
¡¡¡¡ * default LDT is a single-entry callgate to lcall7 for iBCS
¡¡¡¡ * and a callgate to lcall27 for Solaris/x86 binaries
¡¡¡¡ */
¡¡¡¡set_call_gate(&default_ldt[0],lcall7);
¡¡¡¡set_call_gate(&default_ldt[4],lcall27);[/code]
¡¡¡¡
¡¡¡¡ÒÔÉÏÕª×Ôi386\kernel\Traps.c-> trap_init()º¯ÊýƬ¶Ï£¬trap_init()º¯ÊýÓÖ±»²Ù×÷ϵͳµÄ³õʼ»¯¹¤×÷start_kernel()º¯Êýµ÷Ó㬴ÓÁбíÖпÉÒÔ¿´³ölinuxËù´¦ÀíµÄÒì³£¡£´ÓÉÏÃæµÄ×¢ÊÍÖпÉÒÔ¿´µ½Òì³£3£­5£¬¾ÍÊÇÖжÏÖ¸Áîint3£¬int4£¬int5¿ÉÒÔ±»ËùÓеĽø³Ìµ÷Óã¬ÕâÈý¸öʵ¼ÊÉÏÊǵ÷ÊÔ³ÌÐòËùÓõ½µÄ£¬ËùÒÔµ±È»Äܱ»ÄãµÄ³ÌÐòµ÷Ó᣶øÆäËûµÄÒì³£Ö»Äܱ»´¦ÓÚÌØÈ¨¼¶0µÄ½ø³Ìµ÷Óã¬Ò²¾ÍÊÇ˵ÕâЩÒì³£Ö»Äܱ»ÄÚºËËù´¦Àí£¬µÀÀí·Ç³£Ã÷ÏÔ£¬µ«ÊÇʵÏÖÆðÀ´¾Í²»ÊÇÄÇôֱ½ÓÁË¡£
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 5 ÌõÆÀÂÛ

  1. ͯѫ ÓÚ 2006-09-25 10:46:55·¢±í:

    ¡¡¡¡Ò»¿´¾ÍÃ÷°×£¬±£´æµ±Ç°½ø³ÌµÄ¼Ä´æÆ÷£¬±£´æÔÚµ±Ç°½ø³ÌµÄϵͳ¶ÑÕ»Àï¡£ret_from_intr¹À¼Æ¿ÉÒԲ³öÁË£¬¾ÍÊÇ´¦ÀíÖжϷµ»ØµÄº¯Êý£¬µ«ÊÇΪʲôҪ½ø¶ÑջĨ£¿Õâ¸ö¾ÍºÍdo_IRQº¯ÊýµÄµ÷Ó÷½Ê½ÓйØÁË£¬do_IRQº¯ÊýÊÇͨ¹ýjmpÌø¹ýÈ¥Ö´Ðеģ¬Ò²¾ÍÊÇûÓаѺ¯ÊýºóµÄÖ¸ÁîµØÖ·ÈëÕ»£¬ÕâÑùº¯Êý·µ»Øºó¾ÍÕÒ²»µ½ÏÂÒ»ÌõÖ¸ÁîÁË£¬pushl $ret_from_intr¾Í½â¾öÁËÕâ¸öÎÊÌ⣬º¯Êýdo_IRQ·µ»Øºó£¬Ö¸Áîret¾Í°Ñret_from_intr³öÕ»£¬Í¬Ê±×°Èëµ½ipÖУ¬¾Íµ½ret_from_intrÖ´ÐÐÁË£¬ÕâÊÇÒ»¸ö»ã±à³ÌÐòÉè¼ÆµÄ¼¼ÇÉ£¬±»Óõ½ÁËÕâÀҲÄѹֻá°ÑÈË¿´µÃҪץ¿ñÁË¡£

    ¡¡¡¡ÈÆÁËÀϰëÌ죬Ã÷°×ÁË´¦ÀíÓ²¼þÖжϷþÎñµÄÊǺ¯Êýdo_IRQ¡£¿´Ò»ÏÂÕâ¸öº¯Êý£¬ÔÚirq.cÀïÃæ¡£ÈƹýһЩ´íÎó´¦ÀíºÍSMPµÄ´¦Àí£¬¼òµ¥µØ¿´Ò»Ï£º

    [code]¡¡/*
    ¡¡¡¡ * do_IRQ handles all normal device IRQ's (the special
    ¡¡¡¡ * SMP cross-CPU interrupts have their own specific
    ¡¡¡¡ * handlers).
    ¡¡¡¡ */
    ¡¡¡¡asmlinkage unsigned int do_IRQ(struct pt_regs regs)
    ¡¡¡¡{
    ¡¡¡¡int irq = regs.orig_eax & 0xff;
    /* high bits used in ret_from_ code */
    ¡¡¡¡ int cpu = smp_processor_id();
    ¡¡¡¡ irq_desc_t *desc = irq_desc + irq;
    ¡¡¡¡ struct irqaction * action;
    ¡¡¡¡ unsigned int status;
    ¡¡¡¡
    ¡¡¡¡ kstat.irqs[cpu][irq]++;
    ¡¡¡¡ spin_lock(&desc->lock);
    ¡¡¡¡ desc->handler->ack(irq);
    ¡¡¡¡ ¡­¡­.
    ¡¡¡¡action = NULL;
    ¡¡¡¡ if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
    ¡¡¡¡ action = desc->action;
    ¡¡¡¡ status &= ~IRQ_PENDING; /* we commit to handling */
    ¡¡¡¡ status |= IRQ_INPROGRESS; /* we are handling it */
    ¡¡¡¡ }
    ¡¡¡¡ desc->status = status;
    ¡¡¡¡
    ¡¡¡¡for (;;) {
    ¡¡¡¡ spin_unlock(&desc->lock);
    ¡¡¡¡ handle_IRQ_event(irq, ®s, action);
    ¡¡¡¡ spin_lock(&desc->lock);
    ¡¡¡¡
    ¡¡¡¡ if (!(desc->status & IRQ_PENDING))
    ¡¡¡¡
    ¡¡¡¡break;
    ¡¡¡¡ desc->status &= ~IRQ_PENDING;
    ¡¡¡¡ }
    ¡¡¡¡¡­¡­.
    ¡¡¡¡if (softirq_active(cpu) & softirq_mask(cpu))
    ¡¡¡¡ do_softirq();
    ¡¡¡¡ return 1;
    ¡¡¡¡}
    ¡¡¡¡¹Ø¼üÔÚº¯Êýndle_IRQ_event(irq, ®s, action)ÖУ¬
    ¡¡¡¡int handle_IRQ_event(unsigned int irq,
    struct pt_regs * regs, struct irqaction * action)
    ¡¡¡¡{
    ¡¡¡¡ int status;
    ¡¡¡¡ int cpu = smp_processor_id();
    ¡¡¡¡
    ¡¡¡¡ irq_enter(cpu, irq);
    ¡¡¡¡
    ¡¡¡¡ status = 1; /* Force the "do bottom halves" bit */
    ¡¡¡¡
    ¡¡¡¡ if (!(action->flags & SA_INTERRUPT))
    ¡¡¡¡ __sti();
    ¡¡¡¡
    ¡¡¡¡ do {
    ¡¡¡¡ status |= action->flags;
    ¡¡¡¡ action->handler(irq, action->dev_id, regs);
    ¡¡¡¡ action = action->next;
    ¡¡¡¡ } while (action);
    ¡¡¡¡ if (status & SA_SAMPLE_RANDOM)
    ¡¡¡¡ add_interrupt_randomness(irq);
    ¡¡¡¡ __cli();
    ¡¡¡¡
    ¡¡¡¡ irq_exit(cpu, irq);
    ¡¡¡¡
    ¡¡¡¡ return status;
    ¡¡¡¡}[/code]

    ¡¡¡¡ÔÚandle_IRQ_eventº¯ÊýµÄdo-whileÑ­»·ÖУ¬ÖÕÓÚ¿´µ½ÁËaction = action->next£¬ÏµÍ³ÔÚÑØ×ÅÁ´±í´¦ÀíÖжϣ¬ºÍÔ­ÏȵÄÉèÏëÊÇÒ»Öµġ£¿´µ½ÕâÀÔٻص½Ç°Ã棬Ã÷°×ÁËinterruptÊý×éµÄ×÷Óá£

    ¡¡¡¡ÏÖÔÚÔٻعËÒ»ÏÂlinux´¦ÀíÖжϵÄÕû¸ö¹ý³Ì£¬Ó²¼þ²úÉúÒ»¸öÖжϣ¬cpuµÃµ½ÖжϺţ¬ÏµÍ³ÔÚIDTÖÐÕÒµ½ºÍÕâ¸öÖжϺŶÔÓ¦µÄÖжÏÏòÁ¿£¬´ÓÖжÏÏòÁ¿Öеõ½IRQ0x0n_interuptµÄº¯ÊýµØÖ·£¬Ö´ÐÐÕâ¸öº¯Êý£¬Ìøµ½common_interrupt£¬µ½call_do_IRQ£¬µ½do_IRQ£¬×îºóµ½handle_IRQ_event¡£

    ¡¡¡¡´ÓÕû¸öÖжϵĴ¦Àí¹ý³ÌÀ´Ëµ£¬ÒÔÉÏÒ²¾ÍÊÇÉæ¼°µ½ÁËÖжϵijõʼ£¬´¦ÀíµÄ·½Ã棬»¹ÓÐÓû§ÊÇÈçºÎÉèÖÃÖжϴ¦Àíº¯Êý£¬Õâ¸öÔÚrequest_IRQº¯ÊýÖд¦Àí¡£Ó²¼þÖжϾÍдÕâô¶àÁË£¬»¹ÓÐÈíÖжϺÍϵͳµ÷ÓÃûÓÐд£¬µÈ¿´ÍêºóÔÙ˵¡£

  2. ͯѫ ÓÚ 2006-09-25 10:45:16·¢±í:

    ¡¡¡¡Ò»¸öIRQLIST_16(x)¶¨ÒåÁË16¸öº¯Êý£¬Ãû³ÆÊÇIRQ0x0n_interrupt£¬±ÈÈç3ºÅÖжϵĺ¯Êý¾ÍÊÇvoid IRQ0x03_interrupt(void)¡£Õâ¸öº¯ÊýµÄ¶¨ÒåÔÚlinuxµÄÔ´ÎļþI8259a.cÖУ¬¾ÍÊÇͨ¹ýÒ»´®µÄºê¶¨ÒåÑÚ¸ÇÁË£¬×Ðϸ¿´:

    [code]¡¡#define BI(x,y) BUILD_IRQ(x##y)
    ¡¡¡¡
    ¡¡¡¡#define BUILD_16_IRQS(x) BI(x,0) BI(x,1) BI(x,2)
    BI(x,3) BI(x,4) BI(x,5) BI(x,6) BI(x,7) BI(x,8) BI(x,9)
    BI(x,a) BI(x,b) BI(x,c) BI(x,d) BI(x,e) BI(x,f)
    ¡¡¡¡
    ¡¡¡¡/*
    ¡¡¡¡ * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC)
    interrupts:
    ¡¡¡¡ * (these are usually mapped to vectors 0x20-0x2f)
    ¡¡¡¡ */
    ¡¡¡¡BUILD_16_IRQS(0x0)£¬[/code]

    ¡¡¡¡ºêBUILD_16_IRQS¶¨ÒåÁË16¸öBI£¬Ã¿Ò»¸öBI¶¼Í¨¹ýºêBUILD_IRQ(x##y)Õ¹¿ª£¬ÕÒ³öBUILD_IRQ(x##y)µÄºê¶¨Ò壺

    [code]#define BUILD_IRQ(nr) asmlinkage void IRQ_NAME(nr);
    __asm__( "\n"__ALIGN_STR"\n" SYMBOL_NAME_STR(IRQ)
    #nr "_interrupt:\n\t" "pushl $"#nr"-256\n\t"
    "jmp common_interrupt");[/code]

    ¡¡¡¡ÔÙÕÒ³öIRQ_NAMEµÄºê¶¨Ò壺

    [code]#define IRQ_NAME2(nr) nr##_interrupt(void)
    #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)[/code]

    ¡¡¡¡¡¡¡¡ÖÕÓÚÕÒ³öIRQ0x03_interruptµÄ¶¨Ò壬¾ÍÊÇ

    [code]__asm__( "\n"__ALIGN_STR"\n" SYMBOL_NAME_STR(IRQ)
    #nr "_interrupt:\n\t" "pushl $"#nr"-256\n\t"
    "jmp common_interrupt");
    ¡¡¡¡·­ÒëΪcÓïÑÔ¾ÍÊÇ
    ¡¡¡¡{
    ¡¡¡¡ IRQ#nr_interrupt:
    ¡¡¡¡ Pushl nr-256
    ¡¡¡¡ Jmp common_interrupt
    ¡¡¡¡}[/code]

    ¡¡¡¡Õâ¸öÒ»Á¬´®µÄºê¶¨Òå¾ÍÊÇΪÁ˼òдԴ´úÂ룬·ñÔòҪд16±àÏàͬµÄ´úÂë¡£Èç¹ûÓÐÈË¿´¹ý¡¶ÉîÈëdz³öMFC¡·£¬¶ÔÕâ¸öÓ¦¸Ã±È½ÏÊìϤ£¬ÔÚMFCÖеÄÀඨÒåÀïÃæÒ²Óõ½Á˺ܶàµÄºê£¬Í¬ÑùÈÃÄ㿴ɵÁËÑÛ¡£ÕâЩº¯Êý¶¼ÒªÌøµ½common_interruptÏÂÃæµÄ´úÂëÖ´ÐУ¬ÄÇôÕâ¸öÓÖÔÚÄÄÀÔÚÒ»¸öÍ·ÎļþÀïÃæ£¬Õâ¸öÎļþÊÇHw_irq.h£¬¶¨ÒåÈçÏ£º

    [code]¡¡#define BUILD_COMMON_IRQ() asmlinkage void call_do_IRQ(void);
    __asm__( "\n" __ALIGN_STR"\n"
    "common_interrupt:\n\t" SAVE_ALL
    "pushl $ret_from_intr\n\t" SYMBOL_NAME_STR(call_do_IRQ)":\n\t"
    "jmp "SYMBOL_NAME_STR(do_IRQ));[/code]

    ¡¡¡¡Ìøµ½ÁËÒ»¸öº¯Êýcall_do_IRQÀïÃæ£¬Õâ¸öº¯ÊýÓÃc¸´Ð´Ò»±é¾ÍÊÇ£º

    [code]void call_do_IRQ(void)
    ¡¡¡¡{
    ¡¡¡¡ common_interrupt:
    ¡¡¡¡ SAVE_ALL
    ¡¡¡¡pushl $ret_from_intr
    ¡¡¡¡call_do_IRQ:
    ¡¡¡¡ jmp do_IRQ
    ¡¡¡¡}[/code]

    ¡¡¡¡SAVE_ALLÊÇÒ»¸öºê£º

    [code]#define SAVE_ALL "cld\n\t" "pushl %es\n\t"
    "pushl %ds\n\t" "pushl %eax\n\t" "pushl %ebp\n\t"
    "pushl %edi\n\t" "pushl %esi\n\t" "pushl %edx\n\t"
    "pushl %ecx\n\t" "pushl %ebx\n\t" "movl $"
    STR(__KERNEL_DS) ",%edx\n\t" "movl %edx,%ds\n\t"
    "movl %edx,%es\n\t"[/code]

  3. ͯѫ ÓÚ 2006-09-25 10:43:22·¢±í:

    ¡¡¡¡hw_irq_controller¾ÍÊÇ¿ØÖÆÖжϿØÖÆÐ¾Æ¬µÄ£¬ËüµÄ¹¦ÄÜ´ÓÊý¾ÝÀàÐÍÉÏ¿ÉÒÔ¿´³ö¡£ËùÒÔµ±I<16ʱirq_desc[i].handler = &i8259A_irq_type£»ÕâÀïµÄI¶ÔÓ¦×ÅÖжϺš£struct irqactionÊÇÒ»¸öÁ´±í£¬Ç°ÃæËµ¹ýÓ²¼þ¿ÉÒÔ¹²ÏíÖжϺţ¬Òò´ËÒ»¸öÖжϺÅÀ´Á˺󣬾ÍÔÚÒ»¸öÁ´±íÖÐÕÒ´¦Àí³ÌÐò£¬Õâ¸ö´¦Àí³ÌÐò¾ÍÊÇirqaction->handler£¬Õâ¸öÁ´±íÊÇirq_desc[i]-> irqaction¡£¿É¼ûinit_ISA_irqs¾ÍÊdzõʼ»¯irq_descÊý×éÓõģ¬irq_descÊý×é¼Ç¼Á˸÷¸öÖжϺŵķþÎñ³ÌÐòµÄÁÐ±í£¬ÔÚºóÃæµÄϵͳͳһÖжϴ¦Àí³ÌÐòÖл¹»á¿´µ½Ëü¡£

    ¡¡¡¡µÚ¶þ¸öº¯Êýset_intr_gateÇ°ÃæÒѾ­¼û¹ýÁË£¬ÕâÀïΪÁË·½±ãÔÙÕ³Ìùһϣº

    [code]void set_intr_gate(unsigned int n, void *addr)
    ¡¡¡¡{
    ¡¡¡¡ _set_gate(idt_table+n,14,0,addr);
    ¡¡¡¡}[/code]

    ¡¡¡¡ËüÊÇдIDT±í¸ñÖжÏÏòÁ¿µÄ£¬¹Ø¼üÊÇÈ«¾ÖÊý×éinterrupt¡£ÔÚͬÎļþÖÐÕÒµ½£º

    [code]void (*interrupt[NR_IRQS])(void) = {
    ¡¡¡¡ IRQLIST_16(0x0),
    ¡¡¡¡¡­¡­.
    ¡¡¡¡}[/code]

    ¡¡¡¡ÊÇÒ»¸öº¯ÊýÖ¸ÕëÊý×飬IRQLIST_16(0x0)ÊÇÒ»¸öºê¶¨Òå:

    [code]#define IRQ(x,y) IRQ##x##y##_interrupt
    ¡¡¡¡
    ¡¡¡¡#define IRQLIST_16(x) IRQ(x,0), IRQ(x,1), IRQ(x,2),
    IRQ(x,3), IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7),
    IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), IRQ(x,c),
    IRQ(x,d), IRQ(x,e), IRQ(x,f)[/code]

  4. ͯѫ ÓÚ 2006-09-25 10:42:36·¢±í:

    ¡¡¡¡Êµ¼ÊÉÏËüÃǶ¼ÊÇÓÉÒ»¸öÄÚ²¿º¯ÊýÍê³ÉµÄ£¬_set_gate()£¬¾ÍÊDzÎÊý²»Í¬£¬ÕâÀï¾Í¹Ø×¢µÚÈý¸ö²ÎÊý£¬Õâ¸ö²ÎÊý¾ÍÊÇÃŵÄȨÏÞ¡£Èç¹ûÕâ¸ö²ÎÊýµÈÓÚ3£¬¾ÍÊÇ˵Óû§Ì¬½ø³ÌÒ²Äܵ÷Óá£ÕâÑù¾ÍµÃ³ösystem_gateºÍcall_gateÓû§Ì¬½ø³ÌÄܵ÷Óã¬intr_gateºÍtrap_gateÖ»ÓÐ ºËÐÄ̬½ø³ÌÄܵ÷ÓÃÁË¡£ÕâÀïÒª²¹³äÒ»µã¾ÍÊÇintr_gateºÍtrap_gateϵͳ´¦ÀíÊÇ»ù±¾Ò»Öµģ¬Î¨Ò»µÄ²»Í¬µã¾ÍÊÇintr_gate´¦Àí¹ØÁËÖжϣ¬¶øtrap_gateÔÚ´¦Àíʱ²»¹ØÖжϡ£

    ¡¡¡¡¶ÔÒì³£µÄ´¦Àí¾ßÌå¿ÉÒÔ¿´´¦Àíº¯ÊýµÄ¶¨Ò壬ÕâÀï¾Í²»Ïêϸ½âÊÍÁË¡£Linux¶ÔÓ²¼þµÄÖжϽøÐÐÁËͳһµÄ´¦Àí¡£ÕâÀï¾ÍÒª¿´¿´¾ßÌåµÄ´úÂëÁË¡£ÔÚÔ´Îļþarch\i386\kernel\i8259.cÖУ¬ÏÈ¿´Ò»Ïº¯Êýinit_IRQ£¬Õâ¸öº¯ÊýÊÇÓ²¼þÖжϵijõʼ»¯º¯Êý£¬Ò²±»start_kernelµ÷Óá£È¥µôÁËSMPºêµÈÌõ¼þ±àÒëµÄ´úÂ룬¼ò»¯Ò»Ï¾͵õ½ÈçÏ´úÂ룺

    [code]void __init init_IRQ(void)
    ¡¡¡¡{
    ¡¡¡¡ ¡­¡­¡­.
    ¡¡¡¡ init_ISA_irqs();
    ¡¡¡¡ ¡­¡­¡­.
    ¡¡¡¡ for (i = 0; i < NR_IRQS; i++) {
    ¡¡¡¡ int vector = FIRST_EXTERNAL_VECTOR + i;
    ¡¡¡¡ if (vector != SYSCALL_VECTOR)
    ¡¡¡¡ set_intr_gate(vector, interrupt[i]);
    ¡¡¡¡ }
    ¡¡¡¡ ¡­¡­..
    ¡¡¡¡}[/code]

    ¡¡¡¡ºËÐÄÊÇÁ½¸öº¯Êýinit_ISA_irqs£¬set_intr_gateºÍÒ»¸öÈ«¾ÖÊý×é±äÁ¿interrupt¡£ºêFIRST_EXTERNAL_VECTOR=20£¬Ò²¾ÍÊÇÓ²¼þÖжÏÏòÁ¿>=20£¬ÕâÀï˵Ã÷Ò»ÏÂÖжϺźÍÖжÏÏòÁ¿µÄÇø±ð£¬ÖжϺÅʵ¼ÊÉÏÊÇÓ²¼þÁ¬½Ói8259aÊǵÄÏߺţ¬ÊÇÎïÀíµÄ£»ÖжÏÏòÁ¿ÊÇÂß¼­µÄ£¬´ú±íÖжϷþÎñÔÚIDTÖеÄϱꡣºêSYSCALL_VECTORÊÇ0x80£¬ÎªÏµÍ³µ÷Óñ£Áô¡£

    ¡¡¡¡ÏÈ¿´init_ISA_irqsµÄ¶¨Òå

    [code]void __init init_ISA_irqs (void)
    ¡¡¡¡{
    ¡¡¡¡ int i;
    ¡¡¡¡
    ¡¡¡¡ init_8259A(0);
    ¡¡¡¡
    ¡¡¡¡ for (i = 0; i < NR_IRQS; i++) {
    ¡¡¡¡ irq_desc[i].status = IRQ_DISABLED;
    ¡¡¡¡ irq_desc[i].action = 0;
    ¡¡¡¡ irq_desc[i].depth = 1;
    ¡¡¡¡
    ¡¡¡¡ if (i < 16) {
    ¡¡¡¡ /*
    ¡¡¡¡ * 16 old-style INTA-cycle interrupts:
    ¡¡¡¡ */
    ¡¡¡¡ irq_desc[i].handler = &i8259A_irq_type;
    ¡¡¡¡ } else {
    ¡¡¡¡ /*
    ¡¡¡¡ * 'high' PCI IRQs filled in on demand
    ¡¡¡¡ */
    ¡¡¡¡ irq_desc[i].handler = &no_irq_type;
    ¡¡¡¡ }
    ¡¡¡¡ }
    ¡¡¡¡}[/code]

    ¡¡¡¡¡¡¡¡Ê×ÏÈÒª½âÊ͵ÄÊÇÈ«¾Öirq_descÊý×飺

    [code]/*
    ¡¡¡¡ * This is the "IRQ descriptor", which contains various information
    ¡¡¡¡ * about the irq, including what kind of hardware handling it has,
    ¡¡¡¡ * whether it is disabled etc etc.
    ¡¡¡¡ *
    ¡¡¡¡ * Pad this out to 32 bytes for cache and indexing reasons.
    ¡¡¡¡ */
    ¡¡¡¡typedef struct {
    ¡¡¡¡ unsigned int status; /* IRQ status */
    ¡¡¡¡ hw_irq_controller *handler;
    ¡¡¡¡ struct irqaction *action; /* IRQ action list */
    ¡¡¡¡ unsigned int depth; /* nested irq disables */
    ¡¡¡¡ spinlock_t lock;
    ¡¡¡¡} ____cacheline_aligned irq_desc_t;
    ¡¡¡¡
    ¡¡¡¡extern irq_desc_t irq_desc [NR_IRQS];[/code]
    ¡¡¡¡
    ¡¡¡¡´ÓÒÔÉϵÄÉùÃ÷Öп´³ö£¬irq_descÊÇ"IRQ descriptor"¡£
    ²»Ã÷°×µÄÊǽṹÖеÄÀàÐÍstruct irqactionºÍhw_irq_controller£¬
    ÔÙÕÒ³öËüÃǵÄÉùÃ÷£º
    [code]¡¡¡¡struct hw_interrupt_type {
    ¡¡¡¡ const char * typename;
    ¡¡¡¡ unsigned int (*startup)(unsigned int irq);
    ¡¡¡¡ void (*shutdown)(unsigned int irq);
    ¡¡¡¡ void (*enable)(unsigned int irq);
    ¡¡¡¡ void (*disable)(unsigned int irq);
    ¡¡¡¡ void (*ack)(unsigned int irq);
    ¡¡¡¡ void (*end)(unsigned int irq);
    ¡¡¡¡ void (*set_affinity)(unsigned int irq, unsigned long mask);
    ¡¡¡¡};
    ¡¡¡¡
    ¡¡¡¡typedef struct hw_interrupt_type hw_irq_controller;
    ¡¡¡¡
    ¡¡¡¡struct irqaction {
    ¡¡¡¡ void (*handler)(int, void *, struct pt_regs *);
    ¡¡¡¡ unsigned long flags;
    ¡¡¡¡ unsigned long mask;
    ¡¡¡¡ const char *name;
    ¡¡¡¡ void *dev_id;
    ¡¡¡¡ struct irqaction *next;
    ¡¡¡¡};[/code]

  5. ͯѫ ÓÚ 2006-09-25 10:41:33·¢±í:

    ¡¡¡¡3£®ÏÝÚ壨trap£©

    ¡¡¡¡ÏÝÚåÓÖ³ÆÎªÖ÷¶¯Òì³££¬¾ÍÊÇÔÚÄãµÄ³ÌÐòÖÐÖ±½Ó³öÏÖint nÖ¸Áʵ¼ÊÉÏÔÚÄãµÄ³ÌÐòÖÐÄܳöÏÖµÄÕâÑùµÄÖ¸ÁîÒ²²»¶à£¬³ý·ÇÄãµÄ³ÌÐòÊÇÒÑÄ£¿éµÄ·½Ê½ÁªÈëÄÚºËÖÐÁË¡£

    ¡¡¡¡4£®ÏµÍ³µ÷ÓÃint80

    ¡¡¡¡Ö®ËùÒÔÌØµØÌá³ö¾ÍÊÇΪÁ˰Ñϵͳµ÷ÓÃ˵Ã÷°×£¬ÏµÍ³µ÷ÓÃÊDzÙ×÷ϵͳʵÏֵ쬏øÓû§ÌṩµÄ¹¦Äܽӿڡ£ºÜ¶àÈË»á¶ÔÖ®ÓÐÒ»ÖÖÉñÃØ¸Ð£¬ËüµÄ´úÂëÔÚϵͳ³õʼ»¯Ê±ÔØÈëÄÚ´æµÄµÍ¶Ë£¬±»Ó³ÉäÈëÄں˿ռ䣨3G£©ÒÔÉÏ£¬¶ÔËùÓеĵ÷Óýø³ÌÀ´Ëµ£¬ËüÃǵĵØÖ·ÊÇÒ»ÑùµÄ¡£

    ¡¡¡¡ÒÔÉϵķÖÀàºÜ¶àÈ˲¢²»Ò»¶¨ÔÞͬ£¬µ«ÓÐʤÓÚÎÞ¡£

    ¡¡¡¡LinuxµÄÖжϵĴ¦Àí

    ¡¡¡¡ÔÚ80386ÒÔǰµÄcpuÖУ¬ÖжÏÊÇͨ¹ýÖжÏÏòÁ¿±íIDT´¦Àí¡£Õâ¸ö´¦Àí´ó¼Ò¿ÉÒÔ¿´¿´ÓйصÄÊé¡£¾ÍÊDzÙ×÷ϵͳ°ÑÖжϴ¦ÀíµÄÈ˿ڵØÖ··ÅÔÚÄÚ´æ0¿ªÊ¼µÄµØ·½£¬Ã¿Ò»¸öÖжÏÏòÁ¿Õ¼4¸ö×Ö½Ú£¬2¸öΪÁ˶λùµØÖ·£¬ÁíÍâ2¸öΪÁËÆ«ÒÆ¡£Ò»¹²ÊÇ256¸öÏòÁ¿£¬¸ÕºÃÊÇ1k¡£ÔÚ80386ÖУ¬CPUÔÊÐíÔÚÈÎÒâµØÖ·´æ·ÅIDT£¬ÕâÑùºÍ´¦Àí¶ÎÒ»Ñù£¬CPU¶àÁËÒ»¸ö¼Ä´æÆ÷IDTR£¬´æ·ÅIDTÔÚÄÚ´æµÄÆðÖ·¡£80386ÖÐΪÁËÔÚ±£»¤Ä£Ê½Öд¦ÀíÖжϣ¬ÒýÈëÁËÒ»¸öеÄÊõÓï¡°ÃÅ¡±£¬¶ÔÓÚÕâ¸öÊõÓï´ó¼Ò¿ÉÒԲο¼intelµÄ×ÊÁÏ£¬ÔÚÕâÀï¾ÍÀí½âΪ½ø³ÌȨÏ޸ıäʱ±ØÐëͨ¹ýµÄÒ»µÀ¼ì²éÃÅ¡£IntelΪ80386ÉèÖÃÁË4ÖÖÃÅ£ºÈÎÎñÃÅ¡¢ÖжÏÃÅ¡¢ÏÝÚåÃÅ¡¢µ÷ÓÃÃÅ¡£ºóÈýÕß»ù±¾Éϲ¶à¡£ÈÎÎñÃÅ¿´²»³öÓÐʲôÓô¦£¬ÔÚlinuxµÄ×¢ÊÍÖÐ˵Ã÷ΪÁËÔÚlinuxÉÏÔËÐÐiBCSºÍSolaris/X86ÉèÖÃÁËÁ½¸öÈÎÎñÃÅ¡£80386µÄÖжÏÏòÁ¿ÃèÊöÒ²ºÍ8086ÍêÈ«²»Ò»ÑùÁË£¬ÖжÏÏòÁ¿ÓÐ64볤£¬¸ø³öµÄÊÇÖжϴ¦Àí³ÌÐòµÄ¶ÎÑ¡Ôñ·û£¨16룩¡¢³ÌÐòµÄÆ«ÒÆµØÖ·£¨32룩¡¢ÀàÐÍÂë¡£Òò´ËÔÚÕâÀï¿ÉÒÔÃèÊöÒ»ÏÂ80386´¦ÀíÖжϵij¡¾°ÁË£º

    ¡¡¡¡£¨1£©CPU¸ù¾ÝÖжÏʸÁ¿ÔÚIDTÖÐÕÒµ½¶ÔÓ¦µÄÖжÏÏ

    ¡¡¡¡£¨2£©¸ù¾ÝÖжÏÏòÁ¿ÖеĶÎÑ¡Ôñ·û£¬ÔÚGDTÖÐÕÒµ½¶ÎµÄÆðÖ·£¬½áºÏÆ«ÒÆÁ¿£¬¾ÍµÃµ½ÖжϷþÎñµÄÏßÐÔµØÖ·£¬Õâ¸öµØÖ·¿Ï¶¨ÔÚ3GÒÔÉϵģ¬Ò²¾ÍÊÇ˵ÊÇÓ³Éäµ½ºËÐÄÇøÓòÖеġ£

    ¡¡¡¡80386ÖжÔÖжÏÉèÖÃÁËÃÅ£¨ÖжÏÏòÁ¿£©£¬Ëü¶Ô½ø³ÌµÄȨÏÞÓÐÑϸñµÄÒªÇ󣬾ßÌåÊÇ£º

    ¡¡¡¡1£®½øÈëÃÅ֮ǰ£¬½ø³ÌµÄȨÏÞÒª¸ßÓÚÃŵÄȨÏÞ£¨Õâ¸öȨÏÞÔÚÖжÏÏòÁ¿µÄÀàÐÍÃèÊöÖУ©¡£

    ¡¡¡¡2£®½øÈëÃź󣬽ø³ÌµÄȨÏÞÒª¸ßÓÚÖжϷþÎñ³ÌÐòËùÔڵĶεÄÔËÐÐȨÏÞ£¨GDT£©¡£

    ¡¡¡¡3£®Ó²¼þÖжϿÉÒÔÈÆ¹ýÉÏÊö¹ý³Ì¡£

    ¡¡¡¡4£®ÆäËüÀàÐ͵ÄÖжϣ¬Òì³££¬Èç¹û²»Âú×ã1¾Í»áÒý·¢Ò»¸ö±£»¤Òì³£¡£

    ¡¡¡¡ÕâÖÖȨÏÞÉèÖÃÔÚ³õʼ»¯µÄʱºò¾ÍÍê³ÉÁË£¬ÎÒÃÇ¿´º¯Êýtrap_init()ÖУ¬¹²ÓÐËÄÖÖÉèÖú¯Êý£¬·Ö±ðÊÇ£º

    [code]¡¡¡¡set_trap_gate
    ¡¡¡¡ set_system_gate
    ¡¡¡¡ set_intr_gate
    ¡¡¡¡ set_call_gate[/code]

    ¡¡¡¡ÔÚÔ´´úÂëtraps.cÖÐÕÒµ½ËüÃǵ͍Ò壺

    [code]void set_intr_gate(unsigned int n, void *addr)
    ¡¡¡¡{
    ¡¡¡¡ _set_gate(idt_table+n,14,0,addr);
    ¡¡¡¡}
    ¡¡¡¡
    ¡¡¡¡static void __init set_trap_gate(unsigned int n, void *addr)
    ¡¡¡¡{
    ¡¡¡¡ _set_gate(idt_table+n,15,0,addr);
    ¡¡¡¡}
    ¡¡¡¡
    ¡¡¡¡static void __init set_system_gate(unsigned int n, void *addr)
    ¡¡¡¡{
    ¡¡¡¡ _set_gate(idt_table+n,15,3,addr);
    ¡¡¡¡}
    ¡¡¡¡
    ¡¡¡¡static void __init set_call_gate(void *a, void *addr)
    ¡¡¡¡{
    ¡¡¡¡ _set_gate(a,12,3,addr);
    ¡¡¡¡}[/code]