¡¡¡¡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µÄ½ø³Ìµ÷Óã¬Ò²¾ÍÊÇ˵ÕâЩÒì³£Ö»Äܱ»ÄÚºËËù´¦Àí£¬µÀÀí·Ç³£Ã÷ÏÔ£¬µ«ÊÇʵÏÖÆðÀ´¾Í²»ÊÇÄÇôֱ½ÓÁË¡£
                  	
				

ͯѫ ÓÚ 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º¯ÊýÖд¦Àí¡£Ó²¼þÖжϾÍдÕâô¶àÁË£¬»¹ÓÐÈíÖжϺÍϵͳµ÷ÓÃûÓÐд£¬µÈ¿´ÍêºóÔÙ˵¡£
ͯѫ ÓÚ 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]
ͯѫ ÓÚ 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]
ͯѫ ÓÚ 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]
ͯѫ ÓÚ 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]