wenshengking 发表于 2013-1-16 09:24:46

linux驱动中ioctl()的实现问题

linux驱动中ioctl()的实现问题

ram_ioctl.h文件
#define __RAM_IOCTL_H

#define RAM_IOCOMMAND_CLEAR      0x1a
#define RAM_IOCOMMAND_SET      0x1b
#define RAM_IOCOMMAND_MOVE      0x1c

#define      RAM_IOCTL_MAGIC 'k'

#define      RAM_IOCTL_NR_MIN      RAM_IOCOMMAND_CLEAR
#define RAM_IOCTL_NR_MAX      RAM_IOCOMMAND_MOVE

#define RAM_IOCTL_CLEAR _IO( RAM_IOCTL_MAGIC, RAM_IOCOMMAND_CLEAR )
#define RAM_IOCTL_SET      _IO( RAM_IOCTL_MAGIC, RAM_IOCOMMAND_SET )
#define RAM_IOCTL_MOVE      _IO( RAM_IOCTL_MAGIC, RAM_IOCOMMAND_MOVE)


#endif
ram.c文件中的ioctl()
static int ram_ioctl(struct block_device *bdev,fmode_t mode, unsigned int cmd, unsigned long arg)
{

      int ret = 0;      
      if ( RAM_IOCTL_MAGIC != _IOC_TYPE( cmd ))
      {
                printk(KERN_ALERT "RamDeviceDriver: ioctype mismatch !\n");
                return ret;
      }

      if ( ( RAM_IOCTL_NR_MIN > _IOC_NR( cmd ) ) || ( RAM_IOCTL_NR_MAX < _IOC_NR( cmd ) ) )
      {
                printk(KERN_ALERT "RamDeviceDriver: iocnr mismatch !\n");
                return ret;
      }

      switch (cmd)
      {
                case RAM_IOCTL_CLEAR:
                        memset(ram_data_addr, 0, RAM_DATA_SIZE);
                        printk(KERN_ALERT "RamDeviceDriver:Success to clear memory !\n");
                        break;
                case RAM_IOCTL_SET:
                        memset(ram_data_addr, arg, RAM_DATA_SIZE);
                        printk(KERN_ALERT "RamDeviceDriver:Success to set memory !arg = %ld\n",arg);
                        break;
                case RAM_IOCTL_MOVE:
                        memcpy(ram_data_addr, ram_data_addr + MY_DATA_SIZE, MY_DATA_SIZE );
                        printk(KERN_ALERT "RamDeviceDriver:Success to move data !\n");
                        break;
                default:
                        printk(KERN_ALERT "RamDeviceDriver:Unknown ioctl commd !\n");
                        return -EINVAL;

      }
}



test.c文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "ram_ioctl.h"
int main ( void )
{
      int fd;
      int ret;
      char buf;

      fd = open( "/dev/myram", O_RDWR );

      if ( fd < 0 )
      {
      perror( " open" );
      return -1;
      }

      ret = write( fd, "wensheng",10 );
      if ( ret < 0 )
                perror( "write" );
      printf( "write %d byte\n", ret );
      ioctl( fd, RAM_IOCTL_CLEAR );
      close(fd);

       fd = open( "/dev/myram", O_RDWR );
      ret = read( fd, buf, 10 );

      if ( ret < 0 )
                perror( "read" );

      printf ( "buf is :%s\n",buf );
      close(fd);
      return 0;
}



问题如下:

   运行测试程序时,输出,write 10 byte
                                          buf is :wensheng
    查看dmesg信息 :RamDeviceDriver:Success to clear memory !

    可以看出,程序已经成功写入了“wensheng”字符串,并通过ioctl( fd, RAM_IOCTL_CLEAR );调用驱动中的ioctl() 执行 memset(ram_data_addr, 0, RAM_DATA_SIZE);(其中ram_data_addr是申请得到的内核虚拟内存的起始地址,RAM_DATA_SIZE内存大小)输出:RamDeviceDriver:Success to clear memory !信息。那么我块设备应该已经全部置0,为什么之后却又可以成功读出“wensheng”,其中求大神指点,那里出问题了,谢谢!!!

zy_sunshine 发表于 2013-1-16 23:35:32

嗯,你试着把
close(fd);
ioctl( fd, RAM_IOCTL_CLEAR );
这两句调换过来。

wenshengking 发表于 2013-1-17 09:52:31

先谢谢您能回贴,问题我刚刚已解,原因:write(),read()为I/O操作,写入文件时,系统会先将要写入的数据写入缓冲区(这是为以提高读写速度),只有遇到close()时才将缓冲区数据写入实际文件(没查到很准确的资料,但大概是这个意思)。将程序中的ioctl操作单独执行,如下代码:#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
   #include "ram_ioctl.h"
   int main ( void )
   {
       int fd;
      int ret;
      char buf = { 0 };
      unsigned long int arg = 0xFF;
      fd = open( "/dev/myram", O_RDWR );

      if ( fd < 0 )
      {
      perror( " open" );
      return -1;
      }

      ret = write( fd, "wensheng123 \n",);
   if ( ret < 0 )
         perror( "write" );
   printf( "write %d byte\n", ret );


/*if ( ioctl( fd, RAM_IOCTL_CLEAR ) < 0 )
   {
         perror( "ioctl error\n " );
         return -1;
   }

   if ( ioctl( fd, RAM_IOCTL_SET , arg ) < 0 )
   {
         perror( "ioctl error123 \n" );
         return -1;
   }
*/
   close( fd );

   fd = open( "/dev/myram", O_RDWR );
      ioctl( fd, RAM_IOCTL_SET, arg );
      close( fd );

      fd = open( "/dev/myram", O_RDWR );
      ret = read( fd, buf, 20 );

      if ( ret < 0 )
          perror( "read" );
      printf ( "buf is :%s\n", buf );
      close( fd );
      return 0;


这样我ioctl操作就能按我想的那样工作,


呵呵-- 谢谢您和大家观注,在此结贴
页: [1]
查看完整版本: linux驱动中ioctl()的实现问题