博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux字符设备驱动学习笔记(一):简单的字符设备驱动
阅读量:7077 次
发布时间:2019-06-28

本文共 3159 字,大约阅读时间需要 10 分钟。

最近在鼓捣lnux字符设备驱动,在网上搜集的各种关于linux设备驱动的代码和注释,要么是针对2.4的,要么是错误百出,根本就不能运行成功,真希望大家在发博客的时候能认真核对下代码的正确性,特别是要把代码的运行环境和依赖条件列举出来,否则会对读者造成很大的误解。

以下代码的运行环境为:

操作系统:debian 6

内核版本:2.6.32(amd 64)

gcc版本:4.4.5

源代码如下所示(源代码确保编译可通过,运行无bug):

#include
#include
#include
#include
#include
#include
#include
MODULE_LICENSE("GPL");static int yang_open(struct inode*, struct file*);static int yang_release(struct inode*, struct file*);static ssize_t yang_read(struct file*, char *,size_t, loff_t*);static ssize_t yang_write(struct file*,const char*, size_t,loff_t*);loff_t yang_llseek(struct file *filp, loff_t off, int whence);static int major;static int device_open = 0;static char *device_name = "myvar";static dev_t devid;static struct mydev *my_cdev;struct mydev{ char *data; struct cdev cdev; unsigned long size;};static struct file_operations fops = { .owner = THIS_MODULE, .read = yang_read, .write = yang_write, .open = yang_open, .release = yang_release, .llseek = yang_llseek};int init_yang_module(void){ struct mydev *dev = (struct mydev *)kmalloc(sizeof(struct mydev),GFP_KERNEL); my_cdev = dev;//注册为全局变量,便于模块卸载 memset(dev, 0, sizeof(struct mydev)); dev->size = 10; int err; alloc_chrdev_region(&devid, 0, 1, "myvar"); major = MAJOR(devid); cdev_init(&dev->cdev, &fops); err = cdev_add(&dev->cdev, devid, 1); if(err) { printk(KERN_INFO"I was major number %d.\n",major); return -1; } printk("major number is %d\n",MAJOR(devid)); dev->data = (char*)kmalloc(dev->size * sizeof(char),GFP_KERNEL); memset(dev->data,0,dev->size * sizeof(char)); return 0;}void cleanup_yang_module(void){ cdev_del(&my_cdev->cdev); unregister_chrdev_region(devid, 1); printk("cleanup done\n");}loff_t yang_llseek(struct file *filp, loff_t off, int whence){ struct mydev *dev = filp->private_data; loff_t newpos; switch(whence) { case SEEK_SET: newpos = off; case SEEK_CUR: newpos = filp->f_pos + off; case SEEK_END: newpos = dev->size + off; break; default: return -EINVAL; } if(newpos < 0) return -EINVAL; filp->f_pos = newpos; return newpos;}static int yang_open(struct inode* inode, struct file* file){ struct mydev *dev; dev = container_of(inode->i_cdev, struct mydev, cdev); file->private_data = dev; return 0;}static int yang_release(struct inode* inode, struct file* file){ return 0;}static ssize_t yang_read(struct file* filp, char *buffer,size_t length, loff_t* off){ struct mydev *dev = filp->private_data; if(*off >= dev->size) { return 0; } if(*off + length > dev->size) length = dev->size - *off; if(copy_to_user(buffer,dev->data + *off,length * sizeof(char))) { return -EFAULT; } *off += length; return length;}static ssize_t yang_write(struct file* filp,const char* buffer, size_t length,loff_t* off){ struct mydev *dev = filp->private_data; if(length > dev->size) { return -EFAULT; } if(copy_from_user(dev->data,buffer,dev->size * sizeof(char))) { return -EFAULT; } *off += length; return dev->size;}module_init(init_yang_module); module_exit(cleanup_yang_module);

  

以后有时间我再把注释加上,如果有兄弟刚刚学习linux设备驱动,这份源代码是最好的礼物。

转载于:https://www.cnblogs.com/titanium/p/3487464.html

你可能感兴趣的文章
老男孩浅谈如何看待运维?
查看>>
linux系统基础调优32条技巧
查看>>
华为USG统一安全边界网关的设计、演示、经验鉴证实评-卷A
查看>>
我的友情链接
查看>>
Lync和Exchange 2013集成PART6:OWA集成IM
查看>>
腾讯云、阿里云都“服”了,云容灾你还迟疑什么?
查看>>
【Hibernate框架开发之九】Hibernate 性能优化笔记!(遍历、一级/二级/查询/缓存/乐观悲观锁等优化算法)...
查看>>
[C# 基础知识系列]专题十一:匿名方法解析
查看>>
zabbix自动添加删除主机的python脚本
查看>>
《Java从小白到大牛精简版》——前言
查看>>
坑爹的生活,源于你的工作谁都能干
查看>>
客户端网络库实现真的很简单吗?
查看>>
用百度推荐提升PV和收益的小方法
查看>>
300元成松松写字团10天好基友,值吗?
查看>>
不用Visual Studio,5分钟轻松实现一张报表
查看>>
FreeBSD下安装配置Hadoop集群(四)
查看>>
技术人员,请注意那些被你忽略的重要事情
查看>>
WINDOWS上数据灾难后专业的现场保护方法
查看>>
如何挖掘NAND Flash的IO性能
查看>>
微软私有云分享(R2)19Azure Pack与远程控制台
查看>>