|
¡û ¤Ï¤¸¤á¤Ë
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 ¤ò´ðËܤȤ·¤Æ³ÈÄ¥¤·¤Æ¤¤¤¤Þ¤¹¡£