字符设备驱动copy_to_usr

来源:互联网 发布:淘宝评价截图怎么弄 编辑:程序博客网 时间:2024/06/10 10:50

#Makefile 2.6obj-m :=hello.orbtree-objs := testrbtree.oKERNEL :=/usr/src/linux-headers-2.6.38-8-genericPWD :=$(shell pwd)modules : $(MAKE) -C $(KERNEL) M=$(PWD) modules chmod 777 hello.ko.PHONEY:cleanclean : rm -f *.o *.ko *.order *.mod.c *.symvers

hello.c

#include <linux/module.h>#include </usr/include/linux/ioctl.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/vmalloc.h>#include <linux/uaccess.h>#include <linux/slab.h>#include <linux/fcntl.h>#define HELLO_IOCTL_NR_BASE            0#define HELLO_IOCTL_NR_SET_DATA        (HELLO_IOCTL_NR_BASE + 1)#define HELLO_IOCTL_SET_DATA           _IOR('h', HELLO_IOCTL_NR_SET_DATA, NULL)static ssize_t test_read(struct file *file, char *buf, size_t count, loff_t *f_ops);static ssize_t test_write(struct file *file,const char *buf, size_t count, loff_t *f_ops);static int test_open(struct inode *inode, struct file *file);static int test_release(struct inode *inode, struct file *file);static long test_ioctl (struct file *filp, unsigned int cmd, unsigned long arg);unsigned int fs_major = 0;static char *data;static struct file_operations test_ops={   .owner = THIS_MODULE,    .read = test_read,   .write = test_write,   .open = test_open,   .unlocked_ioctl = test_ioctl,    .release  =  test_release,};static long test_ioctl (struct file *filp, unsigned int cmd, unsigned long arg){   int cmd_nr;   printk("entry ioctl test xf.wang arg = %d\n",arg);   cmd_nr = _IOC_NR (cmd);   switch (cmd_nr)   {       case HELLO_IOCTL_NR_SET_DATA:           printk("xf.wang test ioctl success!\n");       break;       default:           printk("test_ioctl: Unknown ioctl command (%d)\n", cmd);   }return 0;}static ssize_t test_read(struct file *file, char *buf, size_t count, loff_t *f_ops){    int len;    printk("test_read xf.wang \n");    if (count < 0)    {       return -EINVAL;    }    len = strlen (data);    if (len <  count)    {        count = len;    }    copy_to_user(buf, data, count+1);    return count;}static ssize_t test_write(struct file *file,const char *buf, size_t count, loff_t *f_ops){    printk("test_write xf.wang\n");    if (count < 0)    {        return -EINVAL;    }    kfree(data);    data = kmalloc(sizeof(char)*(count+1), GFP_KERNEL);    if(!data)    {       return -ENOMEM;    }    copy_from_user(data, buf, count+1);    return count;}static int test_open(struct inode *inode, struct file *file){     printk("This is test open\n");     return 0;}static int test_release(struct inode *inode, struct file *file){    printk("This is test release\n");    return 0;}int init_skull(void){        int res = 0;    res = register_chrdev(0, "fs", &test_ops);    if (res < 0)    {         printk("can't register test module\n");         return res;    }        if(fs_major == 0)    {        fs_major  = res;    }    printk("init test xf.wang\n");    return 0;}void exit_skull(void){    unregister_chrdev(fs_major, "fs");    printk("exit test xf.wang\n");}module_init(init_skull);module_exit(exit_skull);MODULE_LICENSE("GPL");


注:

在makfile 中可以使用uname -r 可以查看自己使用的kernel version.

查看ko 注册信息: dmesg -c

insmod hello.ko

注册后在proc 文件系统中,产生节点名字在/proc/devices, 可以查到主设备号。

mknod /dev/fs c 250 0 .这样就可以在/dev/下产生节点,供应用层使用。


应用测试程序:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <fcntl.h>#include <linux/ioctl.h>#include <sys/ioctl.h>int main(void){    int fd, i,nwrite,nread;    char *buf = "hello\n";    char read_buf[0] = "";    fd = open ("/dev/fs", O_RDWR);    if (fd <= 0)    {        perror("open :");        exit(1);           }    else    {       printf ("open test success!\n");    }    ioctl(fd,9,8);      nwrite = write(fd,buf,strlen(buf));    if (nwrite < 0)    {        perror ("write");        exit(1);    }       nread = read(fd,read_buf,6);    if (nread < 0)    {        perror ("read");        exit(1);    }    else    {        printf ("read buf = %s\n", read_buf);    }    close(fd);    return 0;}


测试结果:

open test success!
read buf = hello

kernel

#dmesg  //在linux 输入查看 /var/log/message

[18367.579196] This is test open
[18367.579375] test release this test



0 0
原创粉丝点击