博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单字符设备驱动程序的操作步骤
阅读量:2391 次
发布时间:2019-05-10

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

一、Linux驱动程序开发步骤

1.查看原理图,数据手册等

2.找相近的驱动程序作为模板

3.实现驱动程序的初始化

4.设计所要实现的操作:open,read,write,close

5.实现中断(可以不需要)

6.用insmod命令加载驱动

二、驱动框架

驱动是无法直接识别应用程序上的应用层API:read,open,write等,需要对应驱动程序上的led_read,led_open,led_write,这些都是驱动函数。

每个系统调用,驱动程序怎样和它对应起来?

使用file_operations结构,和应用层API对接。

Linux怎么知道去调用哪个驱动程序的file_operations?

根据设备类型和主设备号,需要将注册函数将主设备号和file_operations一起注册到内核

将驱动程序加载到内核,调用驱动初始化函数,像内核注册

module_init(memdev_init);

三、驱动程序的加载和卸载

module_init(memdev_init);

module_exit(memdev_exit);

 四、几种重要的数据结构

struct file

         file结构代表一个打开的文件,它由内核在open时创建,并传递给该文件上进行操作的所有函数,直到最后的close函数。

         file结构private_data是跨系统调用时保存状态信息非常有用的资源。

         file结构的f_ops 保存了文件的当前读写位置。

struct inode

         内核用inode代表一个磁盘上的文件,它和file结构不同,后者表示打开的文件描述符。对于单个文件,可能会有许多个表示打开文件的文件描述符file结构,但他们都指单个inode结构。inode的dev_t i_rdev成员包含了真正的设备编号,struct cdev *i_cdev包含了指向struct cdev结构的指针。

struct file_operations

         file_operations结构保存了字符设备驱动程序的方法。它是一个在 <linux/fs.h> 中定义的 struct file_operations 结构,这是一个内核结构,不会出现在用户空间的程序中,它定义了常见文件 I/O 函数的入口。系统调用函数通过内核,最终调用对应的 struct file_operations 结构的接口函数(例如,open() 文件操作是通过调用对应文件的file_operations 结构的 open 函数接口而被实现)。当然,每个设备的驱动程序不一定要实现其中所有的函数操作,若不需要定义实现时,则只需将其设为 NULL 即可。

驱动程序的简单模板:

#include 
#include
MODULE_LICENSE("GPL");//模块开源许可声明/* 模块加载时的初始化函数 */// __init的意思是将代码放入特定的初始化内存区域,初始化后空间可以回收static int __init myinit(void){ printk(KERN_CRIT"hello mymodule!\n"); printk(KERN_CRIT"module name :%s\n",THIS_MODULE->name); return 0;//内核编程,有返回值的一定不要遗漏}module_init(myinit);//告知系统哪个是初始化函数/* 模块清理函数 *///__exit的意思是如果以后不卸载则不要放入系统static void __exit myexit(void){ printk(KERN_CRIT"goodbye cruel world\n");}module_exit(myexit);//告知系统哪个是清理函数
设备号和设备类的创建和销毁:

#include 
#include
#include
//设备号注册相关#include
//class和device相关MODULE_LICENSE("GPL");dev_t devno;//设备号struct class *cls; //设备类static int __init myinit(void){//在模块初始化时,动态申请前设备号 alloc_chrdev_region(&devno,10,1,"mydev"); cls=class_create(THIS_MODULE,"myclass");//创建类 device_create(cls,NULL,devno,NULL,"mynewdev");//在类下面创建设备 printk("major is %d, minor is %d\n",MAJOR(devno),MINOR(devno)); return 0;}module_init(myinit);static void __exit myexit(void){//模块清理的时候,反注册设备号 device_destroy(cls,devno);//销毁设备 class_destroy(cls);//销毁类 unregister_chrdev_region(devno,1);//反注册设备号}module_exit(myexit);

转载地址:http://kflab.baihongyu.com/

你可能感兴趣的文章
Linux下的内网反弹实例
查看>>
Command execution with a MySQL UDF
查看>>
OTPs: Using s/Key with SSH via OPIE
查看>>
使用arpwatch和arping来排查ARP攻击
查看>>
Linux硬件监控方法
查看>>
RSA SecurID Authentication linux sshd PAM deploy
查看>>
转: pam 禁止某些用户使用ssh 远程登录
查看>>
小包优先+web优先+游戏爆发+单IP限速+连接数限制 脚本V2.0
查看>>
Rhel5 配置NTP服务
查看>>
定制rhel的stage2.img/minstg2.img文件
查看>>
ZZ Quick-Tip: Linux NAT in Four Steps using iptables
查看>>
北京的住房公积金是否可用于还外地的房贷
查看>>
mysqlhotcopy 热备工具体验与总结
查看>>
MooseFS安装笔记
查看>>
GlusterFS分布式集群文件系统安装、配置及性能测试
查看>>
Sakai
查看>>
Adobe ColdFusion Unspecified Directory Traversal Vulnerability
查看>>
Share:A File Checksum Integrity Verifier utility
查看>>
LDAP User Authentication On CentOS 5.x
查看>>
Cpanel PHP Restriction Bypass Vulnerability 0day
查看>>