当前位置: 首页 > news >正文

【驱动】linux设备驱动·扫盲

linux设备驱动

   Linux系统把设备驱动分成字符设备块设备网络设备三种类型。

内核为设备驱动提供了注册和管理的接口,设备驱动还可以使用内核提供的其他功能以及访问内核资源。



PCI局部总线

   早期的计算机有众多总线标准。从最初的8位总线到16位总线,到目前主流的32位总线,不同厂商都制定了自己的总线标准。不同的总线设备给设备驱动的设计带了麻烦,直到后来PCI局部总线出台这种局面才得到缓解,并且逐步成为事实上的标准。

   PCI是英文Peripheral Component Interconnect的缩写,中文意思是外设部件互连标准

   PCI局部总线标准最早由英特尔公司为制定,最初主要应用在PC机。目前已经被越来越多的嵌入式系统已经其他类型的计算机系统使用。

   设计PCI的原因是由于之前的总线有许多的缺点,归纳总结为以下几点:

    • 总线速度过慢。

    • 总线地址分配方法复杂。

    • 总线资源共享效率低。

   PCI总线采用软件配置地址和其它总线信息的方法,避免了手工配置设备在总线地址带来的麻烦,此外,PCI还支持通过桥的方式扩展总线的处理能力。



Linux设备驱动基本概念

   在Linux系统中,所有的资源都是作为文件管理的,设备驱动也不例外,设备驱动通常是作为一类特殊的文件存放在/dev目录下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
total 0
crw-------  1 root root     10,  58 Jun  8 11:40 alarm
crw-------  1 root root     10,  59 Jun  8 11:40 ashmem
crw------T  1 root root     10, 235 Jun  8 11:40 autofs
crw-------  1 root root     10,  60 Jun  8 11:40 binder
drwxr-xr-x  2 root root         740 Jun  8  2013 block
drwxr-xr-x  2 root root          80 Jun  8  2013 bsg
crw------T  1 root root     10, 234 Jun  8 11:40 btrfs-control
drwxr-xr-x  3 root root          60 Jun  8  2013 bus
lrwxrwxrwx  1 root root           3 Jun  8 11:40 cdrom -> sr0
lrwxrwxrwx  1 root root           3 Jun  8 11:40 cdrw -> sr0
drwxr-xr-x  2 root root        3700 Jun  8 11:40 char
crw-------  1 root root      5,   1 Jun  8 11:40 console
lrwxrwxrwx  1 root root          11 Jun  8 11:40 core ->  /proc/kcore
drwxr-xr-x  2 root root          60 Jun  8 11:40 cpu
crw-------  1 root root     10,  57 Jun  8 11:40 cpu_dma_latency
drwxr-xr-x  6 root root         120 Jun  8  2013 disk


   这里仅列出了一部分文件,设备文件属性最开始的一个字符c表示该设备文件关联的是一个字符设备b表示关联的是一个块设备在文件列表的中间部分有两个数字,第一个数字称做主设备号,第二个数字称做次设备号。

在内核中使用主设备号标识一个设备,次设备号提供给设备驱动使用。

   在打工一个设备的时候,内核会根据设备的主设备号得到设备驱动,并且把次设备传递给驱动。linux内核为所有设备都分配了主设备号,在编写驱动程序之前需要参考内核代码Documentation/devices.txt文件,确保使用的设备号没有被占用。

在使用一个设备之前,需要使用linux提供的mknod命令建立设备文件。mknod命令格式如下

1
mknod  [OPTION] ... NAME TYPE [MAJOR MINOR]

   其中,NAME是设备文件名称TYPE是设备类型,c代码字符设备,b代表块设备;MAJOR是主设备号MINOR是次设备号OPTION是选项-m参数用于指定设备文件访问权限。

   linux内核按照外部设备工作特点把设备分成了字符设备、块设备和网络设备3种基本类型。

在编写设备驱动的时候,需要使用内核提供的设备驱动接口,向内核提供具体设备的操作方法。



字符设备

   字符设备是Linux系统最简单的一类设备。

应用程序可以像操作普通文件一样操作字符设备。常见的串口、调制解调器都是字符设备。

   编写字符设备驱动需要使用内核提供的register_chardev()函数注册一个字符设备驱动。

   函数定义如下:

1
int  register_chrdev(unsigned  int  major,  const  char  *name,  struct  file_operations *fops);

   fops是指向函数指针数组的结构指针,驱动程序的入口函数都包括在这个指针内部。    

该函数的返回值如果小于0表示注册设备驱动失败,如果设置major为0,表示由内核动态分配主设备号,函数的返回值是主设备号。    

   当使用register_chardve()函数成功注册一个字符设备后,会在/proc/devices文件中显示出设备信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
mystery@lcw:~$  cat  /proc/devices
Character devices:
   1 mem
   /dev/vc/0
   tty
   4 ttyS
   7 vcs
  10 misc
  13 input
  21 sg
  29 fb
  99 ppdev
108 ppp
253 watchdog
254 rtc
Block devices:
   1 ramdisk
259 blkext
   7 loop
   8 sd
   9 md
252 device-mapper
253 virtblk
254 mdp

   删除了一些,其中Character devices是字符设备驱动列表Block devices是块设备驱动列表数字代表主设备驱动,后面是设备驱动名称。

   与注册驱动相反,内核提供了unregister_chardev()函数卸载设备驱动or

1
int  unregister_chrdev(unsigned  int  major,  const  char  *name);

   内核会比较设备驱动名称与设备号是否相同,如果不同函数返回-EINVAL。错误地卸载设备驱动会带来严重后果,因此在卸载驱动的时候应该对函数返回值做判断。

   在register_chardev()函数中有一个fops参数,该参数指向一个file_operation结构,该结构包含了驱动上的所有操作。随着内核功能的不断增加,file_operations结构的定义也越来越复杂。

   大部分驱动都没有提供所有的函数,对于字符设备来说,常用的函数如下

123810707.jpg



块设备

   与字符设备相比,块设备要复杂的多。

   最主要的差别是块设备带有缓冲,字符设备没有。

块设备传输数据只能以块作为单位读写,字符设备是以字节作为最小读写单位的。块设备对于I/O请求有对应的缓冲区,可以选择响应的顺序,如采用特定的调度策略等;字符设备只能顺序访问。

   此外,块设备提供了随机访问的能力,而字符设备之顺序读取数据。

   块设备提供了一个类似字符设备的访问函数结构block_device_operations,定义如下

1
2
3
4
5
6
7
8
9
10
11
12
13
struct  block_device_operations
{
     int  (*open) ( struct  inode *,  struct  file *);
     int  (*release) ( struct  inode *,  struct  file *);
     int  (*ioctl) ( struct  inode *,  struct  file *, unsigned, unsigned  long );
     long  (*unlocked_ioctl) ( struct  file *, unsigned, unsigned  long );
     long  (*compat_ioctl) ( struct  file *, unsigned, unsigned  long );
     int  (*direct_access) ( struct  block_device *, sector_t, unsigned  long  *);
     int  (*media_changed) ( struct  gendisk *);
     int  (*revalidate_disk) ( struct  gendisk *);
     int  (*getgeo)( struct  block_device *,  struct  hd_geometry *);
     struct  module *owner;
};

   其中,open、release、ioctl等函数的功能与字符设备相同。

块设备提供了几个特有的函数成员:

    • media_change()函数用来检查介质是否改变,主要用于检查可移动设备;

    • revalidate_disk()函数响应物理介质的改变请求;

    • getgen()函数用于向系统汇报驱动器信息。



网络设备

   在Linux内核中,网络设备是一类特殊的设备,因此被单独设计为一种类型的驱动。

   与其他设备不同的是,网络设备不是通过设备文件访问的,在/dev目录下不会看到任何网络设备。因此,网络设备的操作不是通过文件操作实现的。

   Linux内核为了抽象网络设备界面,为其定义了一个接口用于屏蔽网络环境下各种网络设备的差别。内核对所有网络设备的访问都通过这个抽象的接口,接口对上层网络协议提供相同的操作方法。


本文转自infohacker 51CTO博客,原文链接:http://blog.51cto.com/liucw/1218747



相关文章:

  • 对Context的重新思考
  • 在RHEL5下构建LAMP网站服务平台之架设Discuz!论坛
  • 依赖倒置原则
  • .net Application的目录
  • React Router
  • 【干货分享】常用端口服务对照表
  • IO操作
  • 【Window OS】解决Win7远程桌面无法全屏的方法
  • Enterprise Library Step By Step系列(十五):配置应用程序块——设计篇
  • JAVA 线程池之Callable返回结果
  • 用户系列之五:用户SID查看之终结版
  • SQLite第二课 源码下载编译
  • 查看Linux服务器网卡流量小脚本shell和Python各一例
  • 6.4 xz压缩工具
  • Memcached通用类(基于enyim.com Memcached Client)
  • 2017 前端面试准备 - 收藏集 - 掘金
  • Bootstrap JS插件Alert源码分析
  • co.js - 让异步代码同步化
  •  D - 粉碎叛乱F - 其他起义
  • express + mock 让前后台并行开发
  • JS题目及答案整理
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • Vim Clutch | 面向脚踏板编程……
  • Vue 2.3、2.4 知识点小结
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 番外篇1:在Windows环境下安装JDK
  • 近期前端发展计划
  • 看域名解析域名安全对SEO的影响
  • 那些被忽略的 JavaScript 数组方法细节
  • 扑朔迷离的属性和特性【彻底弄清】
  • 前端面试题总结
  • 如何编写一个可升级的智能合约
  • 实战|智能家居行业移动应用性能分析
  • 小程序 setData 学问多
  • 学习ES6 变量的解构赋值
  • 一起参Ember.js讨论、问答社区。
  • 运行时添加log4j2的appender
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • # centos7下FFmpeg环境部署记录
  • # include “ “ 和 # include < >两者的区别
  • #pragma multi_compile #pragma shader_feature
  • #考研#计算机文化知识1(局域网及网络互联)
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • (Python) SOAP Web Service (HTTP POST)
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (算法)N皇后问题
  • (转载)Linux 多线程条件变量同步
  • (转载)深入super,看Python如何解决钻石继承难题
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .net core 控制台应用程序读取配置文件app.config