Linux内核读取功能

时间:2014-04-03 14:09:05

标签: c linux linux-kernel kernel

我正在尝试为我的内核程序创建一个read函数。首先,用户必须输入一些数字(输入数字0停止输入)。数字输入已经为我完成了我的工作是制作读取功能。读取功能必须跟踪输入的数量,并且它具有一个缓冲器,其中包含自模块激活后输入的数字。 我一直坚持将summer.c中读取的缓冲区和字符数添加到test-summer.c并打印出来。

Summer.c代码:

   /* example of a character device using ioctl 
    */

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/errno.h>
    #include <linux/fs.h>
    #include <asm/uaccess.h>
    #include "summer.h"

    #define BUF_LEN 80            /* Max length of the message from the device */

    /* the memory of the device*/
    int total;

    /* Global variables declared as staic, so are global within the file.*/
   static char *msg_Ptr;
   static char msg[BUF_LEN];

    /* called after the device is opened*/
    int device_open(struct inode *inode, struct file *file)
    {
    printk("\nsummer device is open\n");
    total = 0;

    // sprintf(msg);
    printk(msg);
    msg_Ptr = msg;

    return 0;
    }

    /* called after the device is closed
    */
    int device_close(struct inode *inode, struct file *file)
    {
    printk("\nsummer device is closed\n");
  return 0;
}

/* handling of ioctl events
*/
long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param)
{
  int number;
  switch(ioctl_num)
  {
    case SUMMER_SET:
      __get_user(number, (int*)ioctl_param);
      total += number;
      break;
    case SUMMER_GET:
      __put_user(total, (int*)ioctl_param);
      break;
  }
  return 0;
}

/* Read function */
static ssize_t device_read(struct file *filep, char *buffer, size_t length, loff_t *offset){

/* Number of bytes actually written to the buffer */
int bytes_read = 0;

/* If we're at the end of the message, return 0 signifying end of file */
if (*msg_Ptr == 0) return 0;

/* Actually put the data into the buffer */
while (length && *msg_Ptr) {

    /* The buffer is in the user data segment, not the kernel segment;
        *  assignment won't work. We have to use put_use which copies data from 
        *  the kernel data segment to the user data segment. */
    put_user(*(msg_Ptr++), buffer++);

    length--;
    bytes_read++;
}
/* Most read functions return the number of bytes put into the buffer */
return bytes_read;
}


/* table of event handlers of the device
*/
struct file_operations fops =
{
  read: device_read,
 // write: device_write, 
  open: device_open,
  release: device_close,
  unlocked_ioctl:  device_ioctl,
  compat_ioctl: device_ioctl
};

/* called after the kernelmodule is opened
*/
int init_module(void)
{
/* register the device
  ** after registration the device is known to linux by its major number
  ** example: mknod /dev/summer0 c 240 0
  ** this creates the device /dev/summer0
  ** which is a character device (c) with major number 240 and minor number 0
  */
  int retval = register_chrdev(MAJOR_NUM, DEVICE_NAME, &fops);
  if(retval < 0)
  {
    printk("character device not registered\n");
    return retval;
  }
  printk("summer kernel module loaded\n");
  return 0;
}

/* called after the module is closed
*/
void cleanup_module(void)
{
/* unregister the device
  */
  unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
  printk("summer kernel module unloaded\n");
}

Test-summer.c代码

/* example of use of a character device through ioctl
*/

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "../summer.h"

int main(void)
{
  int sum; 
  char* buffer;
  /* open character device   */
  int fd = open("/dev/summer0", O_RDWR);  // open device
  if(fd < 0)
  {
    printf("no device found\n");
    return;
  }
  /* read from device */
  int nc = read(fd,buffer,4,0);

  for(;;)
  {
    int num;
    printf("Number (exit with 0) = ");
    while(scanf("%d", &num) != 1)
      ;
    printf("-- %d --\n", num);
    if(num <= 0) break;

    /* use ioctl to pass a value to the character device     */
    ioctl(fd, SUMMER_SET, &num);
  }

  /* use ioctl to get a value from the character device   */
  ioctl(fd, SUMMER_GET, &sum);
  printf("Result = %d\n", sum);

  /* print num of chars + the buffer as a string with the amount of numbers read since the kernel is active. */
  printf("#char = %d\n", nc);
  printf("Buffer: %s\n" , buffer);

  close(fd);                         // close device
  return 0;
}

1 个答案:

答案 0 :(得分:0)

这是一个老问题,但不想让它没有答案。

在test-summers.c文件中,您没有为缓冲区分配内存并将其传递给read函数。这可能就是为什么你没有得到正确的返回值以及缓冲区没有填满你想要的数据的原因。