Chinaunix首页 | 论坛 | 博客
  • 博客访问: 155819
  • 博文数量: 36
  • 博客积分: 372
  • 博客等级: 一等列兵
  • 技术积分: 282
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-28 17:04
文章分类

全部博文(36)

文章存档

2012年(36)

分类:

2012-06-04 18:45:09

[root@bogon 桌面]# gedit mycdev_globalmem.c

#include
#include
#include
#include
#include
#include

MODULE_AUTHOR("Me");
MODULE_LICENSE("GPL");

#define GLOBALMEM_SIZE 0x1000
#define GLOBALMEM_MAJOR 256

static int globalmem_major = GLOBALMEM_MAJOR;

struct globalmem_dev
{
    struct cdev cdev; /*cdev 结构体*/
    unsigned char mem[255]; /*全局内存*/
};

struct globalmem_dev *globalmem_devp;    /*定义设备变量*/


/*文件打开函数*/
static int globalmem_open(struct inode *inode, struct file *filp)
{
    /*将设备结构体指针赋值给文件私有数据指针*/
    filp->private_data = globalmem_devp;
    return 0;
}

/*globalmem设备驱动的读函数*/
static ssize_t globalmem_read(struct file *filp, char __user *buf, 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 count ? -ENXIO: 0;
    if (count > GLOBALMEM_SIZE - p)
        count = GLOBALMEM_SIZE - p;

    /*从内核空间向用户空间写数据*/
    if (copy_to_user(buf, (void*)(dev->mem + p), count))
    {
        ret = -EFAULT;
    }
    else
    {
        *ppos += count;
        ret = count;

        printk(KERN_INFO "read %u bytes(s) from %u\n", count, p);
    }

    return ret;
}

static ssize_t globalmem_write(struct file *fp, const char __user *buf, size_t size, loff_t *pos)
{
    return size;
}

static int globalmem_release(struct inode *inode, struct file *fp)
{
    return 0;
}

static const struct file_operations globalmem_fops =
{
    .owner = THIS_MODULE,
    .read = globalmem_read,
    .write = globalmem_write,
    .open = globalmem_open,
    .release = globalmem_release,
};

/*初始化并添加cdev结构体的函数*/
static void globalmem_setup_cdev(struct globalmem_dev *dev, int index)
{
    int ret;
    int devno = MKDEV(globalmem_major, index);

    cdev_init(&dev->cdev, &globalmem_fops);
    dev->cdev.owner = THIS_MODULE;
    dev->cdev.ops = &globalmem_fops;
    ret = cdev_add(&dev->cdev, devno, 1);
    if(ret){
        printk("adding globalmem error");
    }
}

/*模块初始化函数*/
int globalmem_init(void)
{
    int result;
    dev_t devno=MKDEV(globalmem_major,0);

    if(globalmem_major)        /*globalmem_major为给定的全局变量,见后面的程序清单*/
    {
        result=register_chrdev_region(devno,1,"globalmem");
    }
    else
    {
        result=alloc_chrdev_region(&devno,0,1,"globalmem");
        globalmem_major=MAJOR(devno);
    }

    if(result<0){
        printk("register globalmem failed..\n");
        return result;
    }else{
        printk("register globalmem success..\n");
    }

    globalmem_devp=kmalloc(sizeof(struct globalmem_dev),GFP_KERNEL);
    if(!globalmem_devp)
    {
        result=-ENOMEM;
        goto fail_malloc;
    }
    memset(globalmem_devp,0,sizeof(struct globalmem_dev));

    memcpy(globalmem_devp->mem, "This is mycdev_globalmem!", sizeof(struct globalmem_dev));

    globalmem_setup_cdev(globalmem_devp,0);
    return 0;

fail_malloc:
    unregister_chrdev_region(devno,1);
    return result;
}

/*模块退出函数*/
static void __exit globalmem_exit(void)
{
    cdev_del(&globalmem_devp->cdev);  /*释放struct cdev*/
    kfree(globalmem_devp);            /*释放分配为给 struct globalmem_dev的内存*/
    unregister_chrdev_region(MKDEV(globalmem_major,0), 1); /*释放devno*/
}

module_init(globalmem_init);
module_exit(globalmem_exit);



[root@bogon 桌面]# gedit Makefile

obj-m:=mycdev_globalmem.o
PWD:=$(shell pwd)
CUR_PATH:=$(shell uname -r)
KERNEL_PATH:=/usr/src/kernels/$(CUR_PATH)

all:
    make -C $(KERNEL_PATH) M=$(PWD) modules
clean:
    make -C $(KERNEL_PATH) M=$(PWD) clean


[root@bogon 桌面]# gedit mycdev_globalmem_test.c

#include
#include
#include
#include
#include

#define GLOBALMEM_SIZE     0x1000

int main()
{
    int testdev;
    int i, ret;
    char buf[GLOBALMEM_SIZE];

    testdev = open("/dev/mycdev_globalmem", O_RDWR);

    if (-1 == testdev) {
        printf("cannot open file.\n");
        exit(1);
    }

    if (ret = read(testdev, buf, GLOBALMEM_SIZE) <0) {
        printf("read error!\n");
        exit(1);
    }

    printf("%s\n", buf);

    close(testdev);

    return 0;
}


[root@bogon 桌面]# make

[root@bogon 桌面]# insmod mycdev_globalmem.ko
[root@bogon 桌面]# cat /proc/devices
[root@bogon 桌面]# mknod /dev/mycdev_globalmem c 256 0
[root@bogon 桌面]# chmod 777 /dev/mycdev_globalmem
[root@bogon 桌面]# gcc mycdev_globalmem_test.c -o mycdev_globalmem_test
[root@bogon 桌面]# ./mycdev_globalmem_test
[root@bogon 桌面]# dmesg
阅读(993) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~