LECTURE 6 ioctl ¥·¥¹¥Æ¥à¥³¡¼¥ë

¡û ¤Ï¤¸¤á¤Ë

º£²ó¤Ï¡¢¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤éȯ¹Ô¤µ¤ì¤ë ioctl ¥·¥¹¥Æ¥à¥³¡¼¥ë¤ËÂбþ¤·¤Æ¤ß¤Þ¤¹¡£ioctl ¤Ï¡¢read ¤ä write ¤Ç¹Ô¤¦¤³¤È¤¬Å¬Åö¤Ç¤Ê¤¤¡¢¥Ç¥Ð¥¤¥¹¤ÎÀßÄê¤òÊѤ¨¤¿¤ê¤¹¤ë¾ì¹ç¤ËÎɤ¯»È¤ï¤ì¤Þ¤¹¡£

¤³¤³¤Ç¤Ï¡¢poll.c ¤ò²þ¤¤·¤Æ ioctl ¥·¥¹¥Æ¥à¥³¡¼¥ë¤ËÂбþ¤µ¤»¤Æ¤ß¤Þ¤·¤ç¤¦¡£

¡û ¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à

ioctl ¥·¥¹¥Æ¥à¥³¡¼¥ë¤ËÂбþ¤·¤¿¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à ioctl.c¡¢ chardev_ioct.h ¤Ç¤¹¡£ ¤Ï¤¸¤á¤Ë ¤Î¥Ú¡¼¥¸¤«¤é¡¢ Á´¤Æ¤Î¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤ò ¸Ç¤á¤¿ tar ¥Ü¡¼¥ë¤ò¥À¥¦¥ó¥í¡¼¥É¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

´Êñ¤Ê»î¸³¥×¥í¥°¥é¥à ioctl_test.c ¤âÍÑ°Õ¤·¤Æ¤ß¤Þ¤·¤¿¡£ ioctl.c ¤ò¥³¥ó¥Ñ¥¤¥ë¤·¤Æ insmod ¤ÇÁȤ߹þ¤ß¡¢ioctl_test.c ¤Î¼Â¹Ô¥×¥í¥°¥é¥à¤ò¼Â¹Ô¤¹¤ë¤È

Tell driver to update internal value ...
Query driver internal value ...
Internal value = 0
Tell driver to update internal value via pointer ...
Query driver internal value via pointer ...
Internal value = 1
Reset reference counter ...

¤Èɽ¼¨¤µ¤ì¤Þ¤¹¡£

--- ioctl.c ---

    1    #include <asm/semaphore.h>
    2    #include <asm/uaccess.h>    /* copy_from_user, copy_to_user */
    3    #include <linux/errno.h>
    4    #include <linux/fs.h>       /* inode, file, file_operations */
    5    #include <linux/ioctl.h>    /* ioctl */
    6    #include <linux/kernel.h>   /* printk() */
    7    #include <linux/module.h> 
    8    #include <linux/poll.h>     /* POLLIN ... */
    9    #include <linux/wait.h>     /* wait_queue_head_t */
   10    #include <linux/sched.h>    /* wait_event_interruptible, wake_up_interruptible */
   11    
   12    #include "chardev_ioctl.h"
   13    
   14    
   15    MODULE_AUTHOR( "Ryo" );
   16    MODULE_DESCRIPTION( "Sample character device driver." );
   17    MODULE_LICENSE( "GPL" );
   18    
   19    
   20    static int   devmajor = 77;
   21    static char* devname  = "chardev";
   22    static char* msg      = "module [poll.o]";
   23    
   24    
   25    #define MAXBUF 32
   26    static unsigned char devbuf[ MAXBUF ];
   27    static int buf_pos;
   28    
   29    static struct semaphore chardev_sem;
   30    static wait_queue_head_t write_q;
   31    static wait_queue_head_t read_q;
   32    
   33    
   34    /*
   35     * ¥í¥°½ÐÎÏ¥Õ¥©¡¼¥Þ¥Ã¥ÈÍÑ´Ø¿ô
   36     */
   37    static void 
   38    log_format( char* body )
   39    {
   40        if ( current != NULL ) {
   41            printk( KERN_INFO "%s : PID = %-5i cmdline = \"%-10s\" : %s\n", 
   42                msg, current->pid, current->comm, body );
   43        }
   44        else {
   45            printk( KERN_INFO "%s : %s\n", msg, body );
   46        }
   47    }
   48    
   49    
   50    /*
   51     * open()
   52     */
   53    static int 
   54    chardev_open( struct inode* inode, struct file* filp )
   55    {
   56        log_format( "open()  called" );
   57        return 0;
   58    }
   59    
   60    
   61    /*
   62     * release()
   63     */
   64    static int 
   65    chardev_release( struct inode* inode, struct file* filp )
   66    {
   67        log_format( "close() called" );
   68        return 0;
   69    }
   70    
   71    
   72    /*
   73     * read()
   74     * ¥æ¡¼¥¶¥×¥í¥»¥¹¤ËÂФ·¤ÆÆâÉô¥Ð¥Ã¥Õ¥¡¤ÎÆâÍƤòžÁ÷¤¹¤ë¡£
   75     * žÁ÷¤·¤¿ÆâÍƤÏÆâÉô¥Ð¥Ã¥Õ¥¡¤«¤é¾Ã¤¨¤ë¡£
   76     */
   77    static ssize_t 
   78    chardev_read( struct file* filp, char* buf, size_t count, loff_t* pos )
   79    {
   80        int copy_len;
   81        int i;
   82    
   83        log_format( "read()  called" );
   84    
   85        if ( down_interruptible( &chardev_sem ) ) {
   86            log_format( "down_interruptible for read failed" );
   87            return -ERESTARTSYS;
   88        }
   89    
   90        while ( buf_pos == 0 ) {
   91            up( &chardev_sem );
   92    
   93            if ( filp->f_flags & O_NONBLOCK ) {
   94                log_format( "read return because O_NONBLOCK is specified" );
   95                return -EAGAIN;
   96            }
   97    
   98            log_format( "read process going to sleep" );
   99    
  100            if ( wait_event_interruptible( read_q, ( buf_pos != 0 ) ) )
  101                return -ERESTARTSYS;
  102    
  103            if ( down_interruptible( &chardev_sem ) ) {
  104                log_format( "down_interruptible for read failed" );
  105                return -ERESTARTSYS;
  106            }
  107        }
  108    
  109    
  110        log_format( "read process going to read" );
  111    
  112        if ( count > buf_pos )
  113            copy_len = buf_pos;
  114        else
  115            copy_len = count;
  116    
  117        if ( copy_to_user( buf, devbuf, copy_len ) ) {
  118            up( &chardev_sem );
  119            log_format( "copy_to_user failed" );
  120            return -EFAULT;
  121        }
  122    
  123        *pos += copy_len;
  124    
  125        for ( i = copy_len; i < buf_pos; i ++ )
  126            devbuf[ i - copy_len ] = devbuf[i];
  127    
  128        buf_pos -= copy_len;
  129    
  130        up( &chardev_sem );
  131        wake_up_interruptible( &write_q );
  132    
  133        return copy_len;
  134    }
  135    
  136    
  137    /*
  138     * write()
  139     * ¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤éžÁ÷¤µ¤ì¤¿ÆâÍƤòÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë½ñ¤­¹þ¤à¡£
  140     */
  141    static ssize_t 
  142    chardev_write( struct file* filp, const char* buf, size_t count, loff_t* pos )
  143    {
  144        int copy_len;
  145    
  146        log_format( "write() called" );
  147    
  148        if ( down_interruptible( &chardev_sem ) ) {
  149            log_format( "down_interruptible for write failed" );
  150            return -ERESTARTSYS;
  151        }
  152    
  153        while ( buf_pos == MAXBUF ) {
  154            up( &chardev_sem );
  155    
  156            if ( filp->f_flags & O_NONBLOCK ) {
  157                log_format( "write return because O_NONBLOCK is specified" );
  158                return -EAGAIN;
  159            }
  160    
  161            log_format( "write process going to sleep" );
  162    
  163            if ( wait_event_interruptible( write_q, ( buf_pos != MAXBUF ) ) )
  164                return -ERESTARTSYS;
  165    
  166            if ( down_interruptible( &chardev_sem ) ) {
  167                log_format( "down_interruptible for write failed" );
  168                return -ERESTARTSYS;
  169            }
  170        }
  171    
  172    
  173        log_format( "write process going to write" );
  174    
  175        if ( count > ( MAXBUF - buf_pos ) )
  176            copy_len = MAXBUF - buf_pos;
  177        else
  178            copy_len = count;
  179    
  180        if ( copy_from_user( devbuf + buf_pos, buf, copy_len ) ) {
  181            up( &chardev_sem );
  182            log_format( "copy_from_user failed" );
  183            return -EFAULT;
  184        }
  185    
  186        *pos    += copy_len;
  187        buf_pos += copy_len;
  188    
  189        up( &chardev_sem );
  190        wake_up_interruptible( &read_q );
  191    
  192        return copy_len;
  193    }
  194    
  195    
  196    /*
  197     * poll()
  198     * select / poll ¥·¥¹¥Æ¥à¥³¡¼¥ëȯ¹Ô»þ¤Ë¼Â¹Ô¤µ¤ì¤ë¡£
  199     */
  200    static unsigned int 
  201    chardev_poll( struct file* filp, poll_table* wait )
  202    {
  203        unsigned int retmask = 0;
  204    
  205        log_format( "poll()  called" );
  206    
  207        poll_wait( filp, &read_q,  wait );
  208        poll_wait( filp, &write_q, wait );
  209    
  210        if ( buf_pos != 0 ) {
  211            retmask |= ( POLLIN  | POLLRDNORM );
  212            log_format( "POLLIN  | POLLRDNORM" );
  213        }
  214    
  215        if ( buf_pos != MAXBUF ) {
  216            retmask |= ( POLLOUT | POLLWRNORM );
  217            log_format( "POLLOUT | POLLWRNORM" );
  218        }
  219    
  220        /* 
  221           Æɤ߹þ¤ß¥Ç¥Ð¥¤¥¹¤¬ EOF ¤Î¾ì¹ç¤Ï retmask ¤Ë POLLHUP ¤òÀßÄê
  222           ¥Ç¥Ð¥¤¥¹¤¬¥¨¥é¡¼¾õÂ֤Ǥ¢¤ë¾ì¹ç¤Ï POLLERR ¤òÀßÄê
  223           out-of-band ¥Ç¡¼¥¿¤¬Æɤ߽Ф»¤ë¾ì¹ç¤Ï POLLPRI ¤òÀßÄê
  224        */
  225    
  226        return retmask;
  227    }
  228    
  229    
  230    /* 
  231     * ioctl()
  232     * Ê£¿ô¥×¥í¥»¥¹¤¬Æ±°ìÊÑ¿ô¤òÁàºî¤¹¤ë¤¿¤á¡¢¥»¥Þ¥Õ¥©¤ä¥¹¥Ô¥ó¥í¥Ã¥¯Åù¤Ç¤Î
  233     * ¥í¥Ã¥¯¤ò¹Íθ¤¹¤Ù¤­¤À¤¬¡¢ioctl ¤Î¼ÂÁõ¤òÎ㼨¤·¤¿¤¤¤À¤±¤Ê¤Î¤Ç¥í¥Ã¥¯¤Ï
  234     * °ìÀڻȤäƤ¤¤Ê¤¤¡£¡£¡£
  235     */
  236    static int 
  237    chardev_ioctl( 
  238        struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg )
  239    {
  240        static int ioctl_value = 0;
  241        int ret = 0;
  242    
  243        log_format( "ioctl()  called" );
  244    
  245        switch( cmd ) {
  246            case CHARDEV_IOCTL_TELL :
  247                log_format( "IOCTL_TELL" );
  248                ioctl_value = arg;
  249                break;
  250    
  251            case CHARDEV_IOCTL_SET :
  252                log_format( "IOCTL_SET" );
  253                if ( get_user( ioctl_value, ( int* )arg ) ) 
  254                    return -EFAULT;
  255                break;
  256    
  257            case CHARDEV_IOCTL_QUERY :
  258                log_format( "IOCTL_QUERY" );
  259                return ioctl_value;
  260    
  261            case CHARDEV_IOCTL_GET :
  262                log_format( "IOCTL_GET" );
  263                if ( put_user( ioctl_value, ( int* )arg ) )
  264                    return -EFAULT;
  265                break;
  266    
  267            case CHARDEV_IOCTL_RESET :
  268                log_format( "IOCTL_RESET" );
  269    
  270                while ( MOD_IN_USE )
  271                    MOD_DEC_USE_COUNT;
  272    
  273                MOD_INC_USE_COUNT;
  274                break;
  275    
  276            default:
  277                return -EINVAL;
  278                /* POSIX ɸ½à¤Ç¤Ï -ENOTTY ¤é¤·¤¤ */
  279        }
  280    
  281        return 0;
  282    }
  283    
  284    
  285    static struct file_operations chardev_fops = 
  286    {
  287        owner   : THIS_MODULE,
  288        read    : chardev_read,
  289        write   : chardev_write,
  290        poll    : chardev_poll,
  291        ioctl   : chardev_ioctl,
  292        open    : chardev_open,
  293        release : chardev_release,
  294    };
  295    
  296    
  297    /*
  298     * ¥â¥¸¥å¡¼¥ë¤Î½é´ü½èÍý
  299     * insmod »þ¤Ë¸Æ¤Ð¤ì¤ë
  300     */
  301    int 
  302    init_module( void )
  303    {
  304        if ( register_chrdev( devmajor, devname, &chardev_fops ) ) {
  305            log_format( "register_chrdev failed" );
  306            return -EBUSY;
  307        }
  308    
  309        sema_init( &chardev_sem, 1 );
  310        init_waitqueue_head( &write_q );
  311        init_waitqueue_head( &read_q );
  312    
  313        log_format( "loaded  into kernel" );
  314        return 0;
  315    }
  316    
  317    
  318    /*
  319     * ¥â¥¸¥å¡¼¥ë¤Î²òÊü½èÍý
  320     * ¥â¥¸¥å¡¼¥ë¤Î»²¾È¿ô¤¬ 0 ¤Ç¤¢¤ì¤Ð¡¢rmmod »þ¤Ë¸Æ¤Ð¤ì¤ë
  321     */
  322    void
  323    cleanup_module( void )
  324    {
  325        if ( unregister_chrdev( devmajor, devname ) ) {
  326            log_format( "unregister_chrdev failed" );
  327            /* Âкö̵¤· ... */
  328        }
  329    
  330        log_format( "removed from kernel" );
  331    }
  332    
  333    
  334    /* End of ioctl.c */

--- chardev_ioctl.h ---

    1    #ifndef ___chardev_ioctl_h_included_
    2    #define ___chardev_ioctl_h_included_
    3    
    4    #include <linux/ioctl.h>
    5    
    6    /* 
    7     * /dev/chardev ¤ËÂФ¹¤ë ioctl() ¥³¥Þ¥ó¥É¤Ë»È¤¦¥Þ¥¸¥Ã¥¯¥Ê¥ó¥Ð¡¼
    8     *
    9     * /usr/src/linux/Documentation/ioctl-number.txt ¤Ëµ­½Ò¤µ¤ì¤Æ¤¤¤ë 
   10     * Code ¤È¤Ö¤Ä¤«¤é¤Ê¤¤¤â¤Î¤òÁª¤Ö
   11     */
   12    #define CHARDEV_IOCTL_MAGIC  0xAE
   13    
   14    
   15    #define CHARDEV_IOCTL_TELL   _IOC( _IOC_NONE,  CHARDEV_IOCTL_MAGIC, 0, 0 )
   16    #define CHARDEV_IOCTL_SET    _IOC( _IOC_WRITE, CHARDEV_IOCTL_MAGIC, 1, sizeof( int ) )
   17    #define CHARDEV_IOCTL_QUERY  _IOC( _IOC_NONE,  CHARDEV_IOCTL_MAGIC, 2, 0 ) 
   18    #define CHARDEV_IOCTL_GET    _IOC( _IOC_READ,  CHARDEV_IOCTL_MAGIC, 3, sizeof( int ) )
   19    #define CHARDEV_IOCTL_RESET  _IOC( _IOC_NONE,  CHARDEV_IOCTL_MAGIC, 4, 0 )
   20    
   21    
   22    #endif
   23    
   24    
   25    /* End of chardev_ioctl.h */

--- ioctl_test.c ---

    1    #include <fcntl.h>
    2    #include <stdlib.h>
    3    #include <sys/ioctl.h>
    4    
    5    #include "chardev_ioctl.h"
    6    
    7    
    8    int 
    9    main( void )
   10    {
   11        int  setval = 0;
   12        int  retval;
   13        int  fd;
   14    
   15        if ( ( fd = open( "/dev/chardev", O_RDWR ) ) < 0 ) {
   16            perror( "open" );
   17            exit( 1 );
   18        }
   19    
   20    
   21        /*
   22         * IOCTL_TELL
   23         */
   24        printf( "Tell driver to update internal value ...\n" );
   25    
   26        if ( ioctl( fd, CHARDEV_IOCTL_TELL, setval ) == -1 )
   27            perror( "ioctl( CHARDEV_IOCTL_TELL )" );
   28    
   29    
   30        /*
   31         * IOCTL_QUERY
   32         */
   33        printf( "Query driver internal value ...\n" );
   34    
   35        if ( ( retval = ioctl( fd, CHARDEV_IOCTL_QUERY ) ) == -1 )
   36            perror( "ioctl( CHARDEV_IOCTL_QUERY )" );
   37    
   38        printf( "Internal value = %d\n", retval );
   39        setval = retval + 1;
   40    
   41    
   42        /*
   43         * IOCTL_SET
   44         */
   45        printf( "Tell driver to update internal value via pointer ...\n" );
   46    
   47        if ( ioctl( fd, CHARDEV_IOCTL_SET, &setval ) == -1 )
   48            perror( "ioctl( CHARDEV_IOCTL_SET )" );
   49    
   50    
   51        /*
   52         * IOCTL_GET
   53         */
   54        printf( "Query driver internal value via pointer ...\n" );
   55    
   56        if ( ioctl( fd, CHARDEV_IOCTL_GET, &retval ) == -1 )
   57            perror( "ioctl( CHARDEV_IOCTL_GET )" );
   58    
   59        printf( "Internal value = %d\n", retval );
   60    
   61    
   62        /*
   63         * IOCTL_RESET
   64         */
   65        printf( "Reset reference counter ...\n" );
   66    
   67        if ( ioctl( fd, CHARDEV_IOCTL_RESET ) == -1 )
   68            perror( "ioctl( CHARDEV_IOCTL_RESET )" );
   69    
   70    
   71        close( fd );
   72        return 0;
   73    }
   74    
   75    
   76    /* End of ioctl_test.c */

¡û ¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤ÎÀâÌÀ

¤Ç¤Ï¡¢¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Æ¤¤¤­¤Þ¤¹¡£

ioctl.c ¤Ï¡¢Á°²ó¤Î poll.c ¤ò´ðËܤȤ·¤Æ¡¢ioctl ¥·¥¹¥Æ¥à¥³¡¼¥ëÂбþÍѤνèÍý¤òÄɲ䷤Ƥ¤¤Þ¤¹¡£¤³¤³¤Ç¤ÏÊѹ¹ÅÀ¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Þ¤¹¡£

  • 5¡¢12 ¹ÔÌÜ

    ioctl Âбþ½èÍý¤Î¼ÂÁõ¤ËɬÍפʥإåÀ¥Õ¥¡¥¤¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤·¤Æ¤¤¤Þ¤¹¡£ 12 ¹ÔÌܤǤϡ¢ioctl ¥³¥Þ¥ó¥ÉÄê¿ô¤òÄêµÁ¤·¤¿¼«ºî¤Î¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤·¤Æ¤¤¤Þ¤¹¡£

    ¥æ¡¼¥¶¥×¥í¥»¥¹¤Ç»ÈÍѤ¹¤ë ioctl ¥·¥¹¥Æ¥à¥³¡¼¥ë¤Î´Ø¿ô¥×¥í¥È¥¿¥¤¥×¤Ï

    #include <sys/ioctl.h>
    int ioctl( int fd, int request, ... );
         

    ¤ÎÍͤˤʤê¤Þ¤¹¡£Âè 2 °ú¿ô¤Ë¥³¥Þ¥ó¥É¤ò»ØÄꤹ¤ëÄê¿ô¤ò¡¢Âè 3 °ú¿ô¤Ë ¥³¥Þ¥ó¥É¤Î°ú¿ô¤òľÀÜÃͤȤ·¤Æ¡¢¤¢¤ë¤¤¤Ï¥Ý¥¤¥ó¥¿¤ò²ð¤·¤Æ¥Ç¡¼¥¿¤òÅϤ·¤Þ¤¹ ( °ú¿ô¤¬Ìµ¤¯¤Æ¤âÎɤ¤ )¡£

    chardev_ioctl.h ¤Ç¤Ï°Ê²¼¤Î ioctl ¥³¥Þ¥ó¥ÉÄê¿ô¤òÄêµÁ¤·¤Æ¤¤¤Þ¤¹¡£

    Äê¿ô̾ ¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤é¸«¤¿Æþ½ÐÎÏÊý¸þ ioctl Âè3°ú¿ô¤Î·¿
    CHARDEV_IOCTL_TELL ½ÐÎÏ ÃÍ
    CHARDEV_IOCTL_SET ½ÐÎÏ ¥Ý¥¤¥ó¥¿
    CHARDEV_IOCTL_QUERY ÆþÎÏ ÃÍ
    CHARDEV_IOCTL_GET ÆþÎÏ ¥Ý¥¤¥ó¥¿
    CHARDEV_IOCTL_RESET ½ÐÎÏ Ìµ¤·

    CHARDEV_IOCTL_TELL / CHARDEV_IOCTL_SET ¤Ï¤É¤Á¤é¤â¡¢¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð ¤ËÂФ·¤ÆÃͤòÀßÄꤹ¤ë¥³¥Þ¥ó¥É¤Ç¤¹¡£TELL ¤ÏľÀÜÃͤòÄÌÃΤ·¡¢SET ¤Ï¥Ý¥¤¥ó¥¿ ¤òÂè 3 °ú¿ô¤ËÀßÄꤹ¤ëÅÀ¤¬°Û¤Ê¤ê¤Þ¤¹¡£

    CHARDEV_IOCTL_QUERY / CHARDEV_IOCTL_GET ¤Ï¤É¤ê¤¿¤â¡¢¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð ¤«¤éÃͤò¼èÆÀ¤¹¤ë¥³¥Þ¥ó¥É¤Ç¤¹¡£QUERY ¤Ï ioctl ¤ÎÊÖ¤êÃͤȤ·¤ÆÃͤò¼èÆÀ¤·¡¢ GET ¤ÏÂè 3 °ú¿ô¤ËÀßÄꤷ¤¿¥Ý¥¤¥ó¥¿¤Î»²¾ÈÀè¤ËÃͤò³ÊǼ¤¹¤ëÅÀ¤¬°Û¤Ê¤ê¤Þ¤¹¡£

    CHARDEV_IOCTL_RESET ¤Ï¥Ç¥Ð¥Ã¥°ÍѤΥ³¥Þ¥ó¥É¤Ç¡¢¥«¡¼¥Í¥ë¥â¥¸¥å¡¼¥ë¤Î »²¾È¥«¥¦¥ó¥¿ ( ¥æ¡¼¥¶¥×¥í¥»¥¹¤ä¾¤Î¥«¡¼¥Í¥ë¥â¥¸¥å¡¼¥ëÅù¤«¤é»²¾È¤µ¤ì¤Æ¤¤¤ë ¿ô¤ò´ÉÍý¤¹¤ë¥«¥¦¥ó¥¿ ) ¤ò¡¢¶¯À©Åª¤Ë 1 ¤Ë¤·¤Æ¤·¤Þ¤¤¤Þ¤¹¡£¤³¤ì¤ò¼Â¹Ô¤·¤¿Ä¾¸å¤Ë ¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤òÊĤ¸¤Æ¤·¤Þ¤¨¤Ð»²¾È¥«¥¦¥ó¥¿¤Ï 0 ¤Ë¤Ê¤ë¤¿¤á¡¢Â¾¤Ë»²¾È¤·¤Æ¤¤¤ë ¥æ¡¼¥¶¥×¥í¥»¥¹Åù¤¬¤¢¤Ã¤Æ¤â¶¯À©Åª¤Ë rmmod ¤·¤Æ¤·¤Þ¤¦¤³¤È¤¬½ÐÍè¤Þ¤¹¡£

    ¥æ¡¼¥¶¥×¥í¥»¥¹¤Ë¤ª¤±¤ë¤³¤ì¤é¤Î¥³¥Þ¥ó¥É¤Î¾Ü¤·¤¤»È¤¤Êý¤Ï¡¢ ioctl_test.c ¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£

    ¤È¤³¤í¤Ç³Æ¡¹¤Î¥³¥Þ¥ó¥ÉÄê¿ô¤Ï¡¢¥·¥¹¥Æ¥àÁ´ÂΤÇÍ£°ì¤Ë¤Ê¤ë¤³¤È¤¬µá¤á¤é¤ì¤Þ¤¹¡£ ¤½¤Î¤¿¤á¤Ë¤Ï¤Þ¤º¡¢¥«¡¼¥Í¥ë¥½¡¼¥¹¥Ä¥ê¡¼Æâ¤Î Documentation/ioctl-number.txt ¤ò»²¾È¤·¤Æ¡¢»È¤ï¤ì¤Æ¤¤¤Ê¤¤¥Þ¥¸¥Ã¥¯¥Ê¥ó¥Ð¡¼¤ò·èÄꤷ¤Þ¤¹¡£ chardev_ioctl.h ¤Ç¤Ï¡¢0xAE ¤ò »È¤Ã¤Æ¤¤¤Þ¤¹¡£¤³¤ÎÃͤϡ¢»È¤Ã¤Æ¤¤¤ë¥·¥¹¥Æ¥à¤Ë±þ¤¸¤Æ·èÄꤷ¤Æ²¼¤µ¤¤¡£

    ¼¡¤Ë¡¢_IOC ¥Þ¥¯¥í¤ò»È¤Ã¤ÆÄê¿ô¤òºî¤ê½Ð¤·¤Þ¤¹¡£

    #include <linux/ioctl.h>
    _IOC( direction, magic, number, size )
         

    direction ¤Ï¥æ¡¼¥¶¥×¥í¥»¥¹¤È¤Î¥Ç¡¼¥¿Å¾Á÷¤ÎÊý¸þ¤ò¡¢°Ê²¼¤ÎÄê¿ô¤Ç»ØÄꤷ¤Þ¤¹¡£

    Äê¿ô̾ ¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤é¸«¤¿¥Ç¡¼¥¿Å¾Á÷¤ÎÊý¸þ
    _IOC_NONE ̵¤· ( ¥Ý¥¤¥ó¥¿¤Ç¤Ï¤Ê¤¯Ä¾ÀÜÃͤò¤ä¤ê¤È¤ê¤¹¤ë¾ì¹ç¤Ï¡¢¤³¤ì¤ò»È¤¦ )
    _IOC_READ ÆþÎÏ
    _IOC_WRITE ½ÐÎÏ
    _IOC_READ | _IOC_WRITE Æþ½ÐÎÏ

    magic ¤Ï¡¢ÀèÄø·èÄꤷ¤¿¥Þ¥¸¥Ã¥¯¥Ê¥ó¥Ð¡¼¤ò»ØÄꤷ¤Þ¤¹¡£number ¤Ï¡¢ ¥³¥Þ¥ó¥É¤ò¼±Ê̤¹¤ë¤¿¤á¤ÎÄÌÈÖ¤ò»ØÄꤷ¤Þ¤¹¡£¥Ó¥Ã¥ÈÉý¤¬ 8 ¥Ó¥Ã¥È¤Ê¤Î¤Ç¡¢ 0 - 255 ¤ò»ØÄꤷ¤Þ¤¹¡£

    size ¤Ï¡¢¥Ç¡¼¥¿Å¾Á÷¤òȼ¤¦¾ì¹ç¤ÎžÁ÷¥µ¥¤¥º¤òÀßÄꤷ¤Þ¤¹¡£¤¿¤À¤·¡¢ ¥³¥Þ¥ó¥É¤«¤éžÁ÷¥µ¥¤¥º¤ò¥Ç¥³¡¼¥É¤·¤Æ»È¤¦¤Î¤Ç¤Ê¤±¤ì¤Ð¡¢Ê̤˲¿¤òÀßÄê ¤·¤Æ¤âÎɤ¤¤ß¤¿¤¤¤Ç¤¹¡£

  • 230 ¡Á 282 ¹ÔÌÜ ( chardev_ioctl )

    º£²óÄɲä·¤¿´Ø¿ô¤Ç¤¹¡£ioctl ¥·¥¹¥Æ¥à¥³¡¼¥ë¤¬È¯¹Ô¤µ¤ì¤¿ºÝ¤Ë¼Â¹Ô¤µ¤ì¤Þ¤¹¡£ switch ʸ¤Ç¥³¥Þ¥ó¥É¤Ë±þ¤¸¤¿½èÍý¤ò¹Ô¤Ã¤Æ¤¤¤ë¤À¤±¤Ç¤¹¡£chardev_ioctl ¤ÎÂè 3 °ú¿ô cmd ¤È¤·¤Æ¥³¥Þ¥ó¥ÉÄê¿ô¤¬¡¢Âè 4 °ú¿ô arg ¤È¤·¤Æ¥æ¡¼¥¶¥×¥í¥»¥¹¤Ç ioctl ¥·¥¹¥Æ¥à¥³¡¼¥ë¤ÎÂè 3 °ú¿ô¤ËÀßÄꤷ¤¿ÊÑ¿ô¤¬ÅϤµ¤ì¤Þ¤¹¡£

    ¥³¥Þ¥ó¥É ½èÍýÆâÍÆ
    CHARDEV_IOCTL_TELL arg ¤òľÀܤÎÀßÄêÃͤȤ·¤Æ¤¤¤ë¤Î¤Ç¡¢ÆâÉôÊÑ¿ô¤ËÀßÄꤷ¤Þ¤¹¡£
    CHARDEV_IOCTL_SET arg ¤ÏÀ°¿ôÊÑ¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤È¤·¤Æ°·¤¤¤Þ¤¹¡£¤³¤Î¥Ý¥¤¥ó¥¿¤Î»²¾ÈÀ褫¤é ÆâÉôÊÑ¿ô¤Ë¥Ç¡¼¥¿¤òžÁ÷¤¹¤ë¤Î¤Ç¤¹¤¬¡¢read / write ¤Î¼ÂÁõƱÍÍ¡¢Ä¾ÀÜÂåÆþ ¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£¤³¤³¤Ç¤Ï¡¢1 / 2 / 4 ¥Ð¥¤¥È¤Î¥Ç¡¼¥¿Å¾Á÷¤ò copy_from_user ¤è¤ê¤âÁ᤯¹Ô¤Ã¤Æ¤¯¤ì¤ë get_user ´Ø¿ô¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡£ get_user ¤ÏÀ®¸ù¤¹¤ë¤È 0¡¢¼ºÇÔ¤¹¤ë¤È -EFAULT ¤òÊÖ¤·¤Þ¤¹¡£
    CHARDEV_IOCTL_QUERY ioctl ¤ÎÌá¤êÃͤòÊÖµÑÃͤȤ·¤Æ¤¤¤ë¤Î¤Ç¡¢ÆâÉôÊÑ¿ô¤ÎÃͤò return ¤·¤Þ¤¹¡£
    CHARDEV_IOCTL_GET arg ¤ÏÀ°¿ôÊÑ´¹¤Ø¤Î¥Ý¥¤¥ó¥¿¤È¤·¤Æ°·¤¤¤Þ¤¹¡£¤³¤Î¥Ý¥¤¥ó¥¿¤Î»²¾ÈÀè¤ËÂФ·¤Æ¡¢ 1 / 2 / 4 ¥Ð¥¤¥È¤Î¥Ç¡¼¥¿Å¾Á÷¤ò copy_to_user ¤è¤ê¤âÁ᤯¹Ô¤Ã¤Æ¤¯¤ì¤ë put_user ´Ø¿ô¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡£put_user ¤ÏÀ®¸ù¤¹¤ë¤È 0 ¤ò¡¢¼ºÇÔ¤¹¤ë¤È -EFAULT ¤òÊÖ¤·¤Þ¤¹¡£
    CHARDEV_IOCTL_RESET ¥«¡¼¥Í¥ë¥â¥¸¥å¡¼¥ë¤Î»²¾È¥«¥¦¥ó¥¿¤ò¡¢¶¯À©Åª¤Ë 1 ¤Ë¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢ ¼Â¹Ô¸å¤Ë¥Õ¥¡¥¤¥ëµ­½Ò»Ò¤òÊĤ¸¤ì¤Ð»²¾È¥«¥¦¥ó¥¿¤¬ 0 ¤È¤Ê¤ê¡¢Â¾¥æ¡¼¥¶¥×¥í¥»¥¹ ¤¬»²¾ÈÃæ¤Ç¤¢¤Ã¤Æ¤â rmmod ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ËÜÅö¤ÎÌÜŪ¤Ï¡¢¥Ð¥°Åù¤Ç »²¾È¥«¥¦¥ó¥¿¤¬¶¸¤Ã¤Æ¤·¤Þ¤¤ rmmod ¤Ç¤­¤Ê¤¯¤Ê¤Ã¤Æ¤·¤Þ¤Ã¤¿»þ¤Ë»È¤¤¤¿¤¤¤À¤±¤Ç¤¹¡£ MOD_IN_USE ¥Þ¥¯¥í¤Ï¡¢»²¾È¥«¥¦¥ó¥¿¤¬ 0 ¤Ç̵¤¤¾ì¹ç¤Ë¿¿¤Èɾ²Á¤µ¤ì¤Þ¤¹¡£ MOD_DEC_USE_COUNT ¥Þ¥¯¥í¤Ï»²¾È¥«¥¦¥ó¥¿¤ò 1 ¸º»»¤·¡¢ MOD_INC_USE_COUNT ¥Þ¥¯¥í¤Ï»²¾È¥«¥¦¥ó¥¿¤ò 1 Áý²Ã¤·¤Þ¤¹¡£ ¤³¤ì¤é¤ò»È¤¤¡¢»²¾È¥«¥¦¥ó¥¿¤¬ 0 ¤Ë¤Ê¤ë¤Þ¤Ç MOD_DEC_USE_COUNT ¤Ç¸º»»¤·¡¢ ºÇ¸å¤Ë MOD_INC_USE_COUNT ¤Ç 1 ¤Ë¤·¤Æ¤¤¤Þ¤¹¡£

  • 285 ¡Á 294 ¹ÔÌÜ

    struct file_opearations ¥Æ¡¼¥Ö¥ë¤Î ioctl ¥¿¥°¤ËÂФ·¤Æ¡¢¿·¤¿¤Ë chardev_ioctl ¤Ø¤Î´Ø¿ô¥Ý¥¤¥ó¥¿¤òÀßÄꤷ¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢ioctl ¥·¥¹¥Æ¥à¥³¡¼¥ë¤¬È¯¹Ô¤µ¤ì¤¿ºÝ¤Ë chardev_ioctl ´Ø¿ô¤¬¼Â¹Ô¤µ¤ì¤Þ¤¹¡£

°Ê¾å¤Ç ioctl.c ¤Î²òÀâ¤Ï½ª¤ï¤ê¤Ç¤¹¡£¥­¥ã¥é¥¯¥¿¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤È¤·¤Æ¤ÎÆâÍƤϤҤȤޤº½ªÎ»¤·¤Æ¡¢¼¡²ó¤«¤é¤Ï¾¤ÎÏÃÂê¤ò¼è¤ê¾å¤²¤¿¤¤¤È»×¤¤¤Þ¤¹¡£