一文讲解Linux内核——设备驱动程序,详细了解

2023-05-16

----- 设备驱动程序通常又称为设备处理程序,它是I/O进程与设备控制器之间的通信程序,又由于它常以进程的形式存在,可简称之为

设备驱动进程。其主要任务是接收上层软件发来的抽象I/O要求,如read或write命令,在把它转换为具体要求后,发送给设备控制器,启动

设备去执行;此外,它也将从设备控制器发来的信号传送给上层软件。

----- 由于驱动程序与硬件密切相关,故应为每一类设备配置一种驱动程序,有时也可为非常类似的两类设备配置一个驱动程序。例如,打印机

和显示器需要不同的驱动程序,但SCSI磁盘驱动程序通常可以处理不同大小和不同速度的多个SCSI磁盘,甚至还可以处理SCSI CD-ROM。

1、设备驱动程序的功能

为了实现I/O进程与设备控制器之间的通信,设备驱动程序应具有以下功能:

-- 1)接收由设备独立性软件发来的命令和参数,并将命令中的抽象要求转换为具体要求。

例如,将磁盘块号转换为磁盘的盘面、磁道号及扇区号。

-- 2)检查用户I/O请求的合法性,了解I/O设备的状态,传递有关参数,设置设备的工作方式。

-- 3)发出I/O命令。

如果设备空闲,便立即启动I/O设备去完成指定的I/O操作;如果设备处于忙碌状态,则将请求者的请求块挂在设备队列上等待。

-- 4)及时响应由控制器或通道发来的中断请求,并根据其中断类型调用相应的中断处理程序进行处理。

-- 5)对于设置有通道的计算机系统,驱动程序还应能够根据用户的I/O请求,自动地构成通道程序

2、设备处理方式

在不同的操作系统中所采用的设备处理方式并不完全相同。

根据在设备处理时是否设置进程,以及设置什么样的进程而把设备处理方式分成以下三类:

---- 1)为每一类设备设置一个进程,专门用于执行这类设备的I/O操作。

比如,为所有的交互式终端设置一个交互式终端进程;为同一类型的打印机设置一个打印进程。

---- 2)在整个系统中设置一个I/O进程,专门用于执行系统中所有各类设备的I/O操作。

也可以设置一个输入进程和一个输出进程,分别处理系统中所有各类设备的输入和输出操作。

---- 3)不设置专门的设备处理进程,而只为各类设备设置相应的设备处理程序(模块),供用户进程或系统进程调用。

3、设备驱动程序的特点

设备驱动程序属于低级的系统例程,它与一般的应用程序及系统程序之间有下述明显差异:

--- 1)驱动程序主要是指在请求I/O的进程与设备控制器之间的一个通信和转换程序。

它将进程的I/O请求经过转换后,传送给控制器;又把控制器中所记录的设备状态和I/O操作完成情况及时的反应给请求I/O的进程。

--- 2)驱动程序与设备控制器和I/O设备的硬件特性紧密相关,因而对不同类型的设备应配置不同的驱动程序。

例如,可以为相同的多个终端设置一个终端驱动程序,但有时即使是同一类型的设备,由于其生产厂家不同,他们也可能并不完全兼容,

此时也需为它们配置不同的驱动程序。

--- 3)驱动程序与I/O设备所采用的I/O控制方式紧密相关。

常用的I/O控制方式是中断驱动和DMA方式,这两种方式的驱动程序明显不同,后者是按数组方式启动设备及进行中断处理。

--- 4)由于驱动程序与硬件紧密相关,因而其中的一部分必须用汇编语言编写。目前有很多驱动程序的基本部分,已经固化在ROM中。

--- 5)驱动程序应允许可重入。一个正在运行的驱动程序常会在一次调用完成前被再次调用。

例如,网络驱动程序正在处理一个到来的数据包时,另一个数据包可能已经到达。

--- 6)驱动程序不允许系统调用。

但是为了满足其与内核其它部分的交互,可以允许对某些内核过程的调用。如通过调用内核过程来分配和释放内存页面作为缓冲区。

4、设备驱动程序的处理过程

不同类型的设备应有不同的设备驱动程序,但大体上它们都可以分成两部分:

--------- 能够驱动I/O设备工作的驱动程序

--------- 设备中断处理程序(处理I/O完成后的工作)。

设备驱动程序的主要任务是启动指定设备。但在启动之前,还必须完成必要的准备工作,如检测设备状态是否为“忙”等。在完成所有的准备

工作后,才向设备控制器发送一条启动命令。以下是设备驱动程序的处理过程:

-- 1)将抽象要求转换为具体要求

由于用户及上层软件对设备控制器的具体情况毫无了解,因而只能向它发出抽象的要求(命令),但这些命令无法传送给设备控制器。因此

就需要将这些抽象要求转换为具体要求。这一转换工作只能由驱动程序来完成,因为在OS中只有驱动程序才同时了解抽象要求和设备控制器

中的寄存器情况;也只有它才知道命令、参数和数据应分别送往哪个寄存器。

-- 2)检查I/O请求的合法性

-- 3)读出和检查设备的状态

-- 4)传送必要的参数

对于许多设备,特别是块设备,除必须向其控制器发送启动命令外,还需传送必要的参数。例如在启动磁盘进行读/写之前,应先将本次要传送

的字节数和数据应到达的主存始址,送入控制器的相应寄存器中。

-- 5)工作方式的设置

-- 6)启动I/O设备

驱动程序发出I/O命令后,基本的I/O操作是在设备控制器的控制下进行的。通常,I/O操作所要完成的工作较多,需要一定的时间,如读/写一个

盘块中的数据,此时驱动(程序)进程把自己阻塞起来,直到中断到来时才将它唤醒。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一文讲解Linux内核——设备驱动程序,详细了解 的相关文章

  • C++ Boost ASIO 简单的周期性定时器?

    我想要一个非常简单的周期性计时器每 50 毫秒调用我的代码 我可以创建一个始终休眠 50 毫秒的线程 但这很痛苦 我可以开始研究用于制作计时器的 Linux API 但它不可移植 I d like使用升压 我只是不确定这是否可能 boost
  • Windows CE 与嵌入式 Linux [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 现在我确信我们都清楚 Linux 与 Windows 桌面的相对优点 然而 我对嵌入式开发世界的了解却少得多 我主要对行业解决方案感兴
  • 捕获实时流量时如何开启纳秒精度?

    如何告诉 libpcap v1 6 2 将纳秒值存储在struct pcap pkthdr ts tv usec 而不是微秒值 捕获实时数据包时 Note This question is similar to How to enable
  • 为什么C Clock()返回0

    我有这样的事情 clock t start end start clock something else end clock printf nClock cycles are d d n start end 我总是得到输出 时钟周期是 0
  • 每个命令都返回“bash:<命令>:找不到命令...”[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我刚刚安装了 Scala 并添加了路径gedit bashrc export SCALA HOME home avijit sca
  • 后台分叉无法正常工作[重复]

    这个问题在这里已经有答案了 我运行这个程序 在前景和背景中 int main int pid printf App Start pid d n getpid while 1 pid fork if pid 0 printf Child n
  • 嵌入式linux编写AT命令

    我在向 GSM 模块写入 AT 命令时遇到问题 当我使用 minicom b 115200 D dev ttySP0 term vt100 时它工作完美 但我不知道如何在 C 代码中做同样的事情 我没有收到任何错误 但模块对命令没有反应 有
  • Linux中使用管道进行进程间通信

    我已经编写了在 linux 中写入数字以进行管道传输的代码 如下所示 但显示错误 任何人都可以帮助我解决这个问题 基本上该程序的问题陈述如下 一个程序将打开一个管道 向管道写入一个数字 其他程序将打开同一管道 读取数字并打印它们 关闭两个管
  • 使用 inotify 的正确方法是什么?

    我想使用inotifyLinux 上的机制 我希望我的应用程序知道文件何时aaa被改变了 您能给我提供一个如何做到这一点的示例吗 文档 来自监视文件系统活动 inotify https developer ibm com tutorials
  • 如何将后台作业的输出分配给 bash 变量?

    我想在 bash 中运行后台作业并将其结果分配给一个变量 我不喜欢使用临时文件 并且希望同时运行多个类似的后台任务 root root var echo hello world root root echo var hello world
  • 从c调用汇编函数

    我试图从 c 调用汇编函数 但我不断收到错误 text globl integrate type integrate function integrate push ebp mov esp ebp mov 0 edi start loop
  • 从 Python 访问 802.11 无线管理帧

    我想从 Linux 上的 Python 嗅探 802 11 管理 探测请求 帧 这可以从 Scapy 中实现 如下所示 coding utf 8 from scapy all import def proc p if p haslayer
  • Linux“屏幕”的 Windows 等效项还是其他替代方案?

    我正在寻找一种在 Windows 环境中控制程序的方法 我希望它与 Linux 软件有点相似 screen 我搜索的原因是我需要使用标识符启动一个程序 在 Windows 上 这样我以后就能够关闭该特定程序 而无需关闭其他任何程序 即使实际
  • 用于编辑 /etc/sudoers 文件的正则表达式模式

    我想删除 etc sudoers 文件中的 uncommnet 轮组 那么我应该使用什么正则表达式模式 cat etc sudoers Allows members of the sys group to run networking so
  • 如何从 Linux 内核模块获取使用计数?

    我对正在开发的内核模块的使用计数有疑问 我想打印它以进行调试 如何从模块代码中获取它 有问题的内核版本 Linux 2 6 32 module refcount http lxr linux no linux v2 6 34 1 inclu
  • 错误:命令“c++”失败,退出状态为 1

    所以我尝试按照以下说明安装 Pyv8https andrewwilkinson wordpress com 2012 01 23 integrating python and javascript with pyv8 https andre
  • 使用 gcc 理解共享库

    我试图理解 C 中共享库的以下行为 机器一 cat one c include
  • 在 Linux 上创建线程与进程的开销

    我试图回答在 python 中创建线程与进程有多少开销的问题 我修改了类似问题的代码 该问题基本上运行一个带有两个线程的函数 然后运行带有两个进程的相同函数并报告时间 import time sys NUM RANGE 100000000
  • 如何在 Linux 中重新添加 unicode 字节顺序标记?

    我有一个相当大的 SQL 文件 它以 FFFE 的字节顺序标记开头 我使用 unicode 感知的 linux 分割工具将此文件分割成 100 000 行块 但是当将这些传递回窗口时 它确实not与第一个部分以外的任何部分一样 只是它具有
  • 运行此处编译的 C 程序会导致在另一台服务器上找不到 GLIBC 库错误 - 是我的错还是他们的错?

    此处编译的 C 程序在我们的 Ubuntu 服务器上运行良好 但是当其他人尝试在他们的特定 Linux 服务器上运行它时 他们会收到以下错误 myprog install lib tls libc so 6 version GLIBC 2

随机推荐