Device Driver Development (part 2)

Device driver development. [part 2]

In the previous part of this article, we showed how we could add files and directories to the /proc filesystem. This time, I’ll show how to change things so that we can write things into kernel space via the proc filesystem, and then read them back.

 /*  * /proc file driver.  */  #define TEST_VERSION            "1.0"  #include
 #include  #include   static int proc_infos( unsigned char *contents, char *buffer, int *len,                                 off_t *begin, off_t offset, int size ); struct proc_dir_entry *proc_TESTDIR; struct proc_dir_entry *proc_TEST; 

Everything at the beginning is exactly the same as it was before. No changes necessary.

 unsigned char *kernel_buffer_ptr; static unsigned char contents[2048]="Hello world"; 

This time we declare the buffer we ‘render’ text into outside of the read routine, so that we can access it from both the read and write routines.

 static int TEST_write_proc( struct file *file, const char *buffer, unsigned long count, void *data) {         int i;          const char *bufptr;          if (!capable(CAP_SYS_ADMIN))                 return -EACCES;          bufptr=buffer;          for (i=0;i<count-1;i++) {                 *kernel_buffer_ptr=*bufptr;                 kernel_buffer_ptr++;                 bufptr++;         }         *kernel_buffer_ptr=;          return(count); } 

This is where the magic happens. We check that the user has the capabilities to write to the file. If admin capabilities are not present, then nothing further is done. If they are present, then we copy the string from the command line into the buffer, and null terminate it.

 static int TEST_read_proc( char *buffer, char **start, off_t offset,                             int size, int *eof, void *data ) {     int len = 0;     off_t begin = 0;      *eof = proc_infos( contents, buffer, &len, &begin, offset, size );      if (offset >= begin + len)         return( 0 );     *start = buffer + (begin - offset);     return( size < begin + len - offset ? size : begin + len - offset ); }  /* This macro frees the machine specific function from bounds checking and  * this like that... */ #define PRINT_PROC(fmt,args...)                                          do {                                                                     *len += sprintf( buffer+*len, fmt, ##args );                     if (*begin + *len > offset + size)                                    return( 0 );                                             if (*begin + *len < offset) {                                                 *begin += *len;                                                  *len = 0;                                                }                                                        } while(0) 

Everything the same as it was in the previous article.

 __initfunc(int TEST_init(void)) {         printk(KERN_INFO "TEST driver v%sn", TEST_VERSION );          kernel_buffer_ptr=contents;          proc_TESTDIR = create_proc_entry( "testdir", S_IFDIR, 0 );         if ((proc_TEST = create_proc_entry( "test", 0, proc_TESTDIR ))) {                 proc_TEST->read_proc = TEST_read_proc;                 proc_TEST->write_proc = TEST_write_proc;         }         return( 0 ); } 

A subtle change here. We tell the proc filesystem what routine to call should a write to the file occur.

 #ifdef MODULE int init_module (void) {         return( TEST_init() ); }  void cleanup_module (void) {         if (proc_TEST)                 remove_proc_entry( "testdir/test", 0 );         if (proc_TESTDIR)                 remove_proc_entry( "testdir", 0 ); } #endif 

Same as last time…

static int proc_infos( unsigned char *TEST, char *buffer, int *len,                           off_t *begin, off_t offset, int size ) {         PRINT_PROC( "%sn", contents);         return( 1 ); }

This has been changed to print out the current buffer contents.When this driver has been installed you can now write to files with echo.

root@nemesis cat /proc/testdir/test Hello world root@nemesis echo "Muahahaha" > /proc/testdir/test root@nemesis cat /proc/testdir/test Muahahaha

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요: 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )


%s에 연결하는 중