头文件
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
宏及相关资源结构体
#define GLB_MEM_SIZE 1024
#define GLB_DEV_MAJOR 210
typedef struct chr_dev
{
struct cdev cdev;
char glb_mem[GLB_MEM_SIZE];
} glb_chr_dev_t;
全局变量
static int glb_major = GLB_DEV_MAJOR;
glb_chr_dev_t *glb_chr_devp;
static const struct file_operations glb_mem_fops = {
.owner = THIS_MODULE,
.open = glbmem_open,
.release = glbmem_release,
.read = glbmem_read,
.write = glbmem_write,
.llseek = glbmem_llseek,
.unlocked_ioctl = glbmem_ioctl
};
基本内容(设备号操作,字符设备操作)
static void
glbmem_setup_cdev(glb_chr_dev_t *dev, int index)
{
int ret;
int devno = MKDEV(glb_major, index);
cdev_init(&dev->cdev, &glb_mem_fops);
dev->cdev.owner = THIS_MODULE;
ret = cdev_add(&dev->cdev, devno, 1);
if(ret)
printk(KERN_NOTICE"Error %d adding globalmem %d\n", err, index);
}
static int
__init chr_dev_init(void)
{
int ret = 0;
dev_t devno = MKDEV(glb_major, 0);
if(glb_major)
ret = register_chrdev_region(devno, 1, “globalmem”);
else if{
ret = alloc_chrdev_region(&devno, 0, 1, “globalmem”);
glb_major = MAJOR(devno);
}
if(ret < 0)
return ret;
glb_chr_devp = kzalloc(sizeof(glb_chr_dev_t), GFP_KERNEL);
if(!glb_chr_devp){
ret = -ENOMEM;
goto fail_malloc;
}
glbmem_setup_cdev(glb_chr_devp, 0);
return ret;
fail_malloc:
unregister_chrdev_region(devno, 1);
return ret;
}
static void
__exit chr_dev_exit(void)
{
cdev_del(&glb_chr_devp->cdev);
kfree(glb_chr_devp);
unregister_chrdev_region(devno, 1);
}
设备操作函数
open
static int
glbmem_open(struct inode *inode, struct file *filp)
{
filp->private_date = glb_chr_devp;
printk(KERN_NOTICE"chr_dev is opening!!!\n");
return 0;
}
release
static int
glb_release(struct inode *inode, struct file *filp)
{
printk(KERN_NOTICE"chr_dev is releasing!!!\n");
return 0;
}
read
static ssize_t
glb_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
int ret = 0;
unsigned long p = *ppos;
unsigned int count = size;
glb_chr_dev_t *dev = filp->private_date;
…
return ret;
}
write
static ssize_t
glb_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
{
int ret = 0;
unsigned long p = *ppos;
unsigned int count = size;
glb_chr_dev_t *dev = filp->private_date;
…
return ret;
}
seek
static loff_t
glb_llseek(struct file *filp, loff_t, int offset, int orig)
{
loff_t ret = 0;
switch(orig){
case 0:
break;
…
}
return ret;
}
ioctl
static long
glb_ioctl(struct file *flip, unsigned int cmd, unsigned long arg)
{
glb_chr_dev_t *dev = filp->private_date;
switch(cmd){
…
}
return 0;
}