|
¡û ¤Ï¤¸¤á¤Ë
multiproc.c ¤Ç¤Ï¡¢read »þ¤ËÆɤ߹þ¤á¤ë¥Ç¡¼¥¿¤¬Â¸ºß¤·¤Ê¤¤¡¢¤¢¤ë¤¤¤Ï write »þ¤Ë½ñ¤¹þ¤à¥¹¥Ú¡¼¥¹¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Ï¨ºÂ¤Ë½èÍý½ªÎ»¤·¤Æ¤¤¤Þ¤·¤¿¡£
º£²ó¤Ï¤½¤ÎÍͤʾì¹ç¤Ë¨ºÂ¤Ë½ªÎ»¤¹¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢Â¾¤Î¥×¥í¥»¥¹¤Ë¤è¤ë¥Ç¡¼¥¿¤ÎÆɤ߽ñ¤¤¬¹Ô¤ï¤ì¤ë¤Þ¤ÇÂÔµ¡¤¹¤ë¥Ö¥í¥Ã¥¯ I/O ¤ò¼ÂÁõ¤·¤Þ¤¹¡£
¡û ¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à
¥Ö¥í¥Ã¥¯ I/O ( read / write ) ¤ËÂбþ¤·¤¿¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à block.c ¤Ç¤¹¡£ ¤Ï¤¸¤á¤Ë ¤Î¥Ú¡¼¥¸¤«¤é¡¢ Á´¤Æ¤Î¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤ò ¸Ç¤á¤¿ tar ¥Ü¡¼¥ë¤ò¥À¥¦¥ó¥í¡¼¥É¤¹¤ë¤³¤È¤â¤Ç¤¤Þ¤¹¡£
echo "HELLO WORLD" > /dev/chardev
¤ÎÍͤˤ·¤Æ½ñ¤¹þ¤ß¤ò¹Ô¤Ã¤¿ºÝ¤ËÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë¶õ¤¤¬Ìµ¤¤¤È¡¢Â¾¥×¥í¥»¥¹¤Ç
cat /dev/chardev HELLO WORLD
¤ÎÍͤˤ·¤ÆÆâÉô¥Ð¥Ã¥Õ¥¡¤ÎÆâÍƤò¼è¤ê½Ð¤¹¤Þ¤Ç¡¢½ñ¤¹þ¤ß¤ò¹Ô¤ª¤¦¤È¤·¤¿¥×¥í¥»¥¹¤ÏÂÔ¤Á¾õÂ֤ˤʤê¤Þ¤¹¡£ÆâÉô¥Ð¥Ã¥Õ¥¡¤ÎÆâÍƤ¬¼è¤ê½Ð¤µ¤ì¤Æ¶õ¤¤¬½ÐÍè¤ë¤ÈƱ»þ¤Ë¡¢½ñ¤¹þ¤ß¥×¥í¥»¥¹¤¬Æ°ºî¤·»Ï¤á¤Þ¤¹¡£
È¿ÂФˡ¢cat Åù¤ÇÆɤ߹þ¤â¤¦¤È¤·¤¿ºÝ¤ËÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë¥Ç¡¼¥¿¤¬Ìµ¤¤¾ì¹ç¡¢Æɤ߹þ¤ß¥×¥í¥»¥¹¤ÏÂÔ¤Á¾õÂ֤ˤʤê¤Þ¤¹¡£ÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë¥Ç¡¼¥¿¤¬½ñ¤¹þ¤Þ¤ì¤ë¤ÈƱ»þ¤Ë¡¢Æɤ߹þ¤ß¥×¥í¥»¥¹¤¬Æ°ºî¤·»Ï¤á¤Þ¤¹¡£
C ¸À¸ìÅù¤ÇÈó¥Ö¥í¥Ã¥¯»ØÄê¤Ç /dev/chardev ¤ò open ¤·¤¿¾ì¹ç¤Ï¡¢¾åµ¤ÎÍͤʾì¹ç¤ËÂÔ¤Á¾õÂ֤ˤʤë¤Î¤Ç¤Ï¤Ê¤¯¡¢Â¨ºÂ¤ËÆɤ߹þ¤ß¡¢½ñ¤¹þ¤ß½èÍý¤¬½ªÎ»¤·¤Þ¤¹¡£¤½¤ÎºÝ read / write ¥·¥¹¥Æ¥à¥³¡¼¥ë¤Ï -1 ¤òÊÖ¤·¡¢errno ¤Ë¤Ï EBUSY ¤¬ÀßÄꤵ¤ì¤Þ¤¹¡£
--- block.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 #include <linux/wait.h> /* wait_queue_head_t */ 8 #include <linux/sched.h> /* wait_event_interruptible, wake_up_interruptible */ 9 10 11 MODULE_AUTHOR( "Ryo" ); 12 MODULE_DESCRIPTION( "Sample character device driver." ); 13 MODULE_LICENSE( "GPL" ); 14 15 16 static int devmajor = 77; 17 static char* devname = "chardev"; 18 static char* msg = "module [block.o]"; 19 20 21 #define MAXBUF 32 22 static unsigned char devbuf[ MAXBUF ]; 23 static int buf_pos; 24 25 static struct semaphore chardev_sem; 26 static wait_queue_head_t write_q; 27 static wait_queue_head_t read_q; 28 29 30 /* 31 * ¥í¥°½ÐÎÏ¥Õ¥©¡¼¥Þ¥Ã¥ÈÍÑ´Ø¿ô 32 */ 33 static void 34 log_format( char* body ) 35 { 36 if ( current != NULL ) { 37 printk( KERN_INFO "%s : PID = %-5i cmdline = \"%-10s\" : %s\n", 38 msg, current->pid, current->comm, body ); 39 } 40 else { 41 printk( KERN_INFO "%s : %s\n", msg, body ); 42 } 43 } 44 45 46 /* 47 * open() 48 */ 49 static int 50 chardev_open( struct inode* inode, struct file* filp ) 51 { 52 log_format( "open() called" ); 53 return 0; 54 } 55 56 57 /* 58 * release() 59 */ 60 static int 61 chardev_release( struct inode* inode, struct file* filp ) 62 { 63 log_format( "close() called" ); 64 return 0; 65 } 66 67 68 /* 69 * read() 70 * ¥æ¡¼¥¶¥×¥í¥»¥¹¤ËÂФ·¤ÆÆâÉô¥Ð¥Ã¥Õ¥¡¤ÎÆâÍƤòžÁ÷¤¹¤ë¡£ 71 * žÁ÷¤·¤¿ÆâÍƤÏÆâÉô¥Ð¥Ã¥Õ¥¡¤«¤é¾Ã¤¨¤ë¡£ 72 */ 73 static ssize_t 74 chardev_read( struct file* filp, char* buf, size_t count, loff_t* pos ) 75 { 76 int copy_len; 77 int i; 78 79 log_format( "read() called" ); 80 81 if ( down_interruptible( &chardev_sem ) ) { 82 log_format( "down_interruptible for read failed" ); 83 return -ERESTARTSYS; 84 } 85 86 while ( buf_pos == 0 ) { 87 up( &chardev_sem ); 88 89 if ( filp->f_flags & O_NONBLOCK ) { 90 log_format( "read return because O_NONBLOCK is specified" ); 91 return -EAGAIN; 92 } 93 94 log_format( "read process going to sleep" ); 95 96 if ( wait_event_interruptible( read_q, ( buf_pos != 0 ) ) ) 97 return -ERESTARTSYS; 98 99 if ( down_interruptible( &chardev_sem ) ) { 100 log_format( "down_interruptible for read failed" ); 101 return -ERESTARTSYS; 102 } 103 } 104 105 106 log_format( "read process going to read" ); 107 108 if ( count > buf_pos ) 109 copy_len = buf_pos; 110 else 111 copy_len = count; 112 113 if ( copy_to_user( buf, devbuf, copy_len ) ) { 114 up( &chardev_sem ); 115 log_format( "copy_to_user failed" ); 116 return -EFAULT; 117 } 118 119 *pos += copy_len; 120 121 for ( i = copy_len; i < buf_pos; i ++ ) 122 devbuf[ i - copy_len ] = devbuf[i]; 123 124 buf_pos -= copy_len; 125 126 up( &chardev_sem ); 127 wake_up_interruptible( &write_q ); 128 129 return copy_len; 130 } 131 132 133 /* 134 * write() 135 * ¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤éžÁ÷¤µ¤ì¤¿ÆâÍƤòÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë½ñ¤¹þ¤à¡£ 136 */ 137 static ssize_t 138 chardev_write( struct file* filp, const char* buf, size_t count, loff_t* pos ) 139 { 140 int copy_len; 141 142 log_format( "write() called" ); 143 144 if ( down_interruptible( &chardev_sem ) ) { 145 log_format( "down_interruptible for write failed" ); 146 return -ERESTARTSYS; 147 } 148 149 while ( buf_pos == MAXBUF ) { 150 up( &chardev_sem ); 151 152 if ( filp->f_flags & O_NONBLOCK ) { 153 log_format( "write return because O_NONBLOCK is specified" ); 154 return -EAGAIN; 155 } 156 157 log_format( "write process going to sleep" ); 158 159 if ( wait_event_interruptible( write_q, ( buf_pos != MAXBUF ) ) ) 160 return -ERESTARTSYS; 161 162 if ( down_interruptible( &chardev_sem ) ) { 163 log_format( "down_interruptible for write failed" ); 164 return -ERESTARTSYS; 165 } 166 } 167 168 169 log_format( "write process going to write" ); 170 171 if ( count > ( MAXBUF - buf_pos ) ) 172 copy_len = MAXBUF - buf_pos; 173 else 174 copy_len = count; 175 176 if ( copy_from_user( devbuf + buf_pos, buf, copy_len ) ) { 177 up( &chardev_sem ); 178 log_format( "copy_from_user failed" ); 179 return -EFAULT; 180 } 181 182 *pos += copy_len; 183 buf_pos += copy_len; 184 185 up( &chardev_sem ); 186 wake_up_interruptible( &read_q ); 187 188 return copy_len; 189 } 190 191 192 static struct file_operations chardev_fops = 193 { 194 owner : THIS_MODULE, 195 read : chardev_read, 196 write : chardev_write, 197 open : chardev_open, 198 release : chardev_release, 199 }; 200 201 202 /* 203 * ¥â¥¸¥å¡¼¥ë¤Î½é´ü½èÍý 204 * insmod »þ¤Ë¸Æ¤Ð¤ì¤ë 205 */ 206 int 207 init_module( void ) 208 { 209 if ( register_chrdev( devmajor, devname, &chardev_fops ) ) { 210 log_format( "register_chrdev failed" ); 211 return -EBUSY; 212 } 213 214 sema_init( &chardev_sem, 1 ); 215 216 init_waitqueue_head( &write_q ); 217 init_waitqueue_head( &read_q ); 218 219 log_format( "loaded into kernel" ); 220 return 0; 221 } 222 223 224 /* 225 * ¥â¥¸¥å¡¼¥ë¤Î²òÊü½èÍý 226 * ¥â¥¸¥å¡¼¥ë¤Î»²¾È¿ô¤¬ 0 ¤Ç¤¢¤ì¤Ð¡¢rmmod »þ¤Ë¸Æ¤Ð¤ì¤ë 227 */ 228 void 229 cleanup_module( void ) 230 { 231 if ( unregister_chrdev( devmajor, devname ) ) { 232 log_format( "unregister_chrdev failed" ); 233 /* Âкö̵¤· ... */ 234 } 235 236 log_format( "removed from kernel" ); 237 } 238 239 240 /* End of block.c */
¡û ¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤ÎÀâÌÀ
¤Ç¤Ï¡¢¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Æ¤¤¤¤Þ¤¹¡£
block.c ¤Ï¡¢Á°²ó¤Î multiproc.c ¤ò´ðËܤȤ·¤Æ¡¢¥Ö¥í¥Ã¥¯ÍѤνèÍý¤òÄɲ䷤Ƥ¤¤Þ¤¹¡£¤³¤³¤Ç¤ÏÊѹ¹ÅÀ¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Þ¤¹¡£
- 7 ¡Á 8 ¹ÔÌÜ
¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á¤ËɬÍפʥإåÀ¥Õ¥¡¥¤¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤·¤Æ¤¤¤Þ¤¹¡£
- 26 ¡Á 27 ¹ÔÌÜ
¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á¤ÎÂÔ¤ÁÎó¤È¸Æ¤Ð¤ì¤ë¥Ç¡¼¥¿¹½Â¤ wait_queue_head_t ·¿ÊÑ¿ô¤òÀë¸À¤·¤Æ¤¤¤Þ¤¹¡£write_q ¤Ï½ñ¤¹þ¤ß ¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á¤ÎÂÔ¤ÁÎó¤Ç¡¢read_q ¤ÏÆɤ߹þ¤ß¥×¥í¥»¥¹ ¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á¤ÎÂÔ¤ÁÎó¤Ç¤¹¡£ÂÔ¤ÁÎó¤Ë¤Ä¤¤¤Æ¤Ï¸å½Ò¤·¤Þ¤¹¡£
- 30 ¡Á 43 ¹ÔÌÜ
¥í¥°½ÐÎÏ¥Õ¥©¡¼¥Þ¥Ã¥È¤ò·¤¨¤ë¤¿¤á¤Ë¡¢ÀìÍѤδؿô¤òÍÑ°Õ¤·¤Þ¤·¤¿¡£ current->pid / current->comm ¤È¤¤¤¦ÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤¹¤¬¡¢current ¤Ï¸½ºß¼Â¹ÔÃæ¤Î¥æ¡¼¥¶¥×¥í¥»¥¹¤Ë´Ø¤¹¤ë¾ðÊó¤ò»²¾È¤¹¤ë¤¿¤á¤ÎÊÑ¿ô¤Ç struct task_struct ¹½Â¤ÂΤòº¹¤¹¥Ý¥¤¥ó¥¿¤Ç¤¹¡£linux/sched.h ¤ò ¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¤³¤È¤Ç»²¾È¤Ç¤¤Þ¤¹¡£
pid ¥á¥ó¥Ð¤Ï̾Á°¤ÎÄ̤ê¥×¥í¥»¥¹ ID ¤òɽ¤¹À°¿ôÃͤǡ¢comm ¤Ï ¥³¥Þ¥ó¥É̾¤òɽ¤¹Ê¸»úÎó¤Ç¤¹¡£¤³¤ì¤é¤ò¥í¥°¤Ë½ÐÎϤ¹¤ëÍͤˤ·¤Æ¤¤¤Þ¤¹¡£
- 68 ¡Á 130 ¹ÔÌÜ ( chardev_read )
- 86 ¹ÔÌÜ ¡Á 103 ¹ÔÌÜ
¥»¥Þ¥Õ¥©¤ò¼èÆÀ¤·¤¿Ä¾¸å¤Î½èÍý¤Ç¤¹¡£¥æ¡¼¥¶¥×¥í¥»¥¹¤ËÊÖ¤»¤ë ¥Ç¡¼¥¿¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç ( buf_pos == 0 )¡¢¥Ç¥Ã¥É¥í¥Ã¥¯¤¬À¸¤¸¤Ê¤¤ÍÍ ¤Ë¤Þ¤º¥»¥Þ¥Õ¥©¤ò²òÊü¤·¤Þ¤¹¡£¤½¤Î¸å¡¢¥Ç¥Ð¥¤¥¹¤ËÂФ·¤ÆÈó¥Ö¥í¥Ã¥¯»ØÄê ¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ÂÔ¤Á¾õÂ֤ˤ»¤º¤Ë¤½¤Î»þÅÀ¤Ç½ªÎ»¤·¤Þ¤¹¡£
Èó¥Ö¥í¥Ã¥¯»ØÄꤵ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢chardev_read ¤Ë°ú¿ô¤È¤·¤Æ ÅϤµ¤ì¤ë struct file ¹½Â¤ÂΤؤΥݥ¤¥ó¥¿ filp ¤ò»È¤¤¡¢f_flags ¥á¥ó¥Ð¤òÄ´¤Ù¤Þ¤¹¡£¤³¤Î¥Õ¥é¥°¤Ë O_NONBLOCK ¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç ¤ÏÈó¥Ö¥í¥Ã¥¯»ØÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£
¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á¤Ë¡¢wait_event_interruptible ¤ò ¼Â¹Ô¤·¤Þ¤¹¡£
#include <linux/sched.h> int wait_event_interruptible( wait_queue_head_t queue, int condition );
wait_queue_head_t ¤Ï linux/wait.h ¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ëÂÔ¤ÁÎó¤È ¸Æ¤Ð¤ì¤ë¥Ç¡¼¥¿¹½Â¤¤Ç¡¢¥¤¥Ù¥ó¥È¤ÎÄÌÃΤòÂÔ¤Ä¥×¥í¥»¥¹¤Î¥ê¥¹¥È¤ò ³ÊǼ¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£ block.c ¤Ç¤Ï static ÊÑ¿ô¤È¤·¤Æ read / write ÍѤÎÂÔ¤ÁÎó¤¬Àë¸À¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ ¤³¤³¤Ç¤Ï¡¢Æɤ߹þ¤ß¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á read_q ¤ò»È¤Ã¤Æ ¤¤¤Þ¤¹¡£
¤³¤ÎÂÔ¤ÁÎó¤Ï½é´ü²½¤·¤Æ»ÈÍѤ·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£¤³¤³¤Ç¤Ï init_module Æâ¤Ç init_waitqueue_head ¤Ë¤è¤Ã¤Æ½é´ü²½¤·¤Æ¤¤¤Þ¤¹¤¬¡¢ ÀÅŪ¤ÊÊÑ¿ô¤È¤·¤ÆÍÑ°Õ¤¹¤ë¾ì¹ç¤Ï DECLARE_WAIT_QUEUE_HEAD ¥Þ¥¯¥í ¤Ë¤è¤Ã¤Æ½é´ü²½¤ò¥³¥ó¥Ñ¥¤¥ë»þ¤Ë¹Ô¤¦¤³¤È¤¬¤Ç¤¤Þ¤¹¡£
#include <linux/wait.h> init_waitqueue_head( wait_queue_head_t* queue_p ); DECLARE_WAIT_QUEUE_HEAD( wait_queue_head_t queue );
wait_event_interruptible ¤Ï¡¢condition ¤Ë»ØÄꤵ¤ì¤¿¼°¤¬ 0 ¤Ç¤¢¤ë¾ì¹ç¤Ï¸½ºß¤Î¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ·¤Þ¤¹¡£ÂÔ¤Á¾õÂÖ¤¬²ò½ü ¤µ¤ì¤ë¤È¤Þ¤¿ condition ¤ÎȽÄê¤ò¹Ô¤¤¡¢0 ¤Ç¤¢¤ì¤ÐºÆÅÙ¥×¥í¥»¥¹¤ò ÂÔ¤Á¾õÂ֤ˤ·¤Þ¤¹¡£condition ¤¬Èó 0 ¤¢¤ë¤¤¤Ï¥·¥°¥Ê¥ë¤Ë¤è¤Ã¤Æ ³ä¤ê¹þ¤Þ¤ì¤¿¾ì¹ç¤Ë¡¢wait_event_interruptible ¤Ï½ªÎ»¤·¤Þ¤¹¡£ condition ¤¬Èó 0 ¤Ç½ªÎ»¤·¤¿¾ì¹ç¤Ï 0 ¤òÊÖ¤·¤Þ¤¹¡£
wait_event_interruptible ¤¬ 0 ¤òÊÖ¤µ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢ ¥·¥°¥Ê¥ë¤Ë¤è¤Ã¤Æ³ä¤ê¹þ¤Þ¤ì¤¿¤È¤ß¤Ê¤·¤Æ -ERESTARTSYS ¤òÊÖ¤·¤Æ¤¤¤Þ¤¹¡£ 0 ¤òÊÖ¤·¤¿¾ì¹ç¤ÏºÆÅÙ¥»¥Þ¥Õ¥©¤ò¼èÆÀ¤·¡¢¥»¥Þ¥Õ¥©¼èÆÀÁ°¤ËÊÌ ¥×¥í¥»¥¹¤Ë¤è¤Ã¤Æ¥Ç¡¼¥¿¤¬¾ÃÈñ¤µ¤ì¤Æ¤¤¤Ê¤¤¤«¤É¤¦¤«¤ò³Îǧ¤¹¤ë¤¿¤á¤Ë while ¥ë¡¼¥×¤ÎºÇ½é¤ËÌá¤ê¤Þ¤¹¡£
- 127 ¹ÔÌÜ
Æɤ߹þ¤ß½èÍý¤¬½ª¤ï¤Ã¤¿¸å¡¢ÂÔ¤Á¾õÂ֤ˤʤäƤ¤¤ë½ñ¤¹þ¤ß¥×¥í¥»¥¹ ¤ò¼Â¹Ô²Äǽ¾õÂ֤ˤ¹¤ë¤¿¤á¤Ë wake_up_interruptible ¤ò¼Â¹Ô¤·¤Þ¤¹¡£
#include <linux/sched.h> wake_up_interruptible( wait_queue_head_t* queue );
»ÈÍѤ·¤Æ¤¤¤ëÂÔ¤ÁÎó¤Ï½ñ¤¹þ¤ß¥×¥í¥»¥¹¤ÎÂÔ¤ÁÎó write_q ¤Ç¤¹¡£ ¤³¤ì¤ò¼Â¹Ô¤·¤Ê¤¤¤È¡¢ÂÔ¤Á¾õÂ֤ˤʤäƤ¤¤ë½ñ¤¹þ¤ß¥×¥í¥»¥¹¤Ï ±Ê±ó¤ËÂÔ¤Á¾õÂ֤ˤʤäƤ·¤Þ¤¦¤¿¤áÃí°Õ¤·¤Æ²¼¤µ¤¤¡£
- 133 ¡Á 189 ¹ÔÌÜ ( chardev_write )
chardev_read ƱÍÍ¡¢¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á¤Î½èÍý¤ò¹Ô¤Ã¤Æ¤¤¤Þ¤¹¡£ chardev_read ¤È°Û¤Ê¤ëÅÀ¤Ï¡¢¥Ö¥í¥Ã¥¯È½ÄêÍѤξò·ïʸ¤¬°Û¤Ê¤ë / wait_event_interruptible ¤Ç»ÈÍѤ·¤Æ¤¤¤ëÂÔ¤ÁÎó¤¬ write_q ¤Ç¤¢¤ë / wake_up_interruptible ¤Ç»ÈÍѤ·¤Æ¤¤¤ëÂÔ¤ÁÎó¤¬ read_q ¤Ç¤¢¤ë¡¢ ¤È¤¤¤Ã¤¿ÅÀ¤Ç¤¹¡£
- 202 ¡Á 221 ¹ÔÌÜ ( init_module )
ÂÔ¤ÁÎó½é´ü²½ÍѤνèÍý init_waitqueue_head ¤¬Äɲ䵤ì¤Æ¤¤¤Þ¤¹¡£
#include <linux/wait.h> init_waitqueue_head( wait_queue_head_t* queue_p );
°Ê¾å¤Ç block.c ¤Î²òÀâ¤Ï½ª¤ï¤ê¤Ç¤¹¡£¼¡²ó¤Ï¡¢O_NONBLOCK »ØÄê¤ò¤»¤º¤ËÈó¥Ö¥í¥Ã¥¯ I/O ¤ò¹Ô¤¤¤¿¤¤¾ì¹ç¤Ë»ÈÍѤ¹¤ë¥·¥¹¥Æ¥à¥³¡¼¥ë select ( poll ) ¤ËÂбþ¤µ¤»¤Þ¤¹¡£