如何编写与内核模块通信的shell脚本

时间:2016-08-12 13:15:02

标签: c shell

下面是我的内核模块,我通过C程序测试但现在不是使用c应用程序而是想编写一个shell脚本,它对我的​​内核模块进行读写操作? 提前谢谢。

#include <linux/init.h>           
#include <linux/module.h>         
#include <linux/device.h>        
#include <linux/kernel.h>         
#include <linux/fs.h>            
#include <asm/uaccess.h>          
#define  DEVICE_NAME "mydevice"    
#define  CLASS_NAME  "device"

MODULE_LICENSE("GPL");            
MODULE_AUTHOR("ABC");    
MODULE_DESCRIPTION("A simple Linux character driver");  
MODULE_VERSION("0.1"); 

static int    majorNumber;                  
static char   message[256] = {0};           
static short  size_of_message;              
static int    numberOpens = 0;              
static struct class*  character_deviceClass  = NULL; 
static struct device* character_deviceDevice = NULL; 

static int     dev_open(struct inode *, struct file *);
static int     dev_release(struct inode *, struct file *);
static ssize_t dev_read(struct file *, char *, size_t, loff_t *);
static ssize_t dev_write(struct file *, const char *, size_t, loff_t *);

static DEFINE_MUTEX(devicedev_mutex);

static struct file_operations fops =
{
   .open = dev_open,
   .read = dev_read,
   .write = dev_write,
   .release = dev_release,
};


static int __init character_device_init(void){
   printk(KERN_INFO "Shell: Initializing the character device LKM\n");


   majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
   if (majorNumber<0){
      printk(KERN_ALERT "character device failed to register a major number\n");
      return majorNumber;
   }
   printk(KERN_INFO "character device: registered correctly with major number %d\n", majorNumber);


   character_deviceClass = class_create(THIS_MODULE, CLASS_NAME);
   if (IS_ERR(character_deviceClass)){                
      unregister_chrdev(majorNumber, DEVICE_NAME);
      printk(KERN_ALERT "Failed to register device class\n");
      return PTR_ERR(character_deviceClass);          
   }
   printk(KERN_INFO "character device: device class registered correctly\n");


   character_deviceDevice = device_create(character_deviceClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
   if (IS_ERR(character_deviceDevice)){               
      class_destroy(character_deviceClass);           
      unregister_chrdev(majorNumber, DEVICE_NAME);
      printk(KERN_ALERT "Failed to create the device\n");
      return PTR_ERR(character_deviceDevice);
   }
   printk(KERN_INFO "character device: device class created correctly\n"); 

   mutex_init(&devicedev_mutex);
   return 0;
}


static void __exit character_device_exit(void){
   mutex_destroy(&devicedev_mutex);
   device_destroy(character_deviceClass, MKDEV(majorNumber, 0));     
   class_unregister(character_deviceClass);                          
   class_destroy(character_deviceClass);                             
   unregister_chrdev(majorNumber, DEVICE_NAME);             
   printk(KERN_INFO "character device: Goodbye from the LKM!\n");
}


static int dev_open(struct inode *inodep, struct file *filep){

   if(!mutex_trylock(&devicedev_mutex))
   {
     printk(KERN_ALERT "Character device: Device in use by another process");
     return  -EBUSY;
   }   
   numberOpens++;
   printk(KERN_INFO "character device: Device has been opened %d time(s)\n", numberOpens);
   return 0;
}


static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset){
   int error_count = 0;

   error_count = copy_to_user(buffer, message, size_of_message);

   if (error_count==0){           
      printk(KERN_INFO "character device: Sent %d characters to the user\n", size_of_message);
      return (size_of_message=0);  
   }
   else {
      printk(KERN_INFO "character device: Failed to send %d characters to the user\n", error_count);
      return -EFAULT;             
   }
}


static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset){
   sprintf(message, "%s(%d letters)", buffer, len);   
   size_of_message = strlen(message);                 
   printk(KERN_INFO "character device: Received %d characters from the user\n", len);
   return len;
}

static int dev_release(struct inode *inodep, struct file *filep){
   mutex_unlock(&devicedev_mutex);
   printk(KERN_INFO "character device: Device successfully closed\n");
   return 0;
}

module_init(character_device_init);
module_exit(character_device_exit);

1 个答案:

答案 0 :(得分:0)

让我们说你注册了主要号码254和次要号码1(你问题中给出的实际代码将分配的号码记录到dmesg,所以检查那里)。如果您没有配置udev或类似功能为您创建/dev/mydevice,您可以自己这样做:

mknod /dev/mydevice c 254 1 # substitute the real allocated values

此时,打开它与其他任何东西相同:

# file descriptor number 3 is arbitrary, but the same number needs to be reused later
# don't use 0-2, which are reserved for stdin/stdout/stderr
exec 3<>/dev/mydevice

......并且读取和写入同样是传统的:

echo "This is a write" >&3
read varname <&3 # read until newline from device