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

📄 scull.c

📁 Linux设备管理源码 字符设备驱动程序:设计两个终端设备文件实现一个字符设备驱动程序
💻 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 + -