Linux内核驱动介绍(1)

驱动介绍

定义

个人认为驱动就是在底层对于该设备的一些接口进行自己的定义,然后封装成一个个模块,然后让用户在应用层进行自我调用。以下是比较正统的定义。

驱动程序在 Linux 内核里扮演着特殊的角色。 它们是截然不同的”黑盒子”, 使硬件的特殊的一部分响应定义好的内部编程接口。 它们完全隐藏了设备工作的细节. 用户的活动通过一套标准化的调用来进行, 这些调用与特别的驱动是独立的; 设备驱动的角色就是将这些调用映射到作用于实际硬件的和设备相关的操作上。 这个编程接口是这样, 驱动可以与内核的其他部分分开建立, 并在需要的时候在运行时”插入”。

特点

  1. Linux下对于外部设备只能通过驱动进行访问,同时对于一些接口的调用有统一的方程可以使用。
  2. 驱动程序运用的地址是内核的地址,而不是虚拟地址。
  3. 驱动程序是直接对设备硬件进行控制操作的。

    驱动分类

  4. 字符设备驱动
  5. 块设备驱动
  6. 网络接口驱动

字符设备:是一种按字节来访问的设备,字符驱动则负责驱动字符设备,这样的驱动通常实现open、close、read和write系统调用。
块设备:在大多数UNIX系统,块设备不能按字节处理数据,只能一次传送一个或多个长度是512字节(或一个更大的2次幂的数)的整块数据。
网络接口:任何网络事务都通过一个接口来进行,一个接口通常是一个硬件设备(eth0),但是也可以是一个纯粹的软件设备,如回环接口(lo)。一个网络接口负责发送和接受数据报文。 以上的标示和对应数据会在mac系统上用ifconfig在终端中获取。

字符设备

字符设备组成

  • 设备号
  • 创建设备文件
  • 设备注册
  • 重要数据结构
  • 设备操作

    主次设备号

    主次设备号组成一个设备的设备号。主在前,次在后。
    分配住主备号有两种:
  • 静态申请
  • 动态申请

    静态申请

    一般用 cat /proc/devices 确定一个设备号有没有被使用,然后用register_chrdev_region 函数进行注册设备号。

    缺点

    如果不每次查找是否有该设备,会容易发生设备号冲突,导致驱动程序无法注册。每次查找又很麻烦。

    具体函数及操作

    功能
    1
    int register_chrdev_region(dev_t from,unsigned count,const char *name)
参数

from:为主设备号与次设备号的组合
count:为要注册的设备号的数量
name: 设备名字(具体体现在proc/devices 中显示的名字)

动态申请

用alloc_chrdev_region分配设备号,不需要查表。但是设备号得在安装完驱动后才能获取,因为安装前没有分配主设备号。

具体函数及操作

功能
1
int alloc_chrdev_region(dev_t *dev,unsigned baseminor,unsigned count,const char *name)
参数

dev: 分配到的设备号
 baseminor: 起始次设备号
 count: 要注册的设备号个数
 name: 设备名

篇幅有限,之后的见下一篇。