实验四:虚拟内存设备globalmem驱动实现.doc_第1页
实验四:虚拟内存设备globalmem驱动实现.doc_第2页
实验四:虚拟内存设备globalmem驱动实现.doc_第3页
实验四:虚拟内存设备globalmem驱动实现.doc_第4页
实验四:虚拟内存设备globalmem驱动实现.doc_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验四:虚拟内存设备globalmem驱动实现在Linux2.6内核以前注册字符设备的函数接口是register_chrdev(),在2.6中其可继续使用。register_chrdev大致作用:向内核注册cdev结构体,当在用户空间打开设备文件时内核可以根据设备号快速定位此设备文件的cdev-file_operations结构体,从而调用驱动底层的open、close、read、write、ioctl等函数,当我们在用户空间open字符设备文件时,首先调用def_chr_fops-chrdev_open()函数(所有字符设备都调用此函数),chrdev_open会调用kobj_lookup函数找到设备的cdev-kobject,从而得到设备的cdev,进而获得file_operations。要想通过kobj_lookup找到相应的cdev,必需调用register_chrdev()函数。向内核注册。globalmem设备是我们构造的一个虚拟设备,globalmem意味着“全局内存”,在globalmem字符设备驱动中会分配一片大小为GLOBALMEM_SIZE(4KB)的内存空间,并在驱动中提供针对该片内存的读写、控制和定位函数,以供用户空间的进程能通过Linux系统调用访问这片内存。在/home/book/globalmem新建文件globalmem.c如下:#include #include #include #include #include #include #include #include #include #include #include #define GLOBALMEM_SIZE0x1000/*全局内存最大4K字节*/#define MEM_CLEAR 0x1 /*清0全局内存*/#define GLOBALMEM_MAJOR 150 /*预设的globalmem的主设备号*/static int globalmem_major = GLOBALMEM_MAJOR;/*globalmem设备结构体*/struct globalmem_dev struct cdev cdev; /*cdev结构体*/ unsigned char memGLOBALMEM_SIZE; /*全局内存*/;struct globalmem_dev *globalmem_devp; /*设备结构体指针*/int globalmem_open(struct inode *inode, struct file *filp) filp-private_data = globalmem_devp; return 0;int globalmem_release(struct inode *inode, struct file *filp) return 0;static int globalmem_ioctl(struct inode *inodep, struct file *filp, unsigned int cmd, unsigned long arg) struct globalmem_dev *dev = filp-private_data;/*获得设备结构体指针*/ switch (cmd) case MEM_CLEAR: memset(dev-mem, 0, GLOBALMEM_SIZE); printk(KERN_INFO globalmem is set to zeron); break; default: return - EINVAL; return 0;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 %d bytes(s) from %dn, count, p); return ret;static ssize_t globalmem_write(struct file *filp, const 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_from_user(dev-mem + p, buf, count) ret = - EFAULT; else *ppos += count; ret = count; printk(KERN_INFO written %d bytes(s) from %dn, count, p); return ret;static loff_t globalmem_llseek(struct file *filp, loff_t offset, int orig) loff_t ret = 0; switch (orig) case 0: /*相对文件开始位置偏移*/ if (offset GLOBALMEM_SIZE) ret = - EINVAL; break; filp-f_pos = (unsigned int)offset; ret = filp-f_pos; break; case 1: /*相对文件当前位置偏移*/ if (filp-f_pos + offset) GLOBALMEM_SIZE) ret = - EINVAL; break; if (filp-f_pos + offset) f_pos += offset; ret = filp-f_pos; break; default: ret = - EINVAL; break; return ret;static const struct file_operations globalmem_fops = .owner = THIS_MODULE, .llseek = globalmem_llseek, .read = globalmem_read, .write = globalmem_write, .ioctl = globalmem_ioctl, .open = globalmem_open, .release = globalmem_release,;static void globalmem_setup_cdev(struct globalmem_dev *dev, int index) int err, devno = MKDEV(globalmem_major, index); cdev_init(&dev-cdev, &globalmem_fops); dev-cdev.owner = THIS_MODULE; dev-cdev.ops = &globalmem_fops; err = cdev_add(&dev-cdev, devno, 1); if (err) printk(KERN_NOTICE Error %d adding LED%d, err, index);int globalmem_init(void) int result; dev_t devno = MKDEV(globalmem_major, 0); /* 申请设备号*/ if (globalmem_major) result = register_chrdev_region(devno, 1, globalmem); else /* 动态申请设备号 */ result = alloc_chrdev_region(&devno, 0, 1, globalmem); globalmem_major = MAJOR(devno); if (result cdev); /*注销cdev*/ kfree(globalmem_devp); /*释放设备结构体内存*/ unregister_chrdev_region(MKDEV(globalmem_major, 0), 1); /*释放设备号*/MODULE_AUTHOR(Song Baohua);MODULE_LICENSE(Dual BSD/GPL);module_param(globalmem_major, int, S_IRUGO);module_init(globalmem_init);module_exit(globalmem_exit);在/home/book/globalmem新建Makefile文件如下:ifneq ($(KERNELRELEASE),)obj-m := globalmem.o elseKERNELDIR = /usr/src/linux-headers-2.6.31-14-generic/PWD := $(shell pwd)default:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean:rm -rf *.o * core .depend .*.cmd *.ko *.mod.c endif编译globalmem.c,得到myglobalmem.ko文件。运行insmod globalmem.ko命令加载模块,通过lsmod命令,发现globalmem模块已被加载。再通过cat /proc/devices命令查看,发现多出了主设备号为150的myglobalmem字符设备驱动,如下所示:rootEmbedSky /# sudo insmod globalmem.ko rootEmbedSky /# lsmod Not taintedmyglobalmem 3396 0 - Live 0xbf067000ov9650 11088 0 - Live 0xbf05c000rootEmbedSky /# cat /proc/devices Character devices:150 globalmemrootEmbedSky /# sudo mknod /dev/globalmem c 150 0编写应用程序test.c用于测试:#include #include #include #include #include main()char str1024, str21024;int fd, stop;int ret;fd = open(/dev/globalmem, O_RDWR, S_IRUSR | S_IWUSR);if (fd != -1 )printf(Please input the string written to globalmemn);scanf(%s, str);printf(The str is %sn, str);ioctl(fd, 1, NULL);ret = write(fd, str, strlen(str);printf(The ret is %dn, ret);lseek(fd, 0, SEEK_SET);scanf(%d, &stop);read(f

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论