LECTURE 3 Ê£¿ô¥×¥í¥»¥¹¤«¤é¤Î¥¢¥¯¥»¥¹

¡û ¤Ï¤¸¤á¤Ë

LECTURE 2 ñ½ã¤Ê¥­¥ã¥é¥¯¥¿¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð ¤ÇÀâÌÀ¤·¤¿ chardev.c ¤Ç¤Ï¡¢Æ±»þ¤Ë open ¤Ç¤­¤ë¥æ¡¼¥¶¥×¥í¥»¥¹¿ô¤ò 1 ¤ËÀ©¸Â¤·¤Æ¤¤¤Þ¤·¤¿¡£

º£²ó¤Ï¡¢¤³¤ÎÀ©¸Â¤ò̵¤¯¤·¤ÆÊ£¿ô¥æ¡¼¥¶¥×¥í¥»¥¹¤¬Æ±»þ¤Ë¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤ëÍͤˤ·¤Þ¤¹¡£¤³¤Î¾ì¹ç¤Ï¡¢Ê£¿ô¥×¥í¥»¥¹¤¬ read / write ¤ËƱ»þ¤Ë¥¢¥¯¥»¥¹¤¹¤ë¤³¤È¤ÇÆâÉô¥Ð¥Ã¥Õ¥¡¤ÎÆâÍƤËÉÔÀ°¹ç¤¬À¸¤¸¤Ê¤¤Íͤˤ¹¤ë¤¿¤á¡¢ÆâÉô¥Ð¥Ã¥Õ¥¡Áàºî¤ÎÁ°¸å¤Ç¥í¥Ã¥¯¤ò¼èÆÀ / ²òÊü¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

¤³¤³¤Ç¤Ï¡¢¤³¤ÎÍͤʶ¥¹ç¾õÂÖ¤òËɤ°¤¿¤á¤Î¥í¥Ã¥¯¤Î¤¦¤Á¡¢¥»¥Þ¥Õ¥©¤È¸Æ¤Ð¤ì¤ë¥í¥Ã¥¯¤ò»ÈÍѤ¹¤ëÊýË¡¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Þ¤¹¡£

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

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

¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤é¥¢¥¯¥»¥¹¤¹¤ë¤¿¤á¤Î¥Ç¥Ð¥¤¥¹¥Õ¥¡¥¤¥ë¤Ï¡¢Á°²ó¤ÈƱ¤¸ /dev/chardev ¤ò»È¤¤¤Þ¤¹¡£¤³¤ì°Ê¹ß¤Î¥µ¥ó¥×¥ë¤Ç¤âÆä˻ØÄ̵꤬¤¤¾ì¹ç¤ÏƱ¤¸¥Ç¥Ð¥¤¥¹¥Õ¥¡¥¤¥ë¤ò»È¤¤¤Þ¤¹¡£

multiproc.c ¤Ï¡¢echo ¤ä cat ¤ÇÁàºî¤¹¤ëʬ¤Ë¤ÏÆä˰㤤¤Ïʬ¤«¤ê¤Þ¤»¤ó¡£¥Ç¥Ð¥¤¥¹¥Õ¥¡¥¤¥ë¤ò¥ª¡¼¥×¥ó¤·¤Æ¤·¤Ð¤é¤¯½èÍý¤ò³¤±¤ëÍÍ¤Ê¥×¥í¥»¥¹¤Î¾ì¹ç¤Ë¤Ï¡¢Ê£¿ô¥×¥í¥»¥¹¤«¤é¥Ç¥Ð¥¤¥¹¥Õ¥¡¥¤¥ë¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤ë¤³¤È¤¬Ê¬¤«¤ê¤Þ¤¹¡£

--- multiproc.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/kernel.h>   /* printk */
    6    #include <linux/module.h>
    7    
    8    
    9    MODULE_AUTHOR( "Ryo" );
   10    MODULE_DESCRIPTION( "Sample character device driver." );
   11    MODULE_LICENSE( "GPL" );
   12    
   13    
   14    static int   devmajor = 77;
   15    static char* devname  = "chardev";
   16    static char* msg      = "module [multiproc.o]";
   17    
   18    
   19    #define MAXBUF 32
   20    static unsigned char devbuf[ MAXBUF ];
   21    static int buf_pos;
   22    
   23    static struct semaphore chardev_sem;
   24    
   25    
   26    /*
   27     * open()
   28     */
   29    static int 
   30    chardev_open( struct inode* inode, struct file* filp )
   31    {
   32        printk( KERN_INFO "%s : open()  called\n", msg );
   33        return 0;
   34    }
   35    
   36    
   37    /*
   38     * release()
   39     */
   40    static int 
   41    chardev_release( struct inode* inode, struct file* filp )
   42    {
   43        printk( KERN_INFO "%s : close() called\n", msg );
   44        return 0;
   45    }
   46    
   47    
   48    /*
   49     * read()
   50     * ¥æ¡¼¥¶¥×¥í¥»¥¹¤ËÂФ·¤ÆÆâÉô¥Ð¥Ã¥Õ¥¡¤ÎÆâÍƤòžÁ÷¤¹¤ë¡£
   51     * žÁ÷¤·¤¿ÆâÍƤÏÆâÉô¥Ð¥Ã¥Õ¥¡¤«¤é¾Ã¤¨¤ë¡£
   52     */
   53    static ssize_t 
   54    chardev_read( struct file* filp, char* buf, size_t count, loff_t* pos )
   55    {
   56        int copy_len;
   57        int i;
   58    
   59        printk( KERN_INFO "%s : read()  called\n", msg );
   60    
   61        if ( down_interruptible( &chardev_sem ) ) {
   62            printk( KERN_INFO "%s : down_interruptible for read failed\n", msg );
   63            return -ERESTARTSYS;
   64        }
   65    
   66        printk( KERN_INFO "%s : down_interruptible for read successed\n", msg );
   67    
   68        if ( count > buf_pos )
   69            copy_len = buf_pos;
   70        else
   71            copy_len = count;
   72    
   73        if ( copy_to_user( buf, devbuf, copy_len ) ) {
   74            up( &chardev_sem );
   75            printk( KERN_INFO "%s : copy_to_user failed\n", msg );
   76            return -EFAULT;
   77        }
   78    
   79        *pos += copy_len;
   80    
   81        for ( i = copy_len; i < buf_pos; i ++ )
   82            devbuf[ i - copy_len ] = devbuf[i];
   83    
   84        buf_pos -= copy_len;
   85        up( &chardev_sem );
   86        printk( KERN_INFO "%s : buf_pos = %d\n", msg, buf_pos );
   87    
   88        return copy_len;
   89    }
   90    
   91    
   92    /*
   93     * write()
   94     * ¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤éžÁ÷¤µ¤ì¤¿ÆâÍƤòÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë½ñ¤­¹þ¤à¡£
   95     */
   96    static ssize_t 
   97    chardev_write( struct file* filp, const char* buf, size_t count, loff_t* pos )
   98    {
   99        int copy_len;
  100    
  101        printk( KERN_INFO "%s : write() called\n", msg );
  102    
  103        if ( down_interruptible( &chardev_sem ) ) {
  104            printk( KERN_INFO "%s : down_interruptible for write failed\n", msg );
  105            return -ERESTARTSYS;
  106        }
  107    
  108        printk( KERN_INFO "%s : down_interruptible for write successed\n", msg );
  109    
  110        if ( buf_pos == MAXBUF ) {
  111            up( &chardev_sem );
  112            printk( KERN_INFO "%s : no space left\n", msg );
  113            return -ENOSPC;
  114        }
  115    
  116        if ( count > ( MAXBUF - buf_pos ) )
  117            copy_len = MAXBUF - buf_pos;
  118        else
  119            copy_len = count;
  120    
  121        if ( copy_from_user( devbuf + buf_pos, buf, copy_len ) ) {
  122            up( &chardev_sem );
  123            printk( KERN_INFO "%s : copy_from_user failed\n", msg );
  124            return -EFAULT;
  125        }
  126    
  127        *pos    += copy_len;
  128        buf_pos += copy_len;
  129    
  130        up( &chardev_sem );
  131        printk( KERN_INFO "%s : buf_pos = %d\n", msg, buf_pos );
  132    
  133        return copy_len;
  134    }
  135    
  136    
  137    static struct file_operations chardev_fops = 
  138    {
  139        owner   : THIS_MODULE,
  140        read    : chardev_read,
  141        write   : chardev_write,
  142        open    : chardev_open,
  143        release : chardev_release,
  144    };
  145    
  146    
  147    /*
  148     * ¥â¥¸¥å¡¼¥ë¤Î½é´ü½èÍý
  149     * insmod »þ¤Ë¸Æ¤Ð¤ì¤ë
  150     */
  151    int 
  152    init_module( void )
  153    {
  154        if ( register_chrdev( devmajor, devname, &chardev_fops ) ) {
  155            printk( KERN_INFO "%s : register_chrdev failed\n" );
  156            return -EBUSY;
  157        }
  158    
  159        sema_init( &chardev_sem, 1 );
  160        printk( KERN_INFO "%s : loaded  into kernel\n", msg );
  161    
  162        return 0;
  163    }
  164    
  165    
  166    /*
  167     * ¥â¥¸¥å¡¼¥ë¤Î²òÊü½èÍý
  168     * ¥â¥¸¥å¡¼¥ë¤Î»²¾È¿ô¤¬ 0 ¤Ç¤¢¤ì¤Ð¡¢rmmod »þ¤Ë¸Æ¤Ð¤ì¤ë
  169     */
  170    void 
  171    cleanup_module( void )
  172    {
  173        if ( unregister_chrdev( devmajor, devname ) ) {
  174            printk( KERN_INFO "%s : unregister_chrdev failed\n" );
  175            /* Âкö̵¤· ... */
  176        }
  177    
  178        printk( KERN_INFO "%s : removed from kernel\n", msg );
  179    }
  180    
  181    
  182    /* End of multiproc.c */

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

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

multiproc.c ¤Ï¡¢Á°²ó¤Î chardev.c ¤ò´ðËܤȤ·¤Æ¥¢¥¯¥»¥¹´ÉÍýÍÑÊÑ¿ô¤Ë¤è¤ë¥¢¥¯¥»¥¹¿ô¤Î´ÉÍý¥³¡¼¥É¤òºï½ü¤·¡¢read / write »þ¤Ë¥»¥Þ¥Õ¥©¤ò»È¤Ã¤¿ÇÓ¾À©¸æ¤ò¹Ô¤Ã¤Æ¤¤¤Þ¤¹¡£¤è¤Ã¤Æ¡¢Êѹ¹ÅÀ¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Þ¤¹¡£

  • 1 ¹ÔÌÜ

    ÇÓ¾À©¸æ¤Ë»ÈÍѤ¹¤ë¥»¥Þ¥Õ¥©¤Ë¤Ä¤¤¤Æ¤Î¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤·¤Æ¤¤¤Þ¤¹¡£

  • 23 ¹ÔÌÜ

    ÇÓ¾À©¸æÍѤΥ»¥Þ¥Õ¥©¹½Â¤ÂÎ chardev_sem ¤òÀë¸À¤·¤Æ¤¤¤Þ¤¹¡£ ¥»¥Þ¥Õ¥©¤Ë¤Ä¤¤¤Æ¤Ï¸å½Ò¤·¤Þ¤¹¡£

  • 26 ¡Á 34 ¹ÔÌÜ ( chardev_open )

    chardev.c ¤«¤é access_num ¤Ë´Ø¤¹¤ë¥³¡¼¥É¤òºï½ü¤·¤Æ¤¤¤Þ¤¹¡£

  • 37 ¡Á 45 ¹ÔÌÜ ( chardev_release )

    chardev_open ƱÍÍ¡¢access_num ¤Ë´Ø¤¹¤ë¥³¡¼¥É¤òºï½ü¤·¤Æ¤¤¤Þ¤¹¡£

  • 48 ¡Á 89 ¹ÔÌÜ ( chardev_read )

    Ê£¿ô¤Î¥×¥í¥»¥¹¤«¤éÊÂÎó¤Ë¼Â¹Ô¤µ¤ì¤ë²ÄǽÀ­¤¬¤¢¤ë¤¿¤á¡¢ ÆâÉô¥Ð¥Ã¥Õ¥¡¤òÁàºî¤¹¤ëÁ°¤Ë¥»¥Þ¥Õ¥©¤È¸Æ¤Ð¤ì¤ë¥í¥Ã¥¯¤ò¼èÆÀ¤·¤Æ¤¤¤Þ¤¹¡£

    Linux® ¤Ç¤Î¥»¥Þ¥Õ¥©¤Ï¡¢¥»¥Þ¥Õ¥©¤ÎÃͤ¬ 0 ¤è¤êÂ礭¤¤¤«¤É¤¦¤«¤ò¤Þ¤ºÄ´¤Ù¤Þ¤¹¡£ ¤â¤· 0 ¤è¤êÂ礭¤±¤ì¤Ð¡¢¥»¥Þ¥Õ¥©¤ÎÃͤò 1 ¸º¤é¤·¤Þ¤¹¡£0 ¤Ç¤¢¤ë¾ì¹ç¤Ï¡¢ ¥»¥Þ¥Õ¥©¤¬²òÊü¤µ¤ì¤ë¡Ê¥»¥Þ¥Õ¥©¤ÎÃͤ¬ 1 Áý¤¨¤ë¡Ë¤Þ¤ÇÂԤĤ³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£ ¥»¥Þ¥Õ¥©¤¬ÉÔÍפˤʤä¿»þÅÀ¤Ç²òÊü¡Ê¥»¥Þ¥Õ¥©¤ÎÃͤò 1 Áý¤ä¤¹¡Ë¤·¤Þ¤¹¡£

    ¤³¤ì¤é¤Ï¡¢down / down_interruptible ¤È¤¤¤¦´Ø¿ô¤ò¼Â¹Ô¤¹¤ë¤³¤È¤Ç ¼Â¸½¤Ç¤­¤Þ¤¹¡£

    #include <asm/semaphore.h>
    void down( struct semaphore* sem );
    int down_interruptible( struct semaphore* sem );
         

    down ¤È down_interruptible ¤Îº¹¤Ï¡¢¥»¥Þ¥Õ¥©¤Î¼èÆÀÂÔ¤Á¤Î´Ö¤Ë¥·¥°¥Ê¥ë ¤Ë¤è¤Ã¤Æ³ä¤ê¹þ¤à¤³¤È¤¬¤Ç¤­¤ë¤«¤É¤¦¤«¤Ç¤¹¡£¥·¥°¥Ê¥ë¤Ë¤è¤Ã¤Æ³ä¤ê¹þ¤á¤Ê¤¤¾ì¹ç¡¢ ²¾¤Ë¥»¥Þ¥Õ¥©¤¬²òÊü¤µ¤ì¤Ê¤¤¾ì¹ç¤Ï¼èÆÀÂÔ¤Á¤Î¤Þ¤Þ¤É¤¦¤¹¤ë¤³¤È¤â¤Ç¤­¤Ê¤¯¤Ê¤ê¤Þ¤¹¡£ ¤è¤Ã¤ÆÄ̾ï¤Ï down_interruptible ¤ò»ÈÍѤ·¤Þ¤¹¡£

    down_interruptible ¤¬À®¸ù¤·¤¿¤«¼ºÇÔ¤·¤¿¡Ê¥·¥°¥Ê¥ë¤Ë¤è¤Ã¤Æ³ä¤ê¹þ¤Þ¤ì¤¿¡Ë ¤«¤Ï¡¢down_interruptible ¤¬ 0 ¤òÊÖ¤·¤¿¡ÊÀ®¸ù¡Ë¤«¤½¤ì°Ê³°¤òÊÖ¤·¤¿¤« ¤Ë¤è¤Ã¤ÆȽÃǤ·¤Þ¤¹¡£¥·¥°¥Ê¥ë¤Ë¤è¤Ã¤Æ³ä¤ê¹þ¤Þ¤ì¤¿¾ì¹ç¤Ï¡¢- ERESTARTSYS ¤òÊÖ¤¹¤³¤È¤Ç¥«¡¼¥Í¥ë¤Ë³ä¤ê¹þ¤Þ¤ì¤¿¤³¤È¤òÄÌÃΤ·¤Æ½ªÎ»¤·¤Þ¤¹¡£

    ¥»¥Þ¥Õ¥©¤Î½é´üÃÍ¤Ï sema_init ¤È¤¤¤¦½é´ü²½´Ø¿ô¤Ë¤è¤Ã¤ÆÀßÄꤷ¤Þ¤¹¡£

    #include <asm/semaphore.h>
    void sema_init( struct semaphore* sem, int val );
         

    multiproc.c ¤Ç¤Ï¡¢init_module Æâ¤ÇÃͤò 1 ¤Ë½é´ü²½¤·¤Æ¤¤¤Þ¤¹¡£ ¤è¤Ã¤Æ multiproc.c ¤Ç¤Ï¡¢Æ±»þ¤Ë 1 ¥æ¡¼¥¶¥×¥í¥»¥¹¤¬ÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë ¥¢¥¯¥»¥¹¤Ç¤­¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£

    71¡¢81 ¹ÔÌÜ¤Ç¤Ï up ´Ø¿ô¤Ë¤è¤Ã¤Æ¼èÆÀ¤·¤¿¥»¥Þ¥Õ¥©¤ò²òÊü¤·¤Æ¤¤¤Þ¤¹¡£

    #include <asm/semaphore.h>
    void up( struct semaphore* sem );
         
  • 92 ¡Á 134 ¹ÔÌÜ ( chardev_write )

    chardev_read ƱÍÍ¡¢down_interruptible ¤Ë¤è¤Ã¤Æ¥»¥Þ¥Õ¥©¤ò¤Þ¤º¼èÆÀ ¤·¤Æ¤¤¤Þ¤¹¡£¤Þ¤¿¡¢½ªÎ»»þ¡ÊÀµ¾ï / ¼ºÇÔ¶¦¡Ë¤Ë¤Ï up ¤Ë¤è¤Ã¤Æ¥»¥Þ¥Õ¥©¤ò ²òÊü¤·¤Æ¤¤¤Þ¤¹¡£

  • 147 ¡Á 163 ¹ÔÌÜ ( init_module )

    sema_init ´Ø¿ô¤Ë¤è¤ê¡¢¥»¥Þ¥Õ¥©¤ò½é´ü²½¤·¤Æ¤¤¤Þ¤¹¡£1 ¤Ë½é´ü²½¤¹¤ë ¤³¤È¤Ç¡¢ÆâÉô¥Ð¥Ã¥Õ¥¡¤ËƱ»þ¤Ë¥¢¥¯¥»¥¹¤Ç¤­¤ë¥æ¡¼¥¶¥×¥í¥»¥¹¿ô¤ò 1 ¤ËÀ©¸Â¤·¤Æ¤¤¤Þ¤¹¡£

°Ê¾å¤Ç multiproc.c ¤Î²òÀâ¤Ï½ª¤ï¤ê¤Ç¤¹¡£°Ê¹ß¤Î¥­¥ã¥é¥¯¥¿¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤Î¥µ¥ó¥×¥ë¤Ï multiproc.c ¤ò´ðËܤȤ·¤Æ³ÈÄ¥¤·¤Æ¤¤¤­¤Þ¤¹¡£