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

ÔÚLinuxÖÐÓÃÄں˱à³ÌÀ´Öжϴ¦Àí³ÌÐò

·¢²¼Ê±¼ä:2006-11-20 09:29:23À´Ô´:ºìÁª×÷Õß:hlMiracle
¡¡¡¡Öжϴ¦Àí³ÌÐò

¡¡¡¡³ý×îºóÒ»ÕÂÍ⣬ĿǰÎÒÃÇÔÚÄÚºËÖÐËù×öµÄÊÂÇé¾ÍÊÇÏìÓ¦Ò»¸ö½ø³ÌµÄÇëÇ󣬿ÉÄÜͨ¹ý´¦ÀíÒ»¸öÌØÊâÎļþ¡¢·¢ËÍÒ»¸öioctl»ò½øÐÐÒ»¸öϵͳµ÷Óᣵ«ÊÇÄں˵Ť×÷²»Ö»ÊÇÏìÓ¦½ø³ÌÇëÇó£¬ÁíÒ»¸öÒ²ÊǺÜÖØÒªµÄ¹¤×÷ÊÇÏòÁ¬½Óµ½»úÆ÷µÄÓ²¼þ·¢²¼ÃüÁî»òÏûÏ¢¡£

¡¡¡¡CPUºÍÆäËûÓ²¼þµÄ½»»¥ÓÐÁ½ÖÖ¡£µÚÒ»ÖÖÊÇCPU¸øÓ²¼þ·¢ÃüÁî¡£ÁíÒ»ÖÖÊÇÓ²¼þÐèÒª¸æËßCPUһЩ¶«Î÷¡£µÚ¶þÖÖ½»»¥½Ð×öÖжϣ¬ËüºÜÄÑʵÏÖ£¬ÒòΪËüÐèÒª´¦ÀíÓ²¼þ£¬¶ø²»ÊÇCPU¡£Ó²¼þÉ豸ͨ³£ÓÉÒ»¸ö·Ç³£Ð¡µÄram£¬¶øÈç¹ûÄã²»ÔÚÕâ¸öramÖеÄÐÅÏ¢¿ÉÓÃʱ°ÑËüÃǶÁ³ö£¬ËüÃǾͻᶪʧ¡£

¡¡¡¡ÔÚLinuxÏ£¬Ó²¼þÖжϽÐ×öIRQ£¨Interrupt RequestsµÄËõд£©¡£ÓÐÁ½ÖÖIRQ£¬¶ÌÀàÐͺͳ¤ÀàÐÍ¡£¶ÌIRQÐèÒªºÜ¶ÌµÄʱ¼ä£¬ÔÚ´ËÆÚ¼ä»úÆ÷µÄÆäËû²¿·Ö±»Ëø¶¨£¬¶øÇÒûÓÐÆäËûÖжϱ»´¦Àí¡£Ò»¸ö³¤IRQÐèÒª½Ï³¤µÄʱ¼ä£¬ÔÚ´ËÆÚ¼ä¿ÉÄÜ·¢ÉúÆäËûÖжϣ¨µ«²»ÊÇ·¢×Ôͬһ¸öÉ豸£©¡£Èç¹û¿ÉÄܵĻ°£¬×îºÃ°ÑÒ»¸öÖжÎÉùÃ÷Ϊ³¤ÀàÐÍ¡£

¡¡¡¡Èç¹ûCPU½Óµ½Ò»¸öÖжϣ¬Ëü¾Í»áÍ£Ö¹Ò»Çй¤×÷£¨³ý·ÇËüÕýÔÚ´¦ÀíÒ»¸ö¸üÖØÒªµÄÖжϣ¬ÔÚÕâÖÖÇé¿öÏÂÒªµÈµ½¸üÖØÒªµÄÖжϴ¦Àí½áÊøºó²Å»á´¦ÀíÕâ¸öÖжϣ©£¬°ÑÏà¹ØµÄ²ÎÊý´æ´¢µ½Õ»ÀȻºóµ÷ÓÃÖжϴ¦Àí³ÌÐò¡£ÕâÒâζ×ÅÔÚÖжϴ¦Àí³ÌÐò±¾ÉíÖÐÓÐЩÊÂÇéÊDz»ÔÊÐíµÄ£¬ÒòΪÕâʱϵͳ´¦ÔÚÒ»¸öδ֪״̬¡£½â¾öÕâ¸öÎÊÌâµÄ·½·¨ÊÇÈÃÖжϴ¦Àí³ÌÐò×öÐèÒªÂíÉÏ×öµÄÊ£¬Í¨³£ÊÇ´ÓÓ²¼þ¶ÁÈ¡ÐÅÏ¢»ò¸øÓ²¼þ·¢ËÍÐÅÏ¢£¬È»ºó°Ñ¶ÔÐÂÐÅÏ¢µÄ´¦Àíµ÷¶Èµ½ÒÔºóÈ¥×ö£¨Õâ½Ð×ö°ëµ×£©£¬·µ»Ø¡£ÄÚºËÈ·±£¾¡¿ìµ÷Óðëµ×£¬¶øµ±µ÷ÓÃʱ£¬ÈκÎÔÊÐíÔÚÄÚºËÄ£¿éÖÐ×öµÄÊÂÇé¾Í¶¼¿ÉÒÔ×öÁË¡£

¡¡¡¡ÊµÏֵķ½·¨ÊÇÔÚ½Óµ½Ïà¹ØµÄIRQ£¨ÔÚIntelƽ̨ÉÏÓÐ16¸öIRQ£©Ê±µ÷ÓÃÖжϴ¦Àí³ÌÐò¡£Õâ¸öº¯Êý½Óµ½IRQºÅÂë¡¢º¯ÊýÃû¡¢±êÖ¾¡¢Ò»¸ö/proc/interruptsµÄÃû×ֺʹ«¸øÖжϴ¦Àí³ÌÐòµÄÒ»¸ö²ÎÊý¡£±êÖ¾ÖпÉÒÔ°üÀ¨SA_SHIRQÀ´±íÃ÷ÄãÏ£ÍûºÍÆäËû´¦Àí³ÌÐò¹²Ïí´ËIRQ£¨Í¨³£ºÜ¶àÉ豸¹«ÓÃÒ»¸öIRQ£©£¬»òÕßÒ»¸öSA_INTERRUPT±íÃ÷ÕâÊÇÒ»¸ö½ô¼±Öжϡ£Õâ¸öº¯Êý½öÔÚ´ËIRQûÓÐÆäËû´¦Àí³ÌÐò»òÐèÒª¹²ÏíËùÓд¦Àí³ÌÐòʱ²Å»á³É¹¦ÔËÐС£

¡¡¡¡ÄÇô£¬ÓÐÁËÖжϴ¦Àí³ÌÐò£¬ÎÒÃǾͿÉÒÔºÍÓ²¼þͨÐÅ£¬²¢ÇÒ¿ÉÒÔʹÓÃqueue_task_irqºÍtq_immediateºÍmark_bh(BH_IMMEDIATE)À´µ÷¶È°ëµ×¡£ÔÚ2.0°æ±¾Öв»ÄÜʹÓñê×¼queue_taskµÄÔ­ÒòÊÇÖжϿÉÄÜ·¢ÉúÔÚij¸öqueue_taskµÄÖм䡣ÎÒÃÇÐèÒªmark_bhÊÇÒòΪÔçÆÚµÄLinux°æ±¾Ö»ÓÐÒ»¸ö³¤¶ÈΪ32µÄ°ëµ×¶ÓÁС£ÏÖÔÚËüÃÇÖеÄÒ»¸ö£¨BH_IMMEDIATE£©ÓÃÓÚÄÇЩûÓеõ½·ÖÅä¸øËüÃǵİëµ×Èë¿ÚµÄÇý¶¯³ÌÐòµÄ°ëµ×Á´±í¡£
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 1 ÌõÆÀÂÛ

  1. hlMiracle ÓÚ 2006-11-20 09:29:59·¢±í:

    ¡¡¡¡Intel ½á¹¹ÉϵļüÅÌ

    ¡¡¡¡×¢Ò⣺±¾ÕÂÏÂÃæµÄÄÚÈݶ¼ÊÇÍêÈ«Õë¶ÔIntel½á¹¹¡£Èç¹ûÄã²»ÊÇÔÚIntelƽ̨ÉϵĻ°£¬³ÌÐò¾Í²»Äܹ¤×÷£¬Ò²²»Ã»ÓбØÒªÊÔͼ±àÒë¡£

    ¡¡¡¡ÔÚд±¾ÕÂÀý×ÓÖеijÌÐòµÄʱºòÎÒÓöµ½Ò»¸öÎÊÌâ¡£Ò»·½Ã棬×÷Ϊһ¸öÓÐÓõÄÀý×ÓËüÐèÒªÔÚÿ¸öÈ˵ĻúÆ÷ÉÏÔËÐУ¬µÃµ½ÕýÈ·µÄ½á¹û¡£ÁíÒ»·½Ã棬ÄÚºËÒѾ­°üº¬ÁËËùÓÐÆÕͨÉ豸µÄÇý¶¯³ÌÐò£¬ÕâЩÇý¶¯³ÌÐòºÍÎÒҪдµÄ´úÂë²»Ò»¶¨Äܹ»¹²´æ¡£ÎÒÕÒµ½µÄ·½·¨ÊǸø¼üÅÌÖжÏдµã¶«Î÷£¬²¢ÇÒÊ×ÏÈʹÕý³£µÄ¼üÅÌÖжÏÎÞЧ¡£ÒòΪÔÚÄÚºËÔ´Îļþ£¨drivers/char/keyboard.c£©ÀïËüÊÇ×÷Ϊһ¸ö¾²Ì¬·ûºÅ±»¶¨ÒåµÄ£¬Ã»Óа취»Ö¸´Ëü¡£ÔÚinsmodÕâ¶Î´úÂëÇ°£¬ÔÚÁíÒ»¸öÖÕ¶Ësleep 120ÉÏ×öÒ»´Î£¬Èç¹ûÒªÆÀ¹ÀÎļþ ϵͳµÄ»°£¬ÐèÒªreboot¡£

    ¡¡¡¡Õâ¶Î´úÂë°ÑËü×Ô¼º°ó¶¨µ½IRQ1ÉÏ£¬ÔÚInterl½á¹¹ÏÂÕâÊǼüÅÌ¿ØÖƵÄIRQ¡£È»ºó£¬µ±Ëü½Óµ½Ò»¸ö¼üÅÌÖжÏʱ£¬¶Á³ö¼üÅ̵Ä״̬£¨ÕâÊÇinb(0x64)µÄÄ¿µÄ£©ºÍÓɼüÅÌ·µ»ØµÄɨÃèÂ롣Ȼºó£¬Ö»ÒªÄÚºËÈÏΪ¿ÉÒÔʱ£¬Ëü¾ÍÔËÐÐgot_char¸ø³ö¼üµÄ±àÂ루ɨÃèÂëµÄÇ°7룩ºÍÊÇ·ñ±»°´ÏµÄÐÅÏ¢£¨Èç¹ûµÚ8λÊÇ0Ôò±íʾ°´Ï£¬ÊÇ1±íʾÊÍ·Å£©¡£

    ÒýÓÃ:
    ex intrpt.c

    /* intrpt.c - An interrupt handler. */


    /* Copyright (C) 1998 by Ori Pomerantz */



    /* The necessary header files */

    /* Standard in kernel modules */
    #include /* Were doing kernel work */
    #include /* Specifically, a module */

    /* Deal with CONFIG_MODVERSIONS */
    #if CONFIG_MODVERSIONS==1
    #define MODVERSIONS
    #include
    #endif

    #include
    #include

    /* We want an interrupt */
    #include

    #include


    /* In 2.2.3 /usr/include/linux/version.h includes a
    * macro for this, but 2.0.35 doesnt - so I add it
    * here if necessary. */
    #ifndef KERNEL_VERSION
    #define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))
    #endif



    /* Bottom Half - this will get called by the kernel
    * as soon as its safe to do everything normally
    * allowed by kernel modules. */
    static void got_char(void *scancode)
    {
    printk(""Scan Code %x %s. "",
    (int) *((char *) scancode) & 0x7F,
    *((char *) scancode) & 0x80 ? ""Released"" : ""Pressed"");
    }


    /* This function services keyboard interrupts. It reads
    * the relevant information from the keyboard and then
    * scheduales the bottom half to run when the kernel
    * considers it safe. */
    void irq_handler(int irq,
    void *dev_id,
    struct pt_regs *regs)
    {
    /* This variables are static because they need to be
    * accessible (through pointers) to the bottom
    * half routine. */
    static unsigned char scancode;
    static struct tq_struct task =
    {NULL, 0, got_char, &scancode};
    unsigned char status;

    /* Read keyboard status */
    status = inb(0x64);
    scancode = inb(0x60);

    /* Scheduale bottom half to run */
    #if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)
    queue_task(&task, &tq_immediate);
    #else
    queue_task_irq(&task, &tq_immediate);
    #endif
    mark_bh(IMMEDIATE_BH);
    }



    /* Initialize the module - register the IRQ handler */
    int init_module()
    {
    /* Since the keyboard handler wont co-exist with
    * another handler, such as us, we have to disable
    * it (free its IRQ) before we do anything. Since we
    * dont know where it is, theres no way to
    * reinstate it later - so the computer will have to
    * be rebooted when were done.
    */
    free_irq(1, NULL);

    /* Request IRQ 1, the keyboard IRQ, to go to our
    * irq_handler. */
    return request_irq(
    1, /* The number of the keyboard IRQ on PCs */
    irq_handler, /* our handler */
    SA_SHIRQ,
    /* SA_SHIRQ means were willing to have othe
    * handlers on this IRQ.
    *
    * SA_INTERRUPT can be used to make the
    * handler into a fast interrupt.
    */
    ""test_keyboard_irq_handler"", NULL);
    }


    /* Cleanup */
    void cleanup_module()
    {
    /* This is only here for completeness. Its totally
    * irrelevant, since we dont have a way to restore
    * the normal keyboard interrupt so the computer
    * is completely useless and has to be rebooted. */
    free_irq(1, NULL);
    }