歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux系統:拷貝的驅動程序解釋(1)

Linux系統:拷貝的驅動程序解釋(1)

日期:2017/2/25 10:36:10   编辑:Linux教程

#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#define GLOBALMEM_SIZE 0x1000
#define MEM_CLEAR 0x1
#define GLOBALMEM_MAJOR 254
static int globalmem_major = GLOBALMEM_MAJOR;

struct globalmem_dev
{
struct cdev cdev;
/***************************************
struct cdev
{
struct kobject koj; //內嵌的kobiject對象
struct module *owner;//所屬模塊
struct file_operations *ops;//文件操作結構體
struct list_head list;
dev_t dev;//設備號
unsigned int count;
};
******************************************/
unsigned char mem[GLOBALMEM_SIZE];
};
struct globalmem_dev *globalmem_devp;
int globalmem_open(struct inode *inode,struct file *filep)
{
filep->private_data=globalmem_devp;
return 0;
}
int globalmem_release(struct inode *inode,struct file *filep)
{
return 0;
}


static int globalmem_ioctl(struct inode *inodep,struct file *filep,unsigned int cmd,unsigned long arg)
{
struct globalmem_dev *dev=filep->private_data;
switch(cmd)
{
case MEM_CLEAR:
memset(dev->mem,0,GLOBALMEM_SIZE);
printk(KERN_INFO "globalmem is set to zero");
break;
default:
return -EINVAL;
}
return 0;
}
static ssize_t globalmem_read(struct file *filep,char __user *buf,size_t size,loff_t *ppos)
{
unsigned long p=*ppos;
unsigned int count=size;
int ret=0;
struct globalmem_dev *dev=filep->private_data;
if(p>=GLOBALMEM_SIZE) //要讀的偏移位置越界
return count ? - ENXIO:0;
if(count>GLOBALMEM_SIZE-p) //要讀的字節數太大
count= GLOBALMEM_SIZE-p;
/*內核空間—>用戶空間:將內核空間中首地址為dev->mem+p的count個字節拷貝到用戶空間的首地址為buf的字符串裡面去*/
if(copy_to_user(buf,(void *)(dev->mem+p),count))
ret = -EFAULT;
else
{
*ppos+=count;
ret=count;
printk(KERN_INFO "read %d bytes(s) from %d\n",(int)count,(int)p);
}
return ret;
}
static ssize_t globalmem_write(struct file *filep,const char __user *buf,size_t size,loff_t *ppos)
{
unsigned long p=*ppos;
unsigned int count =size;
int ret =0;
struct globalmem_dev *dev=filep->private_data;
if(p>=GLOBALMEM_SIZE) //要寫的偏移位置越界
return count ? -ENXIO:0;
if(count>GLOBALMEM_SIZE-p) //要寫的字節數太大
count=GLOBALMEM_SIZE-p;
/*用戶空間->內核空間:將用戶空間中首地址為buf的count個字節拷貝到內核空間首地址為dev-mem+p的存儲空間去*/
if(copy_from_user(dev->mem+p,buf,count))
ret=-EFAULT;
else
{
*ppos+=count;
ret=count;
printk(KERN_INFO "written %d bytes from %d\n",(int)count,(int)p);
}
return ret;
}
static loff_t globalmem_llseek(struct file *filep,loff_t offset,int orig)

Copyright © Linux教程網 All Rights Reserved