LECTURE 2 ñ½ã¤Ê¥­¥ã¥é¥¯¥¿¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð

¡û ¤Ï¤¸¤á¤Ë

Linux® ( UNIX ) ¤Ç¤Î¥Ç¥Ð¥¤¥¹¤Î·Á¼°¤Ï¡¢Â礭¤¯°Ê²¼¤Ëʬ¤±¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£

  • ¥­¥ã¥é¥¯¥¿¥Ç¥Ð¥¤¥¹
  • ¥Ö¥í¥Ã¥¯¥Ç¥Ð¥¤¥¹
  • ¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹

¥­¥ã¥é¥¯¥¿¥Ç¥Ð¥¤¥¹¤È¤Ï¥Ç¡¼¥¿¤ò¥Ð¥¤¥Èñ°Ì¤Ç°·¤¦¥Ç¥Ð¥¤¥¹¤Ç¡¢/dev/ttyS0 ¤ä¥³¥ó¥½¡¼¥ëÅù¤ÏÂåɽŪ¤Ê¥­¥ã¥é¥¯¥¿¥Ç¥Ð¥¤¥¹¤Ç¤¹¡£¥Ö¥í¥Ã¥¯¥Ç¥Ð¥¤¥¹¤Ï¥Ç¡¼¥¿¤ò¥Ö¥í¥Ã¥¯¤È¸Æ¤Ð¤ì¤ë°ìÄꥵ¥¤¥º¤Î²ôñ°Ì¤Ç°·¤¦¥Ç¥Ð¥¤¥¹¤Ç¡¢¥Õ¥í¥Ã¥Ô¡¼¥Ç¥£¥¹¥¯¤ä¥Ï¡¼¥É¥Ç¥£¥¹¥¯¤¬ÂåɽŪ¤Ê¥Ö¥í¥Ã¥¯¥Ç¥Ð¥¤¥¹¤Ç¤¹¡£¥Í¥Ã¥È¥ï¡¼¥¯¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤Ï¡¢Ì¾Á°¤ÎÄ̤ê¥Í¥Ã¥È¥ï¡¼¥¯´ØÏ¢¤Î½èÍý¤ò¹Ô¤¦¥Ç¥Ð¥¤¥¹¤Ç¤¹¡£

¤³¤ì¤é°Ê³°¤Ë¤â SCSI Åù¤¤¤í¤¤¤í¤Ê¥Ç¥Ð¥¤¥¹¤¬¤¢¤ê¤Þ¤¹¤¬¡¢¤½¤ì¤é¤Ï¹½Â¤¤¬°Û¤Ê¤ë¤¿¤á¾åµ­¤ÎÍͤˤޤȤá¤ë¤³¤È¤¬½ÐÍè¤Ê¤¤ÍͤǤ¹¡£

¤³¤ì¤«¤é¤·¤Ð¤é¤¯¤Ï¡¢Èæ³ÓŪÁ´ÂÎÁü¤¬ÄϤߤ䤹¤¤¥­¥ã¥é¥¯¥¿¥Ç¥Ð¥¤¥¹¤òºî¤Ã¤Æ¤¤¤­¤¿¤¤¤È»×¤¤¤Þ¤¹¡£

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

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

gcc -DMODULE -D__KERNEL__ -O -c chardev.c

Á°²ó¤È°ã¤¤¡¢__KERNEL__ ¤ò¥³¥ó¥Ñ¥¤¥ë¥ª¥×¥·¥ç¥ó¤È¤·¤Æ»ØÄꤷ¤Æ¤¤¤Þ¤¹¡£¥«¡¼¥Í¥ë¥Ø¥Ã¥À¤ÎÃæ¤Ë¤Ï¡¢¥«¡¼¥Í¥ë¤Ç¤·¤«»²¾È¤·¤Ê¤¤Íͤʥǡ¼¥¿¹½Â¤Åù¤ò__KERNEL__ ¥Þ¥¯¥í¤ÇÊݸ¤Æ¤¤¤Þ¤¹¤¬¡¢¤½¤ì¤é¤Ë¥¢¥¯¥»¥¹¤¹¤ëɬÍפ¬¤¢¤ë¤«¤é¤Ç¤¹¡£¤³¤ì°Ê¹ß¤Î¥µ¥ó¥×¥ë¤Ç¤Ï¡¢É¬¤º»ØÄꤷ¤Þ¤¹¡£¤Ê¤ª¡¢¥½¡¼¥¹Ãæ¤Ëµ­½Ò¤¹¤ëºÝ¤Ë¤Ï¤É¤Î¥«¡¼¥Í¥ë¥Ø¥Ã¥À¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¤è¤ê¤âÀè¤ËÄêµÁ¤·¤Æ²¼¤µ¤¤¡£

¤Þ¤¿¡¢ºÇŬ²½¥ª¥×¥·¥ç¥ó -O ¤Ï¥¤¥ó¥é¥¤¥ó´Ø¿ô¤òŸ³«¤¹¤ë¤¿¤á¤Ë»ØÄꤷ¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤Ï¡¢¥«¡¼¥Í¥ëÆâ¤Î¿¤¯¤Î´Ø¿ô¤¬¥¤¥ó¥é¥¤¥ó´Ø¿ô¤È¤·¤ÆÄêµÁ¤µ¤ì¤Æ¤ª¤ê¡¢ºÇŬ²½¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Ê¤¤¤È¤½¤ì¤é¤¬Å¸³«¤µ¤ì¤Ê¤¤¤¿¤á¡¢¥³¥ó¥Ñ¥¤¥ë¤Ë¼ºÇÔ¤¹¤ë¤«¤é¤Ç¤¹¡£

chardev.c ¤Ï¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤é¤Î open / close / read / write ¤ËÂбþ¤·¤Æ¤¤¤Þ¤¹¤¬¡¢¤½¤ì¤¾¤ì¤ò¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤é¼Â¹Ô¤¹¤ë¤¿¤á¤Ë¥Ç¥Ð¥¤¥¹¥Õ¥¡¥¤¥ë¤òºîÀ®¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤È¥Ç¥Ð¥¤¥¹¥Õ¥¡¥¤¥ë¤Ï¡¢¥á¥¸¥ã¡¼ÈÖ¹æ¤È¥Þ¥¤¥Ê¡¼ÈÖ¹æ¤È¸Æ¤Ð¤ì¤ë¿ôÃͤǷë¤Ó¤Ä¤±¤é¤ì¤Þ¤¹¡Ê¥Ç¥Ð¥¤¥¹¥Õ¥¡¥¤¥ë̾¾Î¤Ï½Å¤Ê¤é¤Ê¤±¤ì¤Ð²¿¤Ç¤âÎɤ¤¡Ë¡£¥á¥¸¥ã¡¼ÈÖ¹æ¤Ç¥«¡¼¥Í¥ë¤¬¥É¥é¥¤¥Ð¤ò¶èÊ̤·¡¢¥Þ¥¤¥Ê¡¼ÈÖ¹æ¤Ç¥É¥é¥¤¥Ð¤¬¥Ç¥Ð¥¤¥¹¤ò¶èÊ̤·¤Þ¤¹¡£chardev.c ¤Ç¤Ï¥Þ¥¤¥Ê¡¼ÈÖ¹æ¤ò»ÈÍѤ·¤Ê¤¤¡ÊƱ¤¸¥É¥é¥¤¥Ð¤ÇÊ£¿ô¤Î¥Ç¥Ð¥¤¥¹¤ò°·¤¦¤ï¤±¤Ç¤Ï¤Ê¤¤¡Ë¤Î¤Ç¡¢¥á¥¸¥ã¡¼ÈÖ¹æ¤Î¤ß¤¬Âç»ö¤Ç¤¹¡£chardev.c ¤Î 13 ¹ÔÌܤǻÈÍѤ¹¤ë¥á¥¸¥ã¡¼ÈÖ¹æ¤ò 77 ¤ÈÄêµÁ¤·¤Æ¤¤¤Þ¤¹¡£¤â¤·¡¢³Æ¼«¤Î¥·¥¹¥Æ¥à¾å¤Ç»ÈÍѺѤߤÎÈÖ¹æ¤Ç¤¢¤ë¾ì¹ç¤Ï¡¢»È¤ï¤ì¤Æ¤¤¤Ê¤¤Ê̤ÎÈÖ¹æ¤ËÃÖ¤­´¹¤¨¤Æ²¼¤µ¤¤¡£¤Ê¤ª¡¢¥á¥¸¥ã¡¼ÈÖ¹æ¤ÏưŪ¤Ë³ä¤êÅö¤Æ¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¤¬¡¢¤³¤³¤Ç¤Ï¿¨¤ì¤Þ¤»¤ó¡£

¤³¤³¤Ç¤Ï¥Ç¥Ð¥¤¥¹¥Õ¥¡¥¤¥ë̾ /dev/chardev ¤ò»È¤¦¤³¤È¤Ë¤·¤Þ¤¹¡£¥Þ¥¤¥Ê¡¼ÈÖ¹æ¤Ï²¿¤Ç¤âÎɤ¤¤Î¤Ç 0 ¤Ë¤·¤Þ¤¹¡£°Ê²¼¤ÎÍͤˤ·¤Æ¥Ç¥Ð¥¤¥¹¥Õ¥¡¥¤¥ë¤òºîÀ®¤·¤Æ²¼¤µ¤¤ ( root ¤Ç¹Ô¤Ã¤Æ²¼¤µ¤¤ )¡£

mknod /dev/chardev c 77 0
chmod 0666 /dev/chardev

insmod ¤Ç¥â¥¸¥å¡¼¥ë¤òÁȤ߹þ¤ó¤À¸å¤Ï¡¢

echo "HELLO WORLD" > /dev/chardev

¤ÎÍͤˤ·¤Æ½ñ¤­¹þ¤ß¤ò¹Ô¤¤

cat /dev/chardev
HELLO WORLD

¤ÎÍͤˤ·¤Æ½ñ¤­¹þ¤ó¤ÀÆâÍƤòÆɤ߹þ¤à¤³¤È¤¬½ÐÍè¤Þ¤¹¡£ÄÌ»» 32 ¥Ð¥¤¥È°Ê¾å¤ò½ñ¤­¹þ¤â¤¦¤È¤¹¤ë¤È¡¢¥«¡¼¥Í¥ë¥í¥°¤Ë

<6>module [chardev.o] : no space left

¤ÎÍͤËɽ¼¨¤µ¤ì¤Þ¤¹¡£¤Ê¤ª¡¢/dev/chardev ¤Ï¡¢Æ±»þ¤Ë°ì¤Ä¤Î¥æ¡¼¥¶¥×¥í¥»¥¹¤·¤«»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤»¤ó¡£

--- chardev.c ---

    1    #include <asm/uaccess.h>    /* copy_from_user, copy_to_user */
    2    #include <linux/errno.h>
    3    #include <linux/fs.h>       /* inode, file, file_operations */
    4    #include <linux/kernel.h>   /* printk */
    5    #include <linux/module.h>
    6    #include <linux/spinlock.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 [chardev.o]";
   17    
   18    
   19    #define MAXBUF 32
   20    static unsigned char devbuf[ MAXBUF ];
   21    static int buf_pos;
   22    
   23    static int access_num;
   24    static spinlock_t chardev_spin_lock;
   25    
   26    
   27    /*
   28     * open()
   29     * 1¥æ¡¼¥¶¥×¥í¥»¥¹¤Î¤ß¤¬¥Ç¥Ð¥¤¥¹¥Õ¥¡¥¤¥ë¤Î open ¤ËÀ®¸ù¤¹¤ë¡£
   30     */
   31    static int 
   32    chardev_open( struct inode* inode, struct file* filp )
   33    {
   34        printk( KERN_INFO "%s : open()  called\n", msg );
   35    
   36        spin_lock( &chardev_spin_lock );
   37    
   38        if ( access_num ) {
   39            spin_unlock( &chardev_spin_lock );
   40            return -EBUSY;
   41        }
   42    
   43        access_num ++;
   44        spin_unlock( &chardev_spin_lock );
   45    
   46        return 0;
   47    }
   48    
   49    
   50    /*
   51     * release()
   52     * »ÈÍѥ桼¥¶¥×¥í¥»¥¹¿ô¤ò¥¯¥ê¥¢¤¹¤ë¡£
   53     */
   54    static int 
   55    chardev_release( struct inode* inode, struct file* filp )
   56    {
   57        printk( KERN_INFO "%s : close() called\n", msg );
   58    
   59        spin_lock( &chardev_spin_lock );
   60        access_num --;
   61        spin_unlock( &chardev_spin_lock );
   62    
   63        return 0;
   64    }
   65    
   66    
   67    /*
   68     * read()
   69     * ¥æ¡¼¥¶¥×¥í¥»¥¹¤ËÂФ·¤ÆÆâÉô¥Ð¥Ã¥Õ¥¡¤ÎÆâÍƤòžÁ÷¤¹¤ë¡£
   70     * žÁ÷¤·¤¿ÆâÍƤÏÆâÉô¥Ð¥Ã¥Õ¥¡¤«¤é¾Ã¤¨¤ë¡£
   71     */
   72    static ssize_t 
   73    chardev_read( struct file* filp, char* buf, size_t count, loff_t* pos )
   74    {
   75        int copy_len;
   76        int i;
   77    
   78        printk( KERN_INFO "%s : read()  called\n", msg );
   79    
   80        if ( count > buf_pos )
   81            copy_len = buf_pos;
   82        else
   83            copy_len = count;
   84    
   85        if ( copy_to_user( buf, devbuf, copy_len ) ) {
   86            printk( KERN_INFO "%s : copy_to_user failed\n", msg );
   87            return -EFAULT;
   88        }
   89    
   90        *pos += copy_len;
   91    
   92        for ( i = copy_len; i < buf_pos; i ++ )
   93            devbuf[ i - copy_len ] = devbuf[i];
   94    
   95        buf_pos -= copy_len;
   96        printk( KERN_INFO "%s : buf_pos = %d\n", msg, buf_pos );
   97    
   98        return copy_len;
   99    }
  100    
  101    
  102    /*
  103     * write()
  104     * ¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤éžÁ÷¤µ¤ì¤¿ÆâÍƤòÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë½ñ¤­¹þ¤à¡£
  105     */
  106    static ssize_t 
  107    chardev_write( 
  108        struct file* filp, const char* buf, size_t count, loff_t* pos )
  109    {
  110        int copy_len;
  111    
  112        printk( KERN_INFO "%s : write() called\n", msg );
  113    
  114        if ( buf_pos == MAXBUF ) {
  115            printk( KERN_INFO "%s : no space left\n", msg );
  116            return -ENOSPC;
  117        }
  118    
  119        if ( count > ( MAXBUF - buf_pos ) )
  120            copy_len = MAXBUF - buf_pos;
  121        else
  122            copy_len = count;
  123    
  124        if ( copy_from_user( devbuf + buf_pos, buf, copy_len ) ) {
  125            printk( KERN_INFO "%s : copy_from_user failed\n", msg );
  126            return -EFAULT;
  127        }
  128    
  129        *pos    += copy_len;
  130        buf_pos += copy_len;
  131    
  132        printk( KERN_INFO "%s : buf_pos = %d\n", msg, buf_pos );
  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        spin_lock_init( &chardev_spin_lock );
  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 chardev.c */

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

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

  • 1 ¡Á 6 ¹ÔÌÜ

    ɬÍפʥإåÀ¥Õ¥¡¥¤¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤·¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤é¤ÎÃæ¤Ë¤Ï¡¢ __KERNEL__ ¥Þ¥¯¥í¤ÇÆâÍƤòÊݸ¤Æ¤¤¤ë²Õ½ê¤¬¤¢¤ê¤Þ¤¹¤Î¤Ç¡¢ÀèƬ¤Ë __KERNEL__ ¤Èµ­½Ò¤¹¤ë¤«¥³¥ó¥Ñ¥¤¥ë¥¹¥¤¥Ã¥Á¤ÇÄêµÁ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

  • 9 ¡Á 11 ¹ÔÌÜ

    MODULE_AUTHOR ¤È MODULE_DESCRIPTION ¤Ï¡¢¤½¤ì¤¾¤ì¥â¥¸¥å¡¼¥ëºîÀ®¼Ô ¤ª¤è¤Ó¥â¥¸¥å¡¼¥ë¤Ë¤Ä¤¤¤Æ¤ÎÀâÌÀ¤ò¥«¡¼¥Í¥ë¥â¥¸¥å¡¼¥ëÆâ¤ËËä¤á¹þ¤à¤¿¤á¤Î ¥Þ¥¯¥í¤Ç¤¹¡£Æ°ºî¾åɬ¿Ü¤È¤¤¤¦¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£MODULE_LICENSE ¥Þ¥¯¥í¤Ë¤Ä¤¤¤Æ¤Ï¡¢Á°²ó¤ÎÀâÌÀÄ̤ê¤Ç¤¹¡£

  • 14 ¹ÔÌÜ

    chardev.c ¤Ç»ÈÍѤ¹¤ë¥á¥¸¥ã¡¼ÈÖ¹æ¤ò 77 È֤Ȥ·¤Æ¤¤¤Þ¤¹¡£Â¾¤ÎÈÖ¹æ¤ò »È¤¤¤¿¤¤»þ¤Ë¤Ï¡¢¤³¤³¤ò½ñ¤­´¹¤¨¤¿¾å¤ÇƱ¤¸ÈÖ¹æ¤ò»È¤Ã¤Æ mknod ¤Ç¥Ç¥Ð¥¤¥¹ ¥Õ¥¡¥¤¥ë¤òºîÀ®¤·¤Æ²¼¤µ¤¤¡£

  • 19 ¡Á 21 ¹ÔÌÜ

    ¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤é½ñ¤­¹þ¤Þ¤ì¤¿¥Ç¡¼¥¿¤òÊݸ¤·¡¢¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤é Æɤ߹þ¤á¤ëÍͤˤ¹¤ë¤¿¤á¤ÎÆâÉô¥Ð¥Ã¥Õ¥¡ 32 ¥Ð¥¤¥È¤òÀë¸À¤·¤Æ¤¤¤Þ¤¹¡£

  • 23 ¡Á 24 ¹ÔÌÜ

    Ʊ»þ¥¢¥¯¥»¥¹²Äǽ¥×¥í¥»¥¹¿ô¤ò´ÉÍý¤¹¤ë¤¿¤á¤ÎÊÑ¿ô¤Ç¤¹¡£chardev.c ¤Ç¤Ï¡¢ Ʊ»þ¤Ë 1 ¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤é¤Î¥¢¥¯¥»¥¹¤·¤«µö²Ä¤·¤Þ¤»¤ó¡£open ¤¬¼Â¹Ô¤µ¤ì¤¿ºÝ¤Ë access_num ¤¬ 0 ¤Ç¤Ê¤±¤ì¤Ð¡¢¤½¤ì°Ê¹ß¤ÎÁàºî¤ò¹Ô¤¨¤Ê¤¤Íͤˤ·¤Æ¤¤¤Þ¤¹¡£ ¤Þ¤¿¡¢SMP ¥·¥¹¥Æ¥àÍÑ¤Ë access_num ¤ÎÁàºî¤òÇÓ¾À©¸æ¤¹¤ë¤¿¤á¤Î¥í¥Ã¥¯ ÊÑ¿ô chardev_spin_lock ¤òÍÑ°Õ¤·¤Æ¤¤¤Þ¤¹¡£¥¹¥Ô¥ó¥í¥Ã¥¯¤Ë¤Ä¤¤¤Æ¤Ï¸å½Ò¤·¤Þ¤¹¡£

  • 27 ¡Á 47 ¹ÔÌÜ ( chardev_open )

    ¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤é¤Î open ¤ËÂбþ¤¹¤ë´Ø¿ô¤Ç¤¹¡£linux/fs.h Æâ¤Î struct file_operations ¤Î¥á¥ó¥Ð¤Ç¤¢¤ë open ´Ø¿ô¥Ý¥¤¥ó¥¿¤Î·Á¼°¤Ç ÄêµÁ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£À®¸ù»þ¤Ë¤Ï 0 ¤ò¡¢²¿¤é¤«¤Î¥¨¥é¡¼½ªÎ»»þ¤Ë¤Ï linux/errno.h Æâ¤ÎŬÀڤʥ¨¥é¡¼ÈÖ¹æ¤òÁª¤Ó¡¢Éé¤Î¿ôÃͤËÊÑ´¹¤·¤ÆÊֵѤ·¤Þ¤¹¡£ ¤³¤³¤Ç¤Ï¡¢access_num ¤¬ 0 ¤Ç¤Ê¤¤¡Ê´û¤Ë»ÈÍѤµ¤ì¤Æ¤¤¤ë¡Ë¾ì¹ç¤Ë¤Ï EBUSY ¤òÊÖ¤·¤Æ½ªÎ»¤·¤Æ¤¤¤Þ¤¹¡£

    access_num ¤ÎÁàºî¤ò¹Ô¤¦Á°¸å¤Ë¡¢spin_lock / spin_unlock ¤È¤¤¤¦½èÍý¤ò¼Â¹Ô¤·¤Æ¤¤¤Þ¤¹¡£SMP ¥·¥¹¥Æ¥à¤Î¾ì¹ç¤Ï¡¢access_num ¤Î 0 ¥Á¥§¥Ã¥¯¤È¼ÂºÝ¤ÎÁýʬ½èÍý¤Î´Ö¤ËÊÌ CPU ¤¬³ä¤ê¹þ¤à²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£ ¤½¤ì¤Ç¤ÏÌäÂ꤬¤¢¤ë¤¿¤á¡¢access_num ¤Î¥Á¥§¥Ã¥¯¤ª¤è¤ÓÁýʬ½èÍý¤ÎÁ°¤Ë ²¿¤é¤«¤Î¥í¥Ã¥¯¤ò¼èÆÀ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥í¥Ã¥¯¤Ë¤â¤¤¤í¤¤¤í¤¢¤ê¤Þ¤¹¤¬¡¢ ¤´¤¯Ã»»þ´Ö¤Î´Ö¤À¤±¥í¥Ã¥¯¤Ç¤­¤ì¤ÐÎɤ¤Íͤʾì¹ç¤Ë¤Ï¥¹¥Ô¥ó¥í¥Ã¥¯¤ò»È¤¤¤Þ¤¹¡£

    #include <linux/spinlock_h>
    spin_lock_init( spinlock_t* lock );
    spin_lock( spinlock_t* lock );
    spin_unlock( spinlock_t* lock );
         

    ¥¹¥Ô¥ó¥í¥Ã¥¯¤Ï¡¢¥í¥Ã¥¯¤ò¼èÆÀ¤¹¤ë¤Þ¤Ç¥Ó¥¸¡¼¥ë¡¼¥×¤ÇÂÔ¤Á¤Þ¤¹¡£ ¤Ê¤ª¡¢__SMP__ ¤òÄêµÁ¤»¤º¤Ë¥³¥ó¥Ñ¥¤¥ë¤·¤¿¾ì¹ç¡¢ ¥¹¥Ô¥ó¥í¥Ã¥¯¤Ï²¿¤â½èÍý¤·¤Þ¤»¤ó¡£¤Þ¤¿¡¢¥¹¥Ô¥ó¥í¥Ã¥¯¤ò»È¤¦ºÝ¤Ë¤Ï ¤¢¤é¤«¤¸¤á spin_lock_init ¤Ç½é´ü²½¤ò¹Ô¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡£chardev.c ¤Ç¤Ï init_module Æâ¤Ç¹Ô¤Ã¤Æ¤¤¤Þ¤¹¡£

  • 50 ¡Á 64 ¹ÔÌÜ ( chardev_release )

    ¥æ¡¼¥¶¥×¥í¥»¥¹¤È¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤Î´ØÏ¢ÉÕ¤±¤¬²òÊü¤µ¤ì¤ëºÝ¤Ë¼Â¹Ô¤µ¤ì¤Þ¤¹¡£ °ìÈÌŪ¤Ë¤Ï¥æ¡¼¥¶¥×¥í¥»¥¹¤¬ close ¤ò¼Â¹Ô¤·¤¿ºÝ¤Ë¼Â¹Ô¤µ¤ì¤Þ¤¹¤¬¡¢ ¥æ¡¼¥¶¥×¥í¥»¥¹¤¬¥¨¥é¡¼½ªÎ»¤·¤Æ¤·¤Þ¤Ã¤¿ºÝ¤Ê¤É¤Ë¤â¼Â¹Ô¤µ¤ì¤ë¤³¤È¤Ç¡¢ »ñ¸»¤¬²òÊü¤µ¤ì¤Þ¤¹¡£linux/fs.h Æâ¤Î struct file_operations ¤Î¥á¥ó¥Ð¤Ç¤¢¤ë release ´Ø¿ô¥Ý¥¤¥ó¥¿¤Î·Á¼°¤ÇÄêµÁ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ ÊÖµÑÃͤˤĤ¤¤Æ¤Ï chardev_open ¤ÈƱ¤¸¤Ç¤¹¡£¤³¤³¤Ç¤Ï access_num ¤ò¥Ç¥¯¥ê¥á¥ó¥È¤·¤Æ¤¤¤ë¤À¤±¤Ê¤Î¤Ç¡¢¾ï¤Ë 0 ¤òÊÖ¤·¤Þ¤¹¡£

    access_num Áàºî¤ÎÁ°¸å¤Ç¥¹¥Ô¥ó¥í¥Ã¥¯¤Î½èÍý¤ò¤·¤Æ¤¤¤Þ¤¹¤¬¡¢ chardev.c ¤Î¾ì¹ç¤Ï¼ÂºÝ¤Ë¤Ï¥¹¥Ô¥ó¥í¥Ã¥¯¤ò¼èÆÀ¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£

  • 67 ¡Á 99 ¹ÔÌÜ ( chardev_read )

    ¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤é¤Î read ¤ËÂбþ¤¹¤ë´Ø¿ô¤Ç¤¹¡£linux/fs.h Æâ¤Î struct file_operations ¤Î¥á¥ó¥Ð¤Ç¤¢¤ë read ´Ø¿ô¥Ý¥¤¥ó¥¿¤Î·Á¼°¤ÇÄêµÁ¤¹¤ë ɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥¨¥é¡¼½ªÎ»»þ¤ÎÊÖµÑÃͤËÂФ·¤Æ¤Ï chardev_open ¤ÈƱ¤¸¤Ç¤¹¡£ Àµ¾ï½ªÎ»»þ¤Ï¡¢¥æ¡¼¥¶¥×¥í¥»¥¹¤ËÊÖ¤¹¥Ç¡¼¥¿¤Î¥Ð¥¤¥È¿ô¤òÊÖ¤·¤Þ¤¹¡£

    °ú¿ô¤Î buf ¤¬·ë²Ì¤ò³ÊǼ¤¹¤ë¤¿¤á¤Î¥æ¡¼¥¶¶õ´Ö¤Î¥Ð¥Ã¥Õ¥¡¤Ç¡¢count ¤¬Í׵ᤵ¤ì¤¿ÆɤߤÀ¤·¥Ð¥¤¥È¿ô¤Ç¤¹¡£¤³¤³¤Ç¤Ï¡¢count ¤¬¸½ºß¤Î³ÊǼ¥Ð¥¤¥È¿ô ¤è¤êÂ礭¤¤¾ì¹ç¤ÏÆâÉô¥Ð¥Ã¥Õ¥¡¥µ¥¤¥º¤Î¡¢¤½¤ì°Ê³°¤Ï count ¥Ð¥¤¥È¤Î¥Ç¡¼¥¿¤ò ¥æ¡¼¥¶¥×¥í¥»¥¹¤ËÊÖ¤·¤Æ¤¤¤Þ¤¹¡£¥«¡¼¥Í¥ë¶õ´Ö¤È¥æ¡¼¥¶¥×¥í¥»¥¹¶õ´Ö¤Ç¤Ï ¥¢¥É¥ì¥¹ÂηϤ¬°Û¤Ê¤ë¤¿¤á¡¢Ã±¤Ë buf ¤Ë¥³¥Ô¡¼¤¹¤ë¤ï¤±¤Ë¤Ï¤¤¤­¤Þ¤»¤ó¡£ ¤³¤Î¾ì¹ç¡¢copy_to_user ¤È¤¤¤¦´Ø¿ô¤ò»È¤¤¤Þ¤¹¡£

    #include <asm/uaccess.h>
    unsigned long copy_to_user( void* to, const void* from, unsigned long count );
    
    

    to ¤Ë¥³¥Ô¡¼À襢¥É¥ì¥¹¡¢from ¤Ë¥³¥Ô¡¼¸µ¥¢¥É¥ì¥¹¤ò»ØÄꤷ¤Þ¤¹¡£¤Þ¤¿¡¢ count ¤Ë¥³¥Ô¡¼¤¹¤ë¥Ð¥¤¥È¿ô¤ò»ØÄꤷ¤Þ¤¹¡£Ìá¤êÃͤϥ³¥Ô¡¼¤µ¤ì¤Æ¤¤¤Ê¤¤ ¥Ð¥¤¥È¿ô¤Ç¤¢¤ë¤¿¤á¡¢Àµ¾ï¤Ë½ªÎ»¤·¤¿¾ì¹ç¤Ï 0 ¤¬ÊÖ¤ê¤Þ¤¹¡£

    ¥³¥Ô¡¼¤·¤¿¸å¤Ï¡¢¥³¥Ô¡¼¤·¤¿¥Ç¡¼¥¿Ä¹¤Ë±þ¤¸¤ÆÆâÉô¥Ð¥Ã¥Õ¥¡Æâ¤Î¥Ç¡¼¥¿¤ò ÀèƬ¤ËµÍ¤á¤Æ¤¤¤Þ¤¹¡£¤Ê¤ª¡¢chardev.c ¤Ï read ¼Â¹Ô»þ¤ËÊÖ¤¹¥Ç¡¼¥¿¤¬Ìµ¤¤¾ì¹ç¤Ç¤â ¥Ö¥í¥Ã¥¯¤¹¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£¥Ö¥í¥Ã¥¯ I/O ¤Ë¤Ä¤¤¤Æ¤Ïº£¸å¿¨¤ì¤ëͽÄê ¤Ç¤¹¡£

    ¤Ê¤ª¡¢ºÇ½é¤Î°ú¿ô¤Ç¤¢¤ë struct file* filp ¤Ï¡¢¥ª¡¼¥×¥ó¤µ¤ì¤Æ¤¤¤ë ¥Õ¥¡¥¤¥ë¾ðÊ󤬳ÊǼ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£Î㤨¤Ð¡¢¥Õ¥¡¥¤¥ë¤ÎÆɤ߽ñ¤­¥â¡¼¥É¤ä¸½ºß¤Î¥Ý¥¤¥ó¥¿°ÌÃÖ ¤È¤¤¤Ã¤¿ÆâÍƤ¬³ÊǼ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤Þ¤¿¡¢ºÇ¸å¤Î°ú¿ô¤Ç¤¢¤ë loff_t* pos ¤Ï¡¢¸½ºß¥¢¥¯¥»¥¹¤·¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¤Î°ÌÃ֤Ǥ¹¡£¥³¥Ô¡¼Ä¾¸å¤Ë¡¢¥³¥Ô¡¼Ä¹¤À¤±¿Ê¤á¤Æ¤¤¤Þ¤¹¡£ °ÌÃÖ¤¬ÌäÂê¤È¤Ê¤ë¥Ç¡¼¥¿¤ò°·¤¦¥É¥é¥¤¥Ð¤Î¾ì¹ç¤Ï¡¢¤³¤ÎÃͤ¬¼¨¤¹¾ì½ê¤«¤é¤Î¥Ç¡¼¥¿¤ò ÊÖ¤¹É¬Íפ¬¤¢¤ê¤Þ¤¹¡£

  • 102 ¡Á 134 ¹ÔÌÜ ( chardev_write )

    ¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤é¤Î write ¤ËÂбþ¤¹¤ë´Ø¿ô¤Ç¤¹¡£linux/fs.h Æâ¤Î struct file_operations ¤Î¥á¥ó¥Ð¤Ç¤¢¤ë write ´Ø¿ô¥Ý¥¤¥ó¥¿¤Î·Á¼°¤ÇÄêµÁ¤¹¤ë ɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥¨¥é¡¼½ªÎ»»þ¤ÎÊÖµÑÃͤËÂФ·¤Æ¤Ï chardev_open ¤ÈƱ¤¸¤Ç¤¹¡£Àµ¾ï½ªÎ»»þ¤Ï¡¢¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤é½ñ¤­¹þ¤Þ¤ì¤¿¥Ç¡¼¥¿¤Î¥Ð¥¤¥È¿ô¤òÊÖ¤·¤Þ¤¹¡£

    °ú¿ô¤Î buf ¤¬ÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë³ÊǼ¤¹¤ë¤¿¤á¤Î¥Ç¡¼¥¿¤òɽ¤¹¥æ¡¼¥¶¶õ´Ö¤Î¥Ð¥Ã¥Õ¥¡¤Ç¡¢ count ¤¬Í׵ᤵ¤ì¤¿½ñ¤­¹þ¤ß¥Ð¥¤¥È¿ô¤Ç¤¹¡£¤³¤³¤Ç¤Ï¡¢ÆâÉô¥Ð¥Ã¥Õ¥¡¤Î ¶õ¤­¥Ð¥¤¥È¿ô¤À¤± buf ¤«¤é¥Ç¡¼¥¿¤òÆɤ߹þ¤ß¡¢ÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë½ñ¤­¹þ¤ó¤Ç¤¤¤Þ¤¹¡£ ÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë¶õ¤­¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢ENOSPC ¤òÊÖ¤·¤Æ¤¤¤Þ¤¹¡£

    ¤³¤³¤Ç¤âñ¤Ë buf ¤«¤é¥³¥Ô¡¼¤¹¤ë¤ï¤±¤Ë¤Ï¤¤¤­¤Þ¤»¤ó¡£¤³¤Î¾ì¹ç¡¢ copy_from_user ¤È¤¤¤¦´Ø¿ô¤ò»È¤¤¤Þ¤¹¡£

    #include <asm/uaccess.h>
    unsigned long copy_from_user( void* to, const void* from, unsigned long count );
    
    

    to ¤Ë¥³¥Ô¡¼À襢¥É¥ì¥¹¡¢from ¤Ë¥³¥Ô¡¼¸µ¥¢¥É¥ì¥¹¤ò»ØÄꤷ¤Þ¤¹¡£¤Þ¤¿¡¢ count ¤Ë¥³¥Ô¡¼¤¹¤ë¥Ð¥¤¥È¿ô¤ò»ØÄꤷ¤Þ¤¹¡£Ìá¤êÃͤϥ³¥Ô¡¼¤µ¤ì¤Æ¤¤¤Ê¤¤ ¥Ð¥¤¥È¿ô¤Ç¤¢¤ë¤¿¤á¡¢Àµ¾ï¤Ë½ªÎ»¤·¤¿¾ì¹ç¤Ï 0 ¤¬ÊÖ¤ê¤Þ¤¹¡£

    filp¡¢pos ¤Ë¤Ä¤¤¤Æ¤Ï chardev_read ¤ÈƱÍͤǤ¹¡£

  • 137 ¡Á 144 ¹ÔÌÜ

    ¥â¥¸¥å¡¼¥ëÆâ¤Î³Æ´Ø¿ô¤È¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤é¤ÎÁàºî¤ò´ØÏ¢ÉÕ¤±¤ë¤¿¤á¤Ë¤Ï¡¢ linux/fs.h Æâ¤Î struct file_operations ·¿¹½Â¤ÂΤòºîÀ®¤·¡¢¥«¡¼¥Í¥ë¤Ë ÅÐÏ¿¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥«¡¼¥Í¥ë 2.4.19 ¤Î linux/fs.h ¤Ç¤Ï¡¢ °Ê²¼¤ÎÍͤËÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

    struct file_operations {
        struct module *owner;
        loff_t (*llseek) (struct file *, loff_t, int);
        ssize_t (*read) (struct file *, char *, size_t, loff_t *);
        ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
        int (*readdir) (struct file *, void *, filldir_t);
        unsigned int (*poll) (struct file *, struct poll_table_struct *);
        int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
        int (*mmap) (struct file *, struct vm_area_struct *);
        int (*open) (struct inode *, struct file *);
        int (*flush) (struct file *);
        int (*release) (struct inode *, struct file *);
        int (*fsync) (struct file *, struct dentry *, int datasync);
        int (*fasync) (int, struct file *, int);
        int (*lock) (struct file *, int, struct file_lock *);
        ssize_t (*readv) (
            struct file *, const struct iovec *, unsigned long, loff_t *);
        ssize_t (*writev) (
            struct file *, const struct iovec *, unsigned long, loff_t *);
        ssize_t (*sendpage) (
            struct file *, struct page *, int, size_t, loff_t *, int);
        unsigned long (*get_unmapped_area)(struct file *, 
            unsigned long, unsigned long, unsigned long, unsigned long);
    };
    

    ¤³¤ÎÃæ¤Ç¡¢´ØÏ¢ÉÕ¤±¤ò¹Ô¤¤¤¿¤¤¥á¥ó¥Ð¤Ë´Ø¿ô¥Ý¥¤¥ó¥¿¤òÀßÄꤷ¡¢Â¾¤Î¥á¥ó¥Ð¤Ë¤Ï NULL ¤òÀßÄꤷ¤Þ¤¹¡£ ¤¿¤À¤·¾åµ­¤Î¥á¥ó¥Ð¤ÎÃæ¤Ç struct module * owner ¥á¥ó¥Ð¤Ï¡¢ ¥Õ¥¡¥¤¥ëÁàºî¤È¤Î´ØÏ¢ÉÕ¤±¤ò¹Ô¤¦¤¿¤á¤Î´Ø¿ô¥Ý¥¤¥ó¥¿¤Ç¤Ï¤Ê¤¯¡¢ ¥«¡¼¥Í¥ë¥â¥¸¥å¡¼¥ë¼«¿È¤Î¾ðÊó¤ò³ÊǼ¤¹¤ë¤¿¤á¤Î¥á¥ó¥Ð¤Ç¤¹¡£ ¤½¤Î¤¿¤á¡¢ÊÌÅÓ½é´ü²½¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥«¡¼¥Í¥ë 2.4 ¤Ç¤Ï¡¢THIS_MODULE ¤È¤¤¤¦Ãͤǽé´ü²½¤¹¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£

    chardev.c ¤Ç¤Ï¡¢Á´¥á¥ó¥Ð¤ËÃͤòÀßÄꤹ¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢gcc ¤Î³ÈÄ¥µ¡Ç½ ¤Ç¤¢¤ë¹½Â¤ÂΤΥ¿¥°ÉÕ¤­½é´ü²½¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£"¥á¥ó¥Ð̾ :" ¤È¤¤¤¦¥é ¥Ù¥ë¤Ë³¤±¤ÆÃͤòµ­½Ò¤·¤Æ¤¤¤­¤Þ¤¹¡£¤³¤ÎÍͤˤ¹¤ë¤È¡¢É¬Íפʲսê¤À¤±Àß Äꤹ¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£

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

    ¼«Ê¬¼«¿È¤ò¥­¥ã¥é¥¯¥¿¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤È¤·¤Æ¥«¡¼¥Í¥ë¤ËÅÐÏ¿¤¹¤ë¤¿¤á¤Ë¡¢ register_chrdev ¤ò¼Â¹Ô¤·¤Æ¤¤¤Þ¤¹¡£

    #include <linux/fs.h>
    int register_chrdev( 
        unsigned int major, const char* name, struct file_operations* fops );
    
    

    major ¤Ï¥á¥¸¥ã¡¼Èֹ桢name ¤ÏǤ°Õ¤Î¥É¥é¥¤¥Ð̾¾Î¡¢fops ¤Ï¥Õ¥¡¥¤¥ëÁàºî¤È´Ø¿ô¤Î´ØÏ¢¥Æ¡¼¥Ö¥ë¤Î¥¢¥É¥ì¥¹¤Ç¤¹¡£ ÊÖ¤êÃͤ¬Éé¤Î¾ì¹ç¤Ï¥¨¥é¡¼½ªÎ»¤Ç¤¹¡£major ¤Ë 0 °Ê³°¤ò»ØÄꤷ¤ÆÀµ¾ï¤Ë½ªÎ» ¤·¤¿¾ì¹ç¤Ï 0 ¤¬ÊÖ¤ê¤Þ¤¹¡£¤Þ¤¿ major ¤Ë 0 ¤ò»ØÄꤷ¤¿¾ì¹ç¤Ï ¥á¥¸¥ã¡¼ÈÖ¹æ¤ÎưŪ³ä¤êÅö¤Æ¤¬¹Ô¤ï¤ì¡¢¼ÂºÝ¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥á¥¸¥ã¡¼Èֹ椬ÊÖ¤ê¤Þ¤¹¡£

    ¤Þ¤¿¡¢spin_lock_init ¤Ë¤è¤Ã¤Æ¥¹¥Ô¥ó¥í¥Ã¥¯¤Î½é´ü²½¤ò¹Ô¤Ã¤Æ¤¤¤Þ¤¹¡£

  • 166 ¡Á 179 ¹ÔÌÜ ( cleanup_module )

    ¥«¡¼¥Í¥ë¤ËÅÐÏ¿¤µ¤ì¤Æ¤¤¤ë¾ðÊó¤òºï½ü¤¹¤ë¤¿¤á¤Ë¡¢unregister_chrdev ¤ò¼Â¹Ô¤·¤Æ¤¤¤Þ¤¹¡£

    #include <linux/fs.h>
    int unregister_chrdev( unsigned int major, const char* name );
    
    

    major ¤ÏÅÐÏ¿»þ¤Ë»ØÄꤷ¤¿¥á¥¸¥ã¡¼Èֹ桢name ¤ÏÅÐÏ¿»þ¤Ë»ØÄꤷ¤¿ ¥Ç¥Ð¥¤¥¹Ì¾¾Î¤Ç¤¹¡£Àµ¾ï½ªÎ»»þ¤Ï 0¡¢¤½¤ì°Ê³°¤Ï¥¨¥é¡¼½ªÎ»¤Ç¤¹¡£

°Ê¾å¤Ç chardev.c ¤Î²òÀâ¤Ï½ª¤ï¤ê¤Ç¤¹¡£open / close / read / write ¤È¤¤¤¦´ðËÜŪ¤Ê¥Õ¥¡¥¤¥ëÁàºî¤ËÂбþ¤·¤Æ¤ß¤Þ¤·¤¿¤¬¡¢¤½¤ì¤À¤±¤Ç¤âΩÇÉ¤Ê ¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤Ë¸«¤¨¤Æ¤·¤Þ¤¤¤Þ¤¹¡ª¡ÊÁàºî¤·¤Æ¤¤¤ë¥Ï¡¼¥É¥¦¥§¥¢¤Ï¥á¥â¥ê¤À¤±¤Ç¤¹¤¬¡£¡£¡£¡Ë

º£¸å¤Ï¡¢¾¯¤·¤Å¤Ä³ÆÁàºî¤ò³ÈÄ¥¤·¤Æ¤¤¤­¤¿¤¤¤È»×¤¤¤Þ¤¹¡£