📄 upperdrv.c
字号:
/*****upperdrv.c *****//**************************************************************/#ifndef __KERNEL__# define __KERNEL__#endif#ifndef MODULE# define MODULE#endif#define WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE#define __NO_VERSION__#include <linux/version.h>#include <linux/module.h>char kernel_version[]=UTS_RELEASE;#include <linux/kernel.h>#include <linux/mm.h>#include <linux/types.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/sched.h>#include <linux/ioport.h>#include <linux/string.h>#include <linux/slab.h>#include <asm/io.h>#include <asm/segment.h>#include <asm/uaccess.h>#ifndef _UPPER_DEVICE_H#define _UPPER_DEVICE_H#include <linux/ioctl.h>#define UPPER_MAJOR 117#define UPPER_LOW2UPPER 1 // change the input string from low to upper characters#define UPPER_UNCHAN 0 //copy the input string to the output#define UPPER_MAGIC UPPER_MAJOR#define UPPER_RESET _IO(UPPER_MAGIC,0) // reset the data#define UPPER_QUERY_NEW_MSG _IO(UPPER_MAGIC,1) // check for new message#define UPPER_QUERY_MSG_LENGTH _IO(UPPER_MAGIC,2) // get message length#define IOC_NEW_MSG 1#endif#define DEVICE_NAME "upper"#include "softdev.h"const int upperdrv_major=117;static int usage,new_msg; // control flagsunsigned char *data;unsigned char **data_point;// open the device static int upper_open(struct inode *inode,struct file *filp) { MOD_INC_USE_COUNT; printk("This upper drive is in open!\n"); return 0; }// close the device static int upper_release(struct inode *inode,struct file *filp) { MOD_DEC_USE_COUNT; printk("This upper drive is in release!\n"); return 0; }// write to device -transfer from user space to softdev static ssize_t upper_write(struct file *filp,const char *buf,size_t count,loff_t *offset) { int length; if(count<0) return -EINVAL; if(usage || new_msg) return -EBUSY; usage=1; kfree(data); data=kmalloc(sizeof(char)*(count+1),GFP_KERNEL); copy_from_user(data,buf,count); // start transfering length=softdev_send(data,count); if(length==-1) printk("string no longer than 1512!\n"); else if(length==-2) printk("device is busy!\n"); usage=0; new_msg=1; return count; } // read from device -transfer from softdev to user space static ssize_t upper_read(struct file *filp,char *buf,size_t count,loff_t *offset) { int length; kfree(data_point); data_point=(unsigned char **)kmalloc(sizeof(unsigned char*),GFP_KERNEL); if(count<0) return -EINVAL; if(usage) return -EBUSY; usage=1; length=softdev_recv(data_point); if(length<count) count=length; copy_to_user(buf,*data_point,count); // start transfering new_msg=0; usage=0; return count; }// ioctl for device -control or set the device static int upper_ioctl(struct inode *inode,struct file *filp,unsigned long int cmd,unsigned long arg) { int ret=0; switch(cmd) { case UPPER_LOW2UPPER: softdev_ioctl(1); printk("[in upper]now change upper finished"); return 2; break; case UPPER_UNCHAN: softdev_ioctl(0); printk("[in upper]now stop change upper finished"); return 3; break; case UPPER_RESET: kfree(data); kfree(data_point); data=NULL; data_point=NULL; new_msg=0; break; case UPPER_QUERY_NEW_MSG: if(new_msg) return IOC_NEW_MSG; break; case UPPER_QUERY_MSG_LENGTH: if(data==NULL) { return 0; } else { return strlen(data); } break; default: return -ENOTTY; } return ret; } struct file_operations upper_fops={ owner: THIS_MODULE, NULL, // seek read: upper_read, // read write: upper_write, // write NULL, // readdir NULL, // poll ioctl: upper_ioctl, // ioctl NULL, // mmap open: upper_open, // open NULL, // flush release: upper_release, // release NULL, // fsync NULL, // fasync NULL, // check media change NULL, // revalidate NULL, // lock NULL, NULL, };// Initialize the module -Register the character device int init_module(){ if(register_chrdev(UPPER_MAJOR,DEVICE_NAME,&upper_fops)!=0) { printk("registering character device major: %d failed!\n",UPPER_MAJOR); return -EIO; } else { printk("registering char device UPPER success!\n"); } // initialize the data ptr data=NULL; data_point=NULL; new_msg=0; return 0; }// Clean up -Unregister the character device void cleanup_module() { // free data memory if any if(data) kfree(data); if(data_point) kfree(data_point); unregister_chrdev(UPPER_MAJOR,DEVICE_NAME); printk("Sorry! The UPPER is unloading now!\n"); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -