代码
先把完整代码粘上,后面再逐个解释
#include <linux/cdev.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#define GLOBALMEM_SIZE 0x1000
#define GLOBALMEM_MAJOR 0
#define GLOBALMEM_MAGIC 'g'
#define MEM_CLEAR _IO(GLOBALMEM_MAGIC, 0)
#define GLOBALMEM_NUM 10
static int globalmem_major = GLOBALMEM_MAJOR;
module_param(globalmem_major, int, S_IRUGO);
struct globalmem_dev{
struct cdev cdev;
unsigned char mem[GLOBALMEM_SIZE];
struct mutex mutex;
};
struct globalmem_dev *globalmem_devp;
static ssize_t globalmem_read(struct file *filp, char __user *buff, size_t size, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret = 0;
struct globalmem_dev *dev = filp->private_data;
if (p >= GLOBALMEM_SIZE)
return 0;
if (count > GLOBALMEM_SIZE - p)
count = GLOBALMEM_SIZE - p;
mutex_lock(&dev->mutex);
if (copy_to_user(buff, dev->mem + p, count)){
ret = -EFAULT;
}else{
*ppos += count;
ret = count;
printk(KERN_INFO"read %u bytes from %lu\n", count, p);
}
mutex_unlock(&dev->mutex);
return ret;
}
static ssize_t globalmem_write(struct file *filp, const char __user *buff, size_t size, loff_t *ppos)
{
unsigned long p = *ppos;
unsigned int count = size;
int ret;
struct globalmem_dev *dev = filp->private_data;
if (p >= GLOBALMEM_SIZE)
return 0;
if (count > GLOBALMEM_SIZE - p)
count = GLOBALMEM_SIZE - p;
mutex_lock(&dev->mutex);
if (copy_from_user(dev->mem + p, buff, count)){
ret = -EFAULT;
}else
{
*ppos += count;
ret = count;
printk(KERN_INFO"written %u bytes from %lu\n", count, p);
}
mutex_unlock(&dev->mutex);
return ret;
}
static int globalmem_open(struct inode *inode, struct file *filp)
{
struct globalmem_dev *dev = container_of(inode->i_cdev, struct globalmem_dev, cdev);
filp->private_data = dev;
return 0;
}
static int globalmem_release(struct inode *inode, struct file *filp)
{
return 0;
}
static loff_t globalmem_llseek(struct file *filp, loff_t offset, int arg)
{
loff_t ret = 0;
switch(arg){
case 0://begin from the start
if (offset < 0)
{
ret = -EINVAL;
break;
}
if ((unsigned int)offset > GLOBALMEM_SIZE){
ret = -EINVAL;
break;
}
filp->f_pos = offset;
ret = filp->f_pos;
break;
case 1://begin from current position
if ((unsigned int)offset + (unsigned int)filp->f_pos < 0)
{
ret = -EINVAL;
break;
}
if ((unsigned int)offset + (unsigned int)filp->f

本文详细解析了《Linux设备驱动开发详解》中的globalmem字符设备驱动,包括驱动入口函数、设备打开与释放、读写函数、ioctl命令及驱动卸载过程。通过实例展示了如何在Linux中创建和操作虚拟内存设备。

1933

被折叠的 条评论
为什么被折叠?



