⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 9.html

📁 linux操作系统内核编程-----LINUX系统开发非常好的资料
💻 HTML
📖 第 1 页 / 共 2 页
字号:
    case IOCTL_SET_MSG:
      /* Receive a pointer to a message (in user space) 
       * and set that to be the device\'s message. */ 

      /* Get the parameter given to ioctl by the process */
      temp = (char *) ioctl_param;
   
      /* Find the length of the message */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
      get_user(ch, temp);
      for (i=0; ch && i<BUF_LEN; i++, temp++)
        get_user(ch, temp);
#else
      for (i=0; get_user(temp) && i<BUF_LEN; i++, temp++)
	;
#endif

      /* Don\'t reinvent the wheel - call device_write */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
      device_write(file, (char *) ioctl_param, i, 0);
#else
      device_write(inode, file, (char *) ioctl_param, i);
#endif
      break;

    case IOCTL_GET_MSG:
      /* Give the current message to the calling 
       * process - the parameter we got is a pointer, 
       * fill it. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
      i = device_read(file, (char *) ioctl_param, 99, 0); 
#else
      i = device_read(inode, file, (char *) ioctl_param, 
                      99); 
#endif
      /* Warning - we assume here the buffer length is 
       * 100. If it\'s less than that we might overflow 
       * the buffer, causing the process to core dump. 
       *
       * The reason we only allow up to 99 characters is 
       * that the NULL which terminates the string also 
       * needs room. */

      /* Put a zero at the end of the buffer, so it 
       * will be properly terminated */
      put_user(\'\\0\', (char *) ioctl_param+i);
      break;

    case IOCTL_GET_NTH_BYTE:
      /* This ioctl is both input (ioctl_param) and 
       * output (the return value of this function) */
      return Message[ioctl_param];
      break;
  }

  return SUCCESS;
}


/* Module Declarations *************************** */


/* This structure will hold the functions to be called 
 * when a process does something to the device we 
 * created. Since a pointer to this structure is kept in 
 * the devices table, it can\'t be local to
 * init_module. NULL is for unimplemented functions. */
struct file_operations Fops = {
  NULL,   /* seek */
  device_read, 
  device_write,
  NULL,   /* readdir */
  NULL,   /* select */
  device_ioctl,   /* ioctl */
  NULL,   /* mmap */
  device_open,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
  NULL,  /* flush */
#endif
  device_release  /* a.k.a. close */
};


/* Initialize the module - Register the character device */
int init_module()
{
  int ret_val;

  /* Register the character device (atleast try) */
  ret_val = module_register_chrdev(MAJOR_NUM, 
                                 DEVICE_NAME,
                                 &Fops);

  /* Negative values signify an error */
  if (ret_val < 0) {
    printk (\"%s failed with %d\\n\",
            \"Sorry, registering the character device \",
            ret_val);
    return ret_val;
  }

  printk (\"%s The major device number is %d.\\n\",
          \"Registeration is a success\", 
          MAJOR_NUM);
  printk (\"If you want to talk to the device driver,\\n\");
  printk (\"you\'ll have to create a device file. \\n\");
  printk (\"We suggest you use:\\n\");
  printk (\"mknod %s c %d 0\\n\", DEVICE_FILE_NAME, 
          MAJOR_NUM);
  printk (\"The device file name is important, because\\n\");
  printk (\"the ioctl program assumes that\'s the\\n\");
  printk (\"file you\'ll use.\\n\");

  return 0;
}


/* Cleanup - unregister the appropriate file from /proc */
void cleanup_module()
{
  int ret;

  /* Unregister the device */
  ret = module_unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
 
  /* If there\'s an error, report it */ 
  if (ret < 0)
    printk(\"Error in module_unregister_chrdev: %d\\n\", ret);
}
ex chardev.h    
 
/* chardev.h - the header file with the ioctl definitions.
 *
 * The declarations here have to be in a header file, 
 * because they need to be known both to the kernel 
 * module (in chardev.c) and the process calling ioctl 
 * (ioctl.c)
 */

#ifndef CHARDEV_H
#define CHARDEV_H

#include <linux/ioctl.h> 



/* The major device number. We can\'t rely on dynamic 
 * registration any more, because ioctls need to know 
 * it. */
#define MAJOR_NUM 100


/* Set the message of the device driver */
#define IOCTL_SET_MSG _IOR(MAJOR_NUM, 0, char *)
/* _IOR means that we\'re creating an ioctl command 
 * number for passing information from a user process
 * to the kernel module. 
 *
 * The first arguments, MAJOR_NUM, is the major device 
 * number we\'re using.
 *
 * The second argument is the number of the command 
 * (there could be several with different meanings).
 *
 * The third argument is the type we want to get from 
 * the process to the kernel.
 */

/* Get the message of the device driver */
#define IOCTL_GET_MSG _IOR(MAJOR_NUM, 1, char *)
 /* This IOCTL is used for output, to get the message 
  * of the device driver. However, we still need the 
  * buffer to place the message in to be input, 
  * as it is allocated by the process.
  */


/* Get the n\'th byte of the message */
#define IOCTL_GET_NTH_BYTE _IOWR(MAJOR_NUM, 2, int)
 /* The IOCTL is used for both input and output. It 
  * receives from the user a number, n, and returns 
  * Message[n]. */


/* The name of the device file */
#define DEVICE_FILE_NAME \"char_dev\"


#endif
        
ex ioctl.c    
 
/* ioctl.c - the process to use ioctl\'s to control the 
 * kernel module
 *
 * Until now we could have used cat for input and 
 * output. But now we need to do ioctl\'s, which require 
 * writing our own process. 
 */

/* Copyright (C) 1998 by Ori Pomerantz */
 

/* device specifics, such as ioctl numbers and the 
 * major device file. */
#include \"chardev.h\"    


#include <fcntl.h>      /* open */ 
#include <unistd.h>     /* exit */
#include <sys/ioctl.h>  /* ioctl */



/* Functions for the ioctl calls */

ioctl_set_msg(int file_desc, char *message)
{
  int ret_val;

  ret_val = ioctl(file_desc, IOCTL_SET_MSG, message);

  if (ret_val < 0) {
    printf (\"ioctl_set_msg failed:%d\\n\", ret_val);
    exit(-1);
  }
}



ioctl_get_msg(int file_desc)
{
  int ret_val;
  char message[100]; 

  /* Warning - this is dangerous because we don\'t tell 
   * the kernel how far it\'s allowed to write, so it 
   * might overflow the buffer. In a real production 
   * program, we would have used two ioctls - one to tell
   * the kernel the buffer length and another to give 
   * it the buffer to fill
   */
  ret_val = ioctl(file_desc, IOCTL_GET_MSG, message);

  if (ret_val < 0) {
    printf (\"ioctl_get_msg failed:%d\\n\", ret_val);
    exit(-1);
  }

  printf(\"get_msg message:%s\\n\", message);
}



ioctl_get_nth_byte(int file_desc)
{
  int i;
  char c;

  printf(\"get_nth_byte message:\");

  i = 0;
  while (c != 0) {
    c = ioctl(file_desc, IOCTL_GET_NTH_BYTE, i++);

    if (c < 0) {
      printf(
      \"ioctl_get_nth_byte failed at the %d\'th byte:\\n\", i);
      exit(-1);
    }

    putchar(c);
  } 
  putchar(\'\\n\');
}




/* Main - Call the ioctl functions */
main()
{
  int file_desc, ret_val;
  char *msg = \"Message passed by ioctl\\n\";

  file_desc = open(DEVICE_FILE_NAME, 0);
  if (file_desc < 0) {
    printf (\"Can\'t open device file: %s\\n\", 
            DEVICE_FILE_NAME);
    exit(-1);
  }

  ioctl_get_nth_byte(file_desc);
  ioctl_get_msg(file_desc);
  ioctl_set_msg(file_desc, msg);

  close(file_desc); 
}


</pre><hr><br><center><a href='8.html'>上一页 </a>||<a href='10.html'>下一页</a></center></div> </td>                  </tr>                </table>                <p>&nbsp; </p>                </div>            </td>          </tr>        </table>          <br>          <table border="0" width="75%"><tr><td align="right"><a href="/"><img src="/image2/logo_bottom.gif" border="0"></a></td></tr></table>          <hr size="1" align="center" color="#eecccc">          <br>        </div>      </div>      </td>  </tr></table>  <center><a href="http://ad.myrice.com/RealMedia/ads/click_nx.ads/goldnets.myrice.com/banner1@Bottom" target=_blanck ><script language=JavaScript><!---todayd = new Date();var seconds = todayd.getTime();document.write("<img src=\"http://ad.myrice.com/RealMedia/ads/adstream_nx.ads/goldnets.myrice.com/banner1@Bottom?dd=seconds\" border=0 width=468 height=60>");//--></script></a></center></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -