Linux °æ (¾«»ªÇø)

·¢ÐÅÈË: netiscpu (Ò¹¡îÐǹâµãµã¡î), ÐÅÇø: Linux
±ê  Ìâ: LINUXϵÄÉ豸Çý¶¯³ÌÐò
·¢ÐÅÕ¾: ×Ï ¶¡ Ïã (Sun Nov  8 17:23:12 1998), ×ªÐÅ


·¢ÐÅÈË: olly (½£µ¨ÇÙÐÄ), ÐÅÇø: Linux
±ê  Ìâ: LINUXϵÄÉ豸Çý¶¯³ÌÐò
·¢ÐÅÕ¾: BBS Ë®Ä¾Ç廪վ (Sat Jun 28 14:00:08 1997)



     ÒÔÏÂÊDZ¾È˱ÏÒµÂÛÎĵÄÒ»²¿·Ö£¬ÊǹØÓÚLinuxÏÂÉ豸Çý¶¯³ÌÐòµÄ±àдµÄ¡£
Çë¸÷λͬ־ÃÇÖ¸Õý¡£





Èý¡¢UNIXϵͳϵÄÉ豸Çý¶¯³ÌÐò
3.1¡¢UNIXÏÂÉ豸Çý¶¯³ÌÐòµÄ»ù±¾½á¹¹
ÔÚUNIXϵͳÀ¶ÔÓû§³ÌÐò¶øÑÔ£¬É豸Çý¶¯³ÌÐòÒþ²ØÁËÉ豸µÄ¾ßÌåϸ½Ú£¬
¶Ô¸÷ÖÖ²»Í¬É豸ÌṩÁËÒ»ÖµĽӿڣ¬Ò»°ãÀ´ËµÊÇ°ÑÉ豸ӳÉäΪһ¸öÌØÊâµÄÉ豸ÎÄ
¼þ£¬Óû§³ÌÐò¿ÉÒÔÏó¶ÔÆäËüÎļþÒ»Ñù¶Ô´ËÉ豸Îļþ½øÐвÙ×÷¡£UNIX¶ÔÓ²¼þÉ豸
Ö§³ÖÁ½¸ö±ê×¼½Ó¿Ú£º¿éÌرðÉ豸ÎļþºÍ×Ö·ûÌرðÉ豸Îļþ£¬Í¨¹ý¿é£¨×Ö·û£©Ìرð
É豸Îļþ´æÈ¡µÄÉ豸³ÆΪ¿é£¨×Ö·û£©É豸»ò¾ßÓп飨×Ö·û£©É豸½Ó¿Ú¡£
¿éÉ豸½Ó¿Ú½öÖ§³ÖÃæÏò¿éµÄI/O²Ù×÷£¬ËùÓÐI/O²Ù×÷¶¼Í¨¹ýÔÚÄں˵ØÖ·¿Õ¼ä
ÖеÄI/O»º³åÇø½øÐУ¬Ëü¿ÉÒÔÖ§³Ö¼¸ºõÈÎÒⳤ¶ÈºÍÈÎÒâλÖÃÉϵÄI/OÇëÇ󣬼´Ìá
¹©Ëæ»ú´æÈ¡µÄ¹¦ÄÜ¡£
×Ö·ûÉ豸½Ó¿ÚÖ§³ÖÃæÏò×Ö·ûµÄI/O²Ù×÷£¬Ëü²»¾­¹ýϵͳµÄ¿ìËÙ»º´æ£¬ËùÒÔËü
ÃǸºÔð¹ÜÀí×Ô¼ºµÄ»º³åÇø½á¹¹¡£×Ö·ûÉ豸½Ó¿ÚÖ»Ö§³Ö˳Ðò´æÈ¡µÄ¹¦ÄÜ£¬Ò»°ã²»ÄÜ
½øÐÐÈÎÒⳤ¶ÈµÄI/OÇëÇ󣬶øÊÇÏÞÖÆI/OÇëÇóµÄ³¤¶È±ØÐëÊÇÉ豸ҪÇóµÄ»ù±¾¿é³¤
µÄ±¶Êý¡£ÏÔÈ»£¬±¾³ÌÐòËùÇý¶¯µÄ´®Ðп¨Ö»ÄÜÌṩ˳Ðò´æÈ¡µÄ¹¦ÄÜ£¬ÊôÓÚÊÇ×Ö·ûÉè
±¸£¬Òò´ËºóÃæµÄÌÖÂÛÔÚÁ½ÖÖÉ豸ÓÐËùÇø±ðʱ¶¼Ö»Éæ¼°×Ö·ûÐÍÉ豸½Ó¿Ú¡£
É豸ÓÉÒ»¸öÖ÷É豸ºÅºÍÒ»¸ö´ÎÉ豸ºÅ±êʶ¡£Ö÷É豸ºÅΨһ±êʶÁËÉ豸ÀàÐÍ£¬
¼´É豸Çý¶¯³ÌÐòÀàÐÍ£¬ËüÊÇ¿éÉ豸±í»ò×Ö·ûÉ豸±íÖÐÉ豸±íÏîµÄË÷Òý¡£´ÎÉ豸ºÅ
½öÓÉÉ豸Çý¶¯³ÌÐò½âÊÍ£¬Ò»°ãÓÃÓÚʶ±ðÔÚÈô¸É¿ÉÄܵÄÓ²¼þÉ豸ÖУ¬I/OÇëÇóËùÉæ
¼°µ½µÄÄǸöÉ豸¡£
É豸Çý¶¯³ÌÐò¿ÉÒÔ·ÖΪÈý¸öÖ÷Òª×é³É²¿·Ö£º
(1) ×Ô¶¯ÅäÖúͳõʼ»¯×Ó³ÌÐò£¬¸ºÔð¼ì²âËùÒªÇý¶¯µÄÓ²¼þÉ豸ÊÇ·ñ´æÔÚºÍÊÇ·ñ
ÄÜÕý³£¹¤×÷¡£Èç¹û¸ÃÉ豸Õý³££¬Ôò¶ÔÕâ¸öÉ豸¼°ÆäÏà¹ØµÄ¡¢É豸Çý¶¯³ÌÐò
ÐèÒªµÄÈí¼þ״̬½øÐгõʼ»¯¡£Õⲿ·ÖÇý¶¯³ÌÐò½öÔÚ³õʼ»¯µÄʱºò±»µ÷ÓÃÒ»
´Î¡£
(2) ·þÎñÓÚI/OÇëÇóµÄ×Ó³ÌÐò£¬ÓÖ³ÆΪÇý¶¯³ÌÐòµÄÉϰ벿·Ö¡£µ÷ÓÃÕⲿ·ÖÊÇÓÉ
ÓÚϵͳµ÷ÓõĽá¹û¡£Õⲿ·Ö³ÌÐòÔÚÖ´ÐеÄʱºò£¬ÏµÍ³ÈÔÈÏΪÊǺͽøÐе÷ÓÃ
µÄ½ø³ÌÊôÓÚͬһ¸ö½ø³Ì£¬Ö»ÊÇÓÉÓû§Ì¬±ä³ÉÁ˺ËÐÄ̬£¬¾ßÓнøÐдËϵͳµ÷
ÓõÄÓû§³ÌÐòµÄÔËÐл·¾³£¬Òò´Ë¿ÉÒÔÔÚÆäÖе÷ÓÃsleep()µÈÓë½ø³ÌÔËÐл·
¾³Óйصĺ¯Êý¡£
(3) ÖжϷþÎñ×Ó³ÌÐò£¬ÓÖ³ÆΪÇý¶¯³ÌÐòµÄÏ°벿·Ö¡£ÔÚUNIXϵͳÖУ¬²¢²»ÊÇ
Ö±½Ó´ÓÖжÏÏòÁ¿±íÖе÷ÓÃÉ豸Çý¶¯³ÌÐòµÄÖжϷþÎñ×Ó³ÌÐò£¬¶øÊÇÓÉUNIX
ϵͳÀ´½ÓÊÕÓ²¼þÖжϣ¬ÔÙÓÉϵͳµ÷ÓÃÖжϷþÎñ×Ó³ÌÐò¡£ÖжϿÉÒÔ²úÉúÔÚÈÎ
ºÎÒ»¸ö½ø³ÌÔËÐеÄʱºò£¬Òò´ËÔÚÖжϷþÎñ³ÌÐò±»µ÷ÓõÄʱºò£¬²»ÄÜÒÀÀµÓÚ
Èκνø³ÌµÄ״̬£¬Ò²¾Í²»Äܵ÷ÓÃÈκÎÓë½ø³ÌÔËÐл·¾³Óйصĺ¯Êý¡£ÒòΪÉè
±¸Çý¶¯³ÌÐòÒ»°ãÖ§³ÖͬһÀàÐ͵ÄÈô¸ÉÉ豸£¬ËùÒÔÒ»°ãÔÚϵͳµ÷ÓÃÖжϷþÎñ
×Ó³ÌÐòµÄʱºò£¬¶¼´øÓÐÒ»¸ö»ò¶à¸ö²ÎÊý£¬ÒÔΨһ±êʶÇëÇó·þÎñµÄÉ豸¡£
ÔÚϵͳÄÚ²¿£¬I/OÉ豸µÄ´æȡͨ¹ýÒ»×é¹Ì¶¨µÄÈë¿ÚµãÀ´½øÐУ¬Õâ×éÈë¿ÚµãÊÇ
ÓÉÿ¸öÉ豸µÄÉ豸Çý¶¯³ÌÐòÌṩµÄ¡£Ò»°ãÀ´Ëµ£¬×Ö·ûÐÍÉ豸Çý¶¯³ÌÐòÄܹ»ÌṩÈç
ϼ¸¸öÈë¿Úµã£º
(1) openÈë¿Úµã¡£´ò¿ªÉ豸׼±¸I/O²Ù×÷¡£¶Ô×Ö·ûÌرðÉ豸Îļþ½øÐдò¿ª²Ù
×÷£¬¶¼»áµ÷ÓÃÉ豸µÄopenÈë¿Úµã¡£open×Ó³ÌÐò±ØÐë¶Ô½«Òª½øÐеÄI/O
²Ù×÷×öºÃ±ØÒªµÄ×¼±¸¹¤×÷£¬ÈçÇå³ý»º³åÇøµÈ¡£Èç¹ûÉ豸ÊǶÀÕ¼µÄ£¬¼´Í¬Ò»
ʱ¿ÌÖ»ÄÜÓÐÒ»¸ö³ÌÐò·ÃÎÊ´ËÉ豸£¬Ôòopen×Ó³ÌÐò±ØÐëÉèÖÃһЩ±êÖ¾ÒÔ±í
ʾÉ豸´¦ÓÚæ״̬¡£
(2) closeÈë¿Úµã¡£¹Ø±ÕÒ»¸öÉ豸¡£µ±×îºóÒ»´ÎʹÓÃÉ豸ÖÕ½áºó£¬µ÷ÓÃclose
×Ó³ÌÐò¡£¶ÀÕ¼É豸±ØÐë±ê¼ÇÉ豸¿ÉÔÙ´ÎʹÓá£
(3) readÈë¿Úµã¡£´ÓÉ豸É϶ÁÊý¾Ý¡£¶ÔÓÚÓлº³åÇøµÄI/O²Ù×÷£¬Ò»°ãÊÇ´Ó»º
³åÇøÀï¶ÁÊý¾Ý¡£¶Ô×Ö·ûÌرðÉ豸Îļþ½øÐжÁ²Ù×÷½«µ÷ÓÃread×Ó³ÌÐò¡£
(4) writeÈë¿Úµã¡£ÍùÉ豸ÉÏдÊý¾Ý¡£¶ÔÓÚÓлº³åÇøµÄI/O²Ù×÷£¬Ò»°ãÊÇ°ÑÊý
¾ÝдÈ뻺³åÇøÀï¡£¶Ô×Ö·ûÌرðÉ豸Îļþ½øÐÐд²Ù×÷½«µ÷ÓÃwrite×Ó³ÌÐò¡£
(5) ioctlÈë¿Úµã¡£Ö´ÐжÁ¡¢Ð´Ö®ÍâµÄ²Ù×÷¡£
(6) selectÈë¿Úµã¡£¼ì²éÉ豸£¬¿´Êý¾ÝÊÇ·ñ¿É¶Á»òÉ豸ÊÇ·ñ¿ÉÓÃÓÚдÊý¾Ý¡£
selectϵͳµ÷ÓÃÔÚ¼ì²éÓëÉ豸ÌرðÎļþÏà¹ØµÄÎļþÃèÊö·ûʱʹÓÃselect
Èë¿Úµã¡£
Èç¹ûÉ豸Çý¶¯³ÌÐòûÓÐÌṩÉÏÊöÈë¿ÚµãÖеÄijһ¸ö£¬ÏµÍ³»áÓÃȱʡµÄ×Ó³ÌÐò
À´´úÌæ¡£¶ÔÓÚ²»Í¬µÄϵͳ£¬Ò²»¹ÓÐһЩÆäËüµÄÈë¿Úµã¡£

3.2¡¢LINUXϵͳϵÄÉ豸Çý¶¯³ÌÐò
¾ßÌåµ½LINUXϵͳÀÉ豸Çý¶¯³ÌÐòËùÌṩµÄÕâ×éÈë¿ÚµãÓÉÒ»¸ö½á¹¹À´Ïòϵ
ͳ½øÐÐ˵Ã÷£¬´Ë½á¹¹¶¨ÒåΪ£º
#include <linux/fs.h>
struct file_operations {
        int (*lseek)(struct inode *inode,struct file *filp,
                off_t off,int pos);
        int (*read)(struct inode *inode,struct file *filp,
                char *buf, int count);
        int (*write)(struct inode *inode,struct file *filp,
                char *buf,int count);
        int (*readdir)(struct inode *inode,struct file *filp,
                struct dirent *dirent,int count);
        int (*select)(struct inode *inode,struct file *filp,
                int sel_type,select_table *wait);
        int (*ioctl) (struct inode *inode,struct file *filp,
                unsigned int cmd,unsigned int arg);
        int (*mmap) (void);
        int (*open) (struct inode *inode, struct file *filp);
        void (*release) (struct inode *inode, struct file *filp);
        int (*fsync) (struct inode *inode, struct file *filp);
};
ÆäÖУ¬struct inodeÌṩÁ˹ØÓÚÌرðÉ豸Îļþ/dev/driver£¨¼ÙÉè´ËÉ豸Ãû
Ϊdriver£©µÄÐÅÏ¢£¬ËüµÄ¶¨ÒåΪ£º
#include <linux/fs.h>
struct inode {
        dev_t           i_dev;  
        unsigned long   i_ino;  /* Inode number */
        umode_t         i_mode; /* Mode of the file */
        nlink_t         i_nlink;
        uid_t           i_uid;
        gid_t           i_gid;
        dev_t           i_rdev;  /* Device major and minor numbers*/
        off_t           i_size;
        time_t          i_atime;
        time_t          i_mtime;
        time_t          i_ctime;
        unsigned long   i_blksize;
        unsigned long   i_blocks;
        struct inode_operations * i_op;
        struct super_block * i_sb;
        struct wait_queue * i_wait;
        struct file_lock * i_flock;
        struct vm_area_struct * i_mmap;
        struct inode * i_next, * i_prev;
        struct inode * i_hash_next, * i_hash_prev;
        struct inode * i_bound_to, * i_bound_by;
        unsigned short i_count;
        unsigned short i_flags;  /* Mount flags (see fs.h) */
        unsigned char i_lock;
        unsigned char i_dirt;
        unsigned char i_pipe;
        unsigned char i_mount;
        unsigned char i_seek;
        unsigned char i_update;
        union {
                struct pipe_inode_info pipe_i;
                struct minix_inode_info minix_i;
                struct ext_inode_info ext_i;
                struct msdos_inode_info msdos_i;
                struct iso_inode_info isofs_i;
                struct nfs_inode_info nfs_i;
        } u;
};

struct fileÖ÷ÒªÓÃÓÚÓëÎļþϵͳ¶ÔÓ¦µÄÉ豸Çý¶¯³ÌÐòʹÓᣵ±È»£¬ÆäËüÉè
±¸Çý¶¯³ÌÐòÒ²¿ÉÒÔʹÓÃËü¡£ËüÌṩ¹ØÓÚ±»´ò¿ªµÄÎļþµÄÐÅÏ¢£¬¶¨ÒåΪ£º
#include <linux/fs.h>
struct file {
        mode_t f_mode;
        dev_t f_rdev;             /* needed for /dev/tty */
        off_t f_pos;              /* Curr. posn in file */
        unsigned short f_flags;   /* The flags arg passed to open */
        unsigned short f_count;   /* Number of opens on this file */
        unsigned short f_reada;
        struct inode *f_inode;    /* pointer to the inode struct */
        struct file_operations *f_op;/* pointer to the fops struct*/
};

Ôڽṹfile_operationsÀָ³öÁËÉ豸Çý¶¯³ÌÐòËùÌṩµÄÈë¿ÚµãλÖ㬷Ö
±ðÊÇ£º
(1) lseek£¬Òƶ¯ÎļþÖ¸ÕëµÄλÖã¬ÏÔȻֻÄÜÓÃÓÚ¿ÉÒÔËæ»ú´æÈ¡µÄÉ豸¡£
(2) read£¬½øÐжÁ²Ù×÷£¬²ÎÊýbufΪ´æ·Å¶ÁÈ¡½á¹ûµÄ»º³åÇø£¬countΪËùÒª
¶ÁÈ¡µÄÊý¾Ý³¤¶È¡£·µ»ØֵΪ¸º±íʾ¶ÁÈ¡²Ù×÷·¢Éú´íÎ󣬷ñÔò·µ»Øʵ¼Ê¶ÁÈ¡
µÄ×Ö½ÚÊý¡£¶ÔÓÚ×Ö·ûÐÍ£¬ÒªÇó¶ÁÈ¡µÄ×Ö½ÚÊýºÍ·µ»ØµÄʵ¼Ê¶ÁÈ¡×Ö½ÚÊý¶¼±Ø
ÐëÊÇinode->i_blksizeµÄµÄ±¶Êý¡£
(3) write£¬½øÐÐд²Ù×÷£¬ÓëreadÀàËÆ¡£
(4) readdir£¬È¡µÃÏÂÒ»¸öĿ¼Èë¿Úµã£¬Ö»ÓÐÓëÎļþϵͳÏà¹ØµÄÉ豸Çý¶¯³ÌÐò
²ÅʹÓá£
(5) selec£¬½øÐÐÑ¡Ôñ²Ù×÷£¬Èç¹ûÇý¶¯³ÌÐòûÓÐÌṩselectÈë¿Ú£¬select²Ù
×÷½«»áÈÏΪÉ豸ÒѾ­×¼±¸ºÃ½øÐÐÈκεÄI/O²Ù×÷¡£
(6) ioctl£¬½øÐжÁ¡¢Ð´ÒÔÍâµÄÆäËü²Ù×÷£¬²ÎÊýcmdΪ×Ô¶¨ÒåµÄµÄÃüÁî¡£
(7) mmap£¬ÓÃÓÚ°ÑÉ豸µÄÄÚÈÝÓ³Éäµ½µØÖ·¿Õ¼ä£¬Ò»°ãÖ»ÓпéÉ豸Çý¶¯³ÌÐòʹ

(8) open£¬´ò¿ªÉ豸׼±¸½øÐÐI/O²Ù×÷¡£·µ»Ø0±íʾ´ò¿ª³É¹¦£¬·µ»Ø¸ºÊý±í
ʾʧ°Ü¡£Èç¹ûÇý¶¯³ÌÐòûÓÐÌṩopenÈë¿Ú£¬ÔòÖ»Òª/dev/driverÎļþ´æ
ÔÚ¾ÍÈÏΪ´ò¿ª³É¹¦¡£
(9) release£¬¼´close²Ù×÷¡£
É豸Çý¶¯³ÌÐòËùÌṩµÄÈë¿Úµã£¬ÔÚÉ豸Çý¶¯³ÌÐò³õʼ»¯µÄʱºòÏòϵͳ½øÐеÇ
¼Ç£¬ÒÔ±ãϵͳÔÚÊʵ±µÄʱºòµ÷Óá£LINUXϵͳÀͨ¹ýµ÷ÓÃregister_chrdev
Ïòϵͳע²á×Ö·ûÐÍÉ豸Çý¶¯³ÌÐò¡£register_chrdev¶¨ÒåΪ£º
 #include <linux/fs.h>
 #include <linux/errno.h>
 int register_chrdev(unsigned int major, const char *name, 
             struct file_operations *fops);
ÆäÖУ¬majorÊÇΪÉ豸Çý¶¯³ÌÐòÏòϵͳÉêÇëµÄÖ÷É豸ºÅ£¬Èç¹ûΪ0ÔòϵͳΪ´Ë
Çý¶¯³ÌÐò¶¯Ì¬µØ·ÖÅäÒ»¸öÖ÷É豸ºÅ¡£nameÊÇÉ豸Ãû¡£fops¾ÍÊÇÇ°ÃæËù˵µÄ¶Ô¸÷¸ö
µ÷ÓõÄÈë¿ÚµãµÄ˵Ã÷¡£´Ëº¯Êý·µ»Ø0±íʾ³É¹¦¡£·µ»Ø-EINVAL±íʾÉêÇëµÄÖ÷É豸ºÅ
·Ç·¨£¬Ò»°ãÀ´ËµÊÇÖ÷É豸ºÅ´óÓÚϵͳËùÔÊÐíµÄ×î´óÉ豸ºÅ¡£·µ»Ø-EBUSY±íʾËùÉê
ÇëµÄÖ÷É豸ºÅÕýÔÚ±»ÆäËüÉ豸Çý¶¯³ÌÐòʹÓá£Èç¹ûÊǶ¯Ì¬·ÖÅäÖ÷É豸ºÅ³É¹¦£¬´Ë
º¯Êý½«·µ»ØËù·ÖÅäµÄÖ÷É豸ºÅ¡£Èç¹ûregister_chrdev²Ù×÷³É¹¦£¬É豸Ãû¾Í»á³ö
ÏÖÔÚ/proc/devicesÎļþÀï¡£
³õʼ»¯²¿·ÖÒ»°ã»¹¸ºÔð¸øÉ豸Çý¶¯³ÌÐòÉêÇëϵͳ×ÊÔ´£¬°üÀ¨ÄÚ´æ¡¢Öжϡ¢Ê±
ÖÓ¡¢I/O¶Ë¿ÚµÈ£¬ÕâЩ×ÊÔ´Ò²¿ÉÒÔÔÚopen×Ó³ÌÐò»ò±ðµÄµØ·½ÉêÇë¡£ÔÚÕâЩ×ÊÔ´²»
ÓõÄʱºò£¬Ó¦¸ÃÊÍ·ÅËüÃÇ£¬ÒÔÀûÓÚ×ÊÔ´µÄ¹²Ïí¡£
ÔÚUNIXϵͳÀ¶ÔÖжϵĴ¦ÀíÊÇÊôÓÚϵͳºËÐĵIJ¿·Ö£¬Òò´ËÈç¹ûÉ豸Óëϵ
ͳ֮¼äÒÔÖжϷ½Ê½½øÐÐÊý¾Ý½»»»µÄ»°£¬¾Í±ØÐë°Ñ¸ÃÉ豸µÄÇý¶¯³ÌÐò×÷ΪϵͳºËÐÄ
µÄÒ»²¿·Ö¡£É豸Çý¶¯³ÌÐòͨ¹ýµ÷ÓÃrequest_irqº¯ÊýÀ´ÉêÇëÖжϣ¬Í¨¹ýfree_irq
À´ÊÍ·ÅÖжϡ£ËüÃǵĶ¨ÒåΪ£º
#include <linux/sched.h>
int request_irq(unsigned int irq,
                void (*handler)(int irq,void dev_id,struct pt_regs *regs),
                unsigned long flags,
                const char *device,
                void *dev_id);
void free_irq(unsigned int irq, void *dev_id);
²ÎÊýirq±íʾËùÒªÉêÇëµÄÓ²¼þÖжϺš£handlerΪÏòϵͳµÇ¼ÇµÄÖжϴ¦Àí×Ó
³ÌÐò£¬ÖжϲúÉúʱÓÉϵͳÀ´µ÷Ó㬵÷ÓÃʱËù´ø²ÎÊýirqΪÖжϺţ¬dev_idΪÉê
Çëʱ¸æËßϵͳµÄÉ豸±êʶ£¬regsΪÖжϷ¢Éúʱ¼Ä´æÆ÷ÄÚÈÝ¡£deviceΪÉ豸Ãû£¬
½«»á³öÏÖÔÚ/proc/interruptsÎļþÀï¡£flagÊÇÉêÇëʱµÄÑ¡ÏËü¾ö¶¨Öжϴ¦Àí
³ÌÐòµÄһЩÌØÐÔ£¬ÆäÖÐ×îÖØÒªµÄÊÇÖжϴ¦Àí³ÌÐòÊÇ¿ìËÙ´¦Àí³ÌÐò£¨flagÀïÉèÖÃ
ÁËSA_INTERRUPT£©»¹ÊÇÂýËÙ´¦Àí³ÌÐò£¨²»ÉèÖÃSA_INTERRUPT£©£¬¿ìËÙ´¦Àí³ÌÐò
ÔËÐÐʱ£¬ËùÓÐÖж϶¼±»ÆÁ±Î£¬¶øÂýËÙ´¦Àí³ÌÐòÔËÐÐʱ£¬³ýÁËÕýÔÚ´¦ÀíµÄÖжÏÍ⣬
ÆäËüÖж϶¼Ã»Óб»ÆÁ±Î¡£ÔÚLINUXϵͳÖУ¬ÖжϿÉÒÔ±»²»Í¬µÄÖжϴ¦Àí³ÌÐò¹²Ïí£¬
ÕâÒªÇóÿһ¸ö¹²Ïí´ËÖжϵĴ¦Àí³ÌÐòÔÚÉêÇëÖжÏʱÔÚflagsÀïÉèÖÃSA_SHIRQ£¬
ÕâЩ´¦Àí³ÌÐòÖ®¼äÒÔdev_idÀ´Çø·Ö¡£Èç¹ûÖжÏÓÉij¸ö´¦Àí³ÌÐò¶ÀÕ¼£¬Ôòdev_id
¿ÉÒÔΪNULL¡£request_irq·µ»Ø0±íʾ³É¹¦£¬·µ»Ø-INVAL±íʾirq>15»ò
handler==NULL£¬·µ»Ø-EBUSY±íʾÖжÏÒѾ­±»Õ¼ÓÃÇÒ²»Äܹ²Ïí¡£
×÷ΪϵͳºËÐĵÄÒ»²¿·Ö£¬É豸Çý¶¯³ÌÐòÔÚÉêÇëºÍÊÍ·ÅÄÚ´æʱ²»Êǵ÷ÓÃmalloc
ºÍfree£¬¶ø´úÖ®ÒÔµ÷ÓÃkmallocºÍkfree£¬ËüÃDZ»¶¨ÒåΪ£º
#include <linux/kernel.h>
void * kmalloc(unsigned int len, int priority);
void kfree(void * obj);
²ÎÊýlenΪϣÍûÉêÇëµÄ×Ö½ÚÊý£¬objΪҪÊͷŵÄÄÚ´æÖ¸Õë¡£priorityΪ·ÖÅäÄÚ´æ²Ù
×÷µÄÓÅÏȼ¶£¬¼´ÔÚûÓÐ×ã¹»¿ÕÏÐÄÚ´æʱÈçºÎ²Ù×÷£¬Ò»°ãÓÃGFP_KERNEL¡£
ÓëÖжϺÍÄڴ治ͬ£¬Ê¹ÓÃÒ»¸öûÓÐÉêÇëµÄI/O¶Ë¿Ú²»»áʹCPU²úÉúÒì³££¬Ò²
¾Í²»»áµ¼ÖÂÖîÈç¡°segmentation fault"Ò»ÀàµÄ´íÎó·¢Éú¡£Èκνø³Ì¶¼¿ÉÒÔ·ÃÎÊ
ÈκÎÒ»¸öI/O¶Ë¿Ú¡£´ËʱϵͳÎÞ·¨±£Ö¤¶ÔI/O¶Ë¿ÚµÄ²Ù×÷²»»á·¢Éú³åÍ»£¬ÉõÖÁ»á
Òò´Ë¶øʹϵͳ±ÀÀ£¡£Òò´Ë£¬ÔÚʹÓÃI/O¶Ë¿ÚÇ°£¬Ò²Ó¦¸Ã¼ì²é´ËI/O¶Ë¿ÚÊÇ·ñÒÑÓÐ
±ðµÄ³ÌÐòÔÚʹÓã¬ÈôûÓУ¬ÔٰѴ˶˿ڱê¼ÇΪÕýÔÚʹÓã¬ÔÚʹÓÃÍêÒÔºóÊÍ·ÅËü¡£
ÕâÑùÐèÒªÓõ½Èçϼ¸¸öº¯Êý£º
int check_region(unsigned int from, unsigned int extent); 
void request_region(unsigned int from, unsigned int extent, 
                    const char *name); 
void release_region(unsigned int from, unsigned int extent);
µ÷ÓÃÕâЩº¯ÊýʱµÄ²ÎÊýΪ£ºfrom±íʾËùÉêÇëµÄI/O¶Ë¿ÚµÄÆðʼµØÖ·£»
extentΪËùÒªÉêÇëµÄ´Ófrom¿ªÊ¼µÄ¶Ë¿ÚÊý£»nameΪÉ豸Ãû£¬½«»á³öÏÖÔÚ
/proc/ioportsÎļþÀï¡£check_region·µ»Ø0±íʾI/O¶Ë¿Ú¿ÕÏУ¬·ñÔòΪÕýÔÚ
±»Ê¹Óá£
ÔÚÉêÇëÁËI/O¶Ë¿ÚÖ®ºó£¬¾Í¿ÉÒÔÈçϼ¸¸öº¯ÊýÀ´·ÃÎÊI/O¶Ë¿Ú£º
#include <asm/io.h>
inline unsigned int inb(unsigned short port);
inline unsigned int inb_p(unsigned short port);
inline void outb(char value, unsigned short port);
inline void outb_p(char value, unsigned short port);
ÆäÖÐinb_pºÍoutb_p²åÈëÁËÒ»¶¨µÄÑÓʱÒÔÊÊӦijЩÂýµÄI/O¶Ë¿Ú¡£
ÔÚÉ豸Çý¶¯³ÌÐòÀһ°ã¶¼ÐèÒªÓõ½¼Æʱ»úÖÆ¡£ÔÚLINUXϵͳÖУ¬Ê±ÖÓÊÇÓÉ
ϵͳ½Ó¹Ü£¬É豸Çý¶¯³ÌÐò¿ÉÒÔÏòϵͳÉêÇëʱÖÓ¡£ÓëʱÖÓÓйصÄϵͳµ÷ÓÃÓУº
#include <asm/param.h>
#include <linux/timer.h>
void add_timer(struct timer_list * timer);
int  del_timer(struct timer_list * timer);
inline void init_timer(struct timer_list * timer);
struct timer_listµÄ¶¨ÒåΪ£º
struct timer_list {
               struct timer_list *next;
               struct timer_list *prev;
               unsigned long expires;
               unsigned long data;
               void (*function)(unsigned long d);
       };
ÆäÖÐexpiresÊÇÒªÖ´ÐÐfunctionµÄʱ¼ä¡£ÏµÍ³ºËÐÄÓÐÒ»¸öÈ«¾Ö±äÁ¿JIFFIES
±íʾµ±Ç°Ê±¼ä£¬Ò»°ãÔÚµ÷ÓÃadd_timerʱjiffies=JIFFIES+num,±íʾÔÚnum¸ö
ϵͳ×îСʱ¼ä¼ä¸ôºóÖ´ÐÐfunction¡£ÏµÍ³×îСʱ¼ä¼ä¸ôÓëËùÓõÄÓ²¼þƽ̨Óйأ¬
ÔÚºËÐÄÀﶨÒåÁ˳£ÊýHZ±íʾһÃëÄÚ×îСʱ¼ä¼ä¸ôµÄÊýÄ¿£¬Ôònum*HZ±íʾnum
Ã롣ϵͳ¼Æʱµ½Ô¤¶¨Ê±¼ä¾Íµ÷ÓÃfunction£¬²¢°Ñ´Ë×Ó³ÌÐò´Ó¶¨Ê±¶ÓÁÐÀïɾ³ý£¬
Òò´ËÈç¹ûÏëҪÿ¸ôÒ»¶¨Ê±¼ä¼ä¸ôÖ´ÐÐÒ»´ÎµÄ»°£¬¾Í±ØÐëÔÚfunctionÀïÔÙÒ»´Îµ÷
ÓÃadd_timer¡£functionµÄ²ÎÊýd¼´ÎªtimerÀïÃæµÄdataÏî¡£
ÔÚÉ豸Çý¶¯³ÌÐòÀ»¹¿ÉÄÜ»áÓõ½ÈçϵÄһЩϵͳº¯Êý£º
#include <asm/system.h>
#define cli() __asm__ __volatile__ ("cli"::)
#define sti() __asm__ __volatile__ ("sti"::)
ÕâÁ½¸öº¯Êý¸ºÔð´ò¿ªºÍ¹Ø±ÕÖжÏÔÊÐí¡£
#include <asm/segment.h>
void memcpy_fromfs(void * to,const void * from,unsigned long n);
void memcpy_tofs(void * to,const void * from,unsigned long n);
ÔÚÓû§³ÌÐòµ÷ÓÃread ¡¢writeʱ£¬ÒòΪ½ø³ÌµÄÔËÐÐ״̬ÓÉÓû§Ì¬±äΪºËÐÄ
̬£¬µØÖ·¿Õ¼äÒ²±äΪºËÐĵØÖ·¿Õ¼ä¡£¶øread¡¢writeÖвÎÊýbufÊÇÖ¸ÏòÓû§³Ì
ÐòµÄ˽ÓеØÖ·¿Õ¼äµÄ£¬ËùÒÔ²»ÄÜÖ±½Ó·ÃÎÊ£¬±ØÐëͨ¹ýÉÏÊöÁ½¸öϵͳº¯ÊýÀ´·ÃÎÊÓÃ
»§³ÌÐòµÄ˽ÓеØÖ·¿Õ¼ä¡£memcpy_fromfsÓÉÓû§³ÌÐòµØÖ·¿Õ¼äÍùºËÐĵØÖ·¿Õ¼ä
¸´ÖÆ£¬memcpy_tofsÔò·´Ö®¡£²ÎÊýtoΪ¸´ÖƵÄÄ¿µÄÖ¸Õ룬fromΪԴָÕ룬n
ΪҪ¸´ÖƵÄ×Ö½ÚÊý¡£
ÔÚÉ豸Çý¶¯³ÌÐòÀ¿ÉÒÔµ÷ÓÃprintkÀ´´òӡһЩµ÷ÊÔÐÅÏ¢£¬Ó÷¨Óëprintf
ÀàËÆ¡£printk´òÓ¡µÄÐÅÏ¢²»½ö³öÏÖÔÚÆÁÄ»ÉÏ£¬Í¬Ê±»¹¼Ç¼ÔÚÎļþsyslogÀï¡£

3.3¡¢LINUXϵͳϵľßÌåʵÏÖ
ÔÚLINUXÀ³ýÁËÖ±½ÓÐÞ¸ÄϵͳºËÐĵÄÔ´´úÂ룬°ÑÉ豸Çý¶¯³ÌÐò¼Ó½øºËÐÄÀï
ÒÔÍ⣬»¹¿ÉÒÔ°ÑÉ豸Çý¶¯³ÌÐò×÷Ϊ¿É¼ÓÔصÄÄ£¿é£¬ÓÉϵͳ¹ÜÀíÔ±¶¯Ì¬µØ¼ÓÔØËü£¬
ʹ֮³ÉΪºËÐĵØÒ»²¿·Ö¡£Ò²¿ÉÒÔÓÉϵͳ¹ÜÀíÔ±°ÑÒѼÓÔصØÄ£¿é¶¯Ì¬µØжÔØÏÂÀ´¡£
LINUXÖУ¬Ä£¿é¿ÉÒÔÓÃCÓïÑÔ±àд£¬ÓÃgcc±àÒë³ÉÄ¿±êÎļþ£¨²»½øÐÐÁ´½Ó£¬×÷
Ϊ*.oÎļþ´æÔÚ£©£¬Îª´ËÐèÒªÔÚgccÃüÁîÐÐÀï¼ÓÉÏ-cµÄ²ÎÊý¡£ÔÚ±àÒëʱ£¬»¹Ó¦¸ÃÔÚ
gccµÄÃüÁîÐÐÀï¼ÓÉÏÕâÑùµÄ²ÎÊý£º-D__KERNEL__ -DMODULE¡£ÓÉÓÚÔÚ²»Á´½Óʱ£¬g
ccÖ»ÔÊÐíÒ»¸öÊäÈëÎļþ£¬Òò´ËÒ»¸öÄ£¿éµÄËùÓв¿·Ö¶¼±ØÐëÔÚÒ»¸öÎļþÀïʵÏÖ¡£
±àÒëºÃµÄÄ£¿é*.o·ÅÔÚ/lib/modules/xxxx/miscÏ£¨xxxx±íʾºËÐÄ°æ±¾£¬Èç
ÔÚºËÐİ汾Ϊ2.0.30ʱӦ¸ÃΪ/lib/modules/2.0.30/misc£©£¬È»ºóÓÃdepmod -a
ʹ´ËÄ£¿é³ÉΪ¿É¼ÓÔØÄ£¿é¡£Ä£¿éÓÃinsmodÃüÁî¼ÓÔØ£¬ÓÃrmmodÃüÁîÀ´Ð¶ÔØ£¬²¢¿É
ÒÔÓÃlsmodÃüÁîÀ´²é¿´ËùÓÐÒѼÓÔصÄÄ£¿éµÄ״̬¡£
±àдģ¿é³ÌÐòµÄʱºò£¬±ØÐëÌṩÁ½¸öº¯Êý£¬Ò»¸öÊÇint init_module(void)£¬
¹©insmodÔÚ¼ÓÔØ´ËÄ£¿éµÄʱºò×Ô¶¯µ÷Ó㬸ºÔð½øÐÐÉ豸Çý¶¯³ÌÐòµÄ³õʼ»¯¹¤×÷¡£
init_module·µ»Ø0ÒÔ±íʾ³õʼ»¯³É¹¦£¬·µ»Ø¸ºÊý±íʾʧ°Ü¡£ÁíÒ»¸öº¯ÊýÊÇvoid 
cleanup_module (void)£¬ÔÚÄ£¿é±»Ð¶ÔØʱµ÷Ó㬸ºÔð½øÐÐÉ豸Çý¶¯³ÌÐòµÄÇå³ý
¹¤×÷¡£
Ôڳɹ¦µÄÏòϵͳע²áÁËÉ豸Çý¶¯³ÌÐòºó£¨µ÷ÓÃregister_chrdev³É¹¦ºó£©£¬
¾Í¿ÉÒÔÓÃmknodÃüÁîÀ´°ÑÉ豸ӳÉäΪһ¸öÌرðÎļþ£¬ÆäËü³ÌÐòʹÓÃÕâ¸öÉ豸µÄʱ
ºò£¬Ö»Òª¶Ô´ËÌرðÎļþ½øÐвÙ×÷¾ÍÐÐÁË¡£


¸½Â¼£º²Î¿¼ÎÄÏ×

1¡¢ ¡¶UNIX²Ù×÷ϵͳÉè¼ÆÓëʵÏÖ¡·
 ³Â»ªçø¡¢À¹úÖ÷±à
 µç×Ó¹¤Òµ³ö°æÉç³ö°æ
2¡¢  ¡¶Linux Kernel Hacker's Guide¡·
 ×÷ÕߣºMichael K. Johnson
3¡¢ ¡¶Kernel Jorn¡·
 ×÷ÕߣºAlessandro Rubini & Georg Zezchwitz
 Á¬ÔØÓÚ¡¶Linux Journal¡·1996Äê3—6ÆÚ
4¡¢ LinuxºËÐÄÔ´´úÂ루ºËÐÄ°æ±¾2.0.30£©
5¡¢ Linux-HOWTO



--
m2m¡ù À´Ô´:¡¤BBS Ë®Ä¾Ç廪վ bbs.net.tsinghua.edu.cn¡¤[FROM: 162.105.160.125]m
--
m;32m¡ù ×ª¼Ä:£®»ªÄÏÍøľÃÞÕ¾ bbs.gznet.edu.cn£®[FROM: mtlab.hit.edu.cn]
--

                              Enjoy Linux!
                          -----It's FREE!-----

¡ù À´Ô´:£®×Ï ¶¡ Ïã bbs.hit.edu.cn£®[FROM: mtlab.hit.edu.cn]
[°Ù±¦Ïä] [·µ»ØÊ×Ò³] [Éϼ¶Ä¿Â¼] [¸ùĿ¼] [·µ»Ø¶¥²¿] [Ë¢ÐÂ] [·µ»Ø]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
Ò³ÃæÖ´ÐÐʱ¼ä£º209.707ºÁÃë