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

付费下载

下载本文档

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

文档简介

1、实验四:虚拟内存设备 globalmem驱动实现在Linux2.6内核以前注册字符设备的函数接口是register_chrdev(),在2.6中其可继续使用。register_chrdev大致作用:向内核注册cdev结构体,当在用户空间打开设备文件时内核可以根据设备号快速定位此设备文件的cdev-file_operations结构体,从而调用驱动底层的open、close、read、write、ioctl等函数,当我们在用户空间open字符设备文件时,首先调用def_chr_fo ps-chrdev_o pen()函数(所有字符设备 都调用 此函数),chrdev_ open会调用 kobj_

2、look up函数找到设备的cdev-kobject,从而得到设备的 cdev,进而获得file_ op eratio ns。 要想通过kobj_lookup找到相应的cdev,必需调用register_chrdev()函数。向内核注册。图字符设备療动的结构globalmem设备是我们构造的一个虚拟设备,globalmem意味着全局内存”,在globalmem字符设备驱动中会分配一片大小为GLOBALMEM_SIZE (4KB)的内存空间,并在驱动中提供针对该片内存的读写、控制和定位函数,以供用户空间的进程能通过Linux系统调用访问这片内存。在/home/book/globalmem 新建文

3、件 globalmem.c女0下:#include #include #include #include #include #include #include #include #include #include #include #define GLOBALMEM_SIZE 0x1000/*全局内存最大 4K 字节 */#define MEM_CLEAR 0x1/*清 0 全局内存 */#define GLOBALMEM_MAJOR 150/*预设的globalmem的主设备号*/static int globalmem_major = GLOBALMEM_MAJOR; /*globalme

4、m设备结构体*/struct globalmem_devstruct cdev cdev; /*cdev 结构体 */unsigned char memGLOBALMEM_SIZE; /*全局内存 */ ;struct globalmem_dev *globalmem_devp; /*设备结构体指针 */ int globalmem_ op en(struct inode *inode, struct file *filp) fil p-p rivate_data = globalmem_dev p;return 0;int globalmem_release(struct inode *in

5、ode, struct file *filp) return 0; static int globalmem_ioctl(struct inode *inode p, 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 z

6、eron); 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)

7、 return count ?- ENXIO: 0;if (count GLOBALMEM_SIZE - p) count = GLOBALMEM_SIZE - p;/*内核空间-用户空间*/if (cop y_to_user(buf, (void*)(dev-mem + p), count) ret =- EFAULT;else*ppos += count;ret = count;p rintk(KERN_INFO read %d bytes(s) from %dn, count, p);return ret;static ssize_t globalmem_write(struct fil

8、e *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;/

9、*用户空间-内核空间*/if (copy_fro m_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 (off

10、set GLOBALMEM SIZE)ret = - EINVAL;break;fil p-f_pos = (unsigned int)offset;ret = fil p-f_pos; break;case 1:/*相对文件当前位置偏移*/if (fil p-f_ pos + offset) GLOBALMEM_SIZE)ret = - EINVAL;break;if (fil p-f_ pos + offset) f_pos += offset;ret = fil p-f_pos;break;default:ret = - EINVAL;break;return ret;static co

11、nst struct file_ op erations globalmem_fo ps =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, devn

12、o = MKDEV(globalmem_major, index);cdev_init (&dev-cdev, &globalmem_fo ps);dev-cdev.owner = THIS_MODULE;dev-cdev. ops = &globalmem_fo ps;err = cdev_add(&dev-cdev, devno, 1);if (err)p rintk(KERN_NOTICE Error %d adding LED%d, err, index);int globalmem_init(void)int result;dev_t devno = MKDEV(globalmem_

13、major, 0);/*申请设备号*/if (globalmem_major)result = register_chrdev_region(devno, 1, globalmem); else /*动态申请设备号*/result = alloc_chrdev_regio n(&devno, 0, 1, globalmem);globalmem_major = MAJOR(devno);if (result cdev);/*注销 cdev*/kfree(globalmem_devp);/*释放设备结构体内存*/unregister_chrdev_region(MKDEV(globalmem_m

14、ajor, 0), 1); /* 释放设备号 */MODULE_AUTHOR(Song Baohua);MODULE_LICENSE(Dual BSD/G PL); 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

15、-headers-2.6.31-14-generic/PWD := $(shell pwd)default:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesclean:rm -rf *.o *core .de pend .*.cmd *.ko *.mod.c endif编译 globalmem.c,得至U myglobalmem.ko 文件。运行insmod globalmem.ko 命令加载模块,通过lsmod命令,发现globalmem模块已被加 载。再通过cat /proc/devices 命令查看,发现多出了主设备号为 150的myglobalmem字符

16、设 备驱动,如下所示:rootEmbedSky /# sudo insmod globalmem.korootEmbedSky /# lsmodNot tainted myglobalmem 3396 0 - Live 0xbf067000 ov9650 11088 0 - Live 0xbf05c000rootEmbedSky /# cat /pr oc/devicesCharacter devices:150 globalmemrootEmbedSky /# sudo mknod /dev/globalmem c 150 0编写应用程序test.c用于测试:#include #includ

17、e #include #include #include main()char str1024, str21024;int fd, stop;int ret;fd = op en(/dev/globalmem, O_RDWR, S_IRUSR | S_IWUSR);if (fd != -1 )p rintf( PI ease 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);p rintf(The ret is %dn, ret); lseek(fd, 0, SEEK_SET);scanf(%d, &sto p); read(fd, str2

温馨提示

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

评论

0/150

提交评论