Chinaunix首页 | 论坛 | 博客
  • 博客访问: 662200
  • 博文数量: 121
  • 博客积分: 4034
  • 博客等级: 上校
  • 技术积分: 1439
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-28 12:42
文章分类

全部博文(121)

文章存档

2017年(8)

2016年(10)

2013年(2)

2012年(3)

2011年(18)

2010年(80)

分类: LINUX

2010-11-25 22:19:52

一个简单memory驱动程序

source code
/*
 *memory.c
 */
#include
//#include

#include
#include
#include
#include
#include
#include
#include
#include
//#include

#include

MODULE_LICENSE("Dual BSD/GPL");

int memory_open(struct inode *inode, struct file *filp);
int memory_release(struct inode *inode, struct file *filp);
ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
ssize_t memory_write(struct file *filp, char *buf, size_t count, loff_t *f_pos);
void memory_exit(void);
int memory_init(void);

struct file_operations memory_fops = {
read:memory_read,
     write:memory_write,
     open:memory_open,
     release:memory_release
};

int memory_major = 60;
char *memory_buffer;

int memory_open(struct inode *inode, struct file *filp)
{
    return 0;
}

int memory_release(struct inode *inode, struct file *filp)
{
    return 0;
}

ssize_t memory_read(struct file *filp, char *buf,
        size_t count, loff_t *f_pos)
{
    copy_to_user(buf, memory_buffer+(*f_pos), 1);
    printk("[output]memory_buffer=%s(%x)\n",memory_buffer,memory_buffer[0]);
    *f_pos += 1;
    return *f_pos;
}

ssize_t memory_write(struct file *filp, char *buf,
        size_t count, loff_t *f_pos)
{
    copy_from_user(memory_buffer, buf, count);
    printk("[input]memory_buffer=%s(%x)\n",memory_buffer,memory_buffer[0]);

    return strlen(buf);
}

int memory_init(void)
{
    int result;

    result = register_chrdev(memory_major, "memory", &memory_fops);
    if (result < 0) {
        printk("<1>memory: can't obtain major number %d\n", memory_major);
        return result;
    }

    memory_buffer = kmalloc(256, GFP_KERNEL);
    if (!memory_buffer) {
        result = - ENOMEM;
        goto fail;
    }
    memset(memory_buffer, 0, 256);

    printk("Inserting memory module\n");
    return 0;

fail:
    memory_exit();
    return result;
}

void memory_exit(void)
{
    unregister_chrdev(memory_major, "memory");

    if (memory_buffer)
        kfree(memory_buffer);

    printk("Removing memory module\n");
}

module_init(memory_init);
module_exit(memory_exit);


Makefile
#Makefile
obj-m := memory.o

KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

modules:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

clean:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) clean


测试程序
#include
#include

int main()
{
    int fd;
    int ret;
    char tmp[256] = {0};

    fd = open("/dev/memory", O_RDWR);

    ret = write(fd, "abcdef", 7);
    printf("write ret=%d\n",ret);

    ret = read(fd, tmp, 1);
    printf("tmp=%c, ret=%d\n",tmp[0],ret);

    ret = read(fd, tmp, 1);
    printf("tmp=%c, ret=%d\n",tmp[0],ret);

    ret = read(fd, tmp, 1);
    printf("tmp=%c, ret=%d\n",tmp[0],ret);

    ret = read(fd, tmp, 1);
    printf("tmp=%c, ret=%d\n",tmp[0],ret);

    close(fd);

    return 0;
}


操作:
insmod memory.ko
mknod /dev/memory c 60 0
chmod 777 /dev/memory
echo "abcdefg" > /dev/memory
cat /dev/memory
rmmod memory.ko
阅读(1449) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~