📄 scull.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/malloc.h>#include <linux/string.h>#include <asm/io.h>#include <asm/segment.h>#include <asm/uaccess.h>//#define DEFAULT 0int scull_major,new_msg;struct device_struct{ const char *name; struct file_operations *chops;};static struct device_struct chrdevs[MAX_CHRDEV];struct scull_dev { void **data; int quantum; //the current quantum size int qset; //the current array size unsigned long size; unsigned int access_key; //used by sculluid and scullpriv unsigned int usage; //lock the device while using it unsigned int new_msg; struct scull_dev *next;};struct scull_dev scull;int register_chrdev(unsigned int major,const char *name,struct file_operations *chops){ if(major==0){ write_lock(&chrdevs); for(major=MAX_CHRDEV-1;major>0;major--){ if(chrdevs[major].chops==NULL){ chrdevs[major].name=name; chrdevs[major].chops=chops; write_unlock(&chrdevs_lock); return major; } } write_unlock(&chrdevs); return -EBUSY; } if(major>=MAX_CHRDEV) return -EINVAL; write_lock(&chrdevs); if(chrdevs[major].chops&&chrdevs[major].chops!=chops){ write_unlock(&chrdevs); return -EBUSY; } chrdevs[major].name=name; chrdevs[major].chops=chops; write_unlock(&chrdevs); return 0;}int scull_open(struct inode *inode,struct file *filp){ MOD_INC_USE_COUNT; printk("This chrdev is in open\n"); return 0;}int scull_write(struct inode *inode,struct file *filp,const char *buffer,int count){ if(count<0) return -EINVAL; if(scull.usage||scull.new_msg) return -EBUSY; scull.usage=1; kfree(scull.data); scull.data=kmalloc(sizeof(char)*(count+1),GFP_KERNEL); if(!scull.data){ return -ENOMEM; } copy_from_user(scull.data,buffer,count+1); scull.usage=0; scull.new_msg=1; return count;}int scull_read(struct inode *inode,struct file *filp,char *buffer,int count){ int length; if(count<0) return -EINVAL; if(scull.usage) return -EBUSY; scull.usage=1; if(count==0) return 0; length=strlen(*scull.data); if(length<count) count=length; copy_to_user(buffer,scull.data,count+1); scull.new_msg=0; scull.usage=0; return count;}int scull_release(struct inode *inode,struct file *filp){ MOD_DEC_USE_COUNT; printk("This chrdev is in release\n"); return 0; #ifdef DEBUG printk("scull_release(%p,%p)\n",inode,filp); #endif}#define SCULL_IOC_MAGIC 'k' // k is the magic number#define SCULL_IOCRESET _IO(SCULL_IOC_MAGIC,0)#define SCULL_IOCSetQUANTUM _IOW(SCULL_IOC_MAGIC,1,scull.quantum)#define SCULL_IOCSetQSET _IOW(SCULL_IOC_MAGIC,2,scull.qset)#define SCULL_IOCTellQUANTUM _IO(SCULL_IOC_MAGIC,3)#define SCULL_IOCGetQUANTUM _IOR(SCULL_IOC_MAGIC,5,scull.quantum)#define SCULL_IOCHARDebugRESET _IO(SCULL_IOC_MAGIC,15)void scull_text(char *text){ int scull_trace; if(scull_trace){ console_print(text); console_print("\n"); } }int scull_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg){ scull_text("scull_ioctl"); switch(cmd){ #ifdef SCULL_DEBUG case SCULL_IOCHARDebugRESET: mod_use_count=1; #endif case SCULL_IOCRESET: scull.quantum=SCULL_IOCSetQUANTUM; scull.qset=SCULL_IOCSetQSET; break; case SCULL_IOCSetQUANTUM: scull.quantum=get_user(scull.quantum,(int *)arg); break; case SCULL_IOCTellQUANTUM: scull.quantum=arg; break; case SCULL_IOCGetQUANTUM: put_user(scull.quantum,(int *)arg); break; default: return -EINVAL; } return 0;}struct file_operations scull_chops={ NULL, scull_read, scull_write, NULL, NULL, scull_ioctl, NULL, scull_open, scull_release, NULL, NULL, NULL, NULL};int init_scull(){ int result; printk("Hello! This is scull!\n"); result=register_chrdev(scull_major,"scull",&scull_chops); if(result<0){ printk("Scull: Can't get major number!\n"); return result; } if(scull_major==0) scull_major=result; return 0;}void cleanup_scull(){ unregister_chrdev(scull_major,"scull"); printk("Sorry! The scull is unloading now!\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -