深入理解Linux内核--I/0体系结构和设备驱动程序

news2024/12/27 9:30:57

I/0体系结构和设备驱动程序

I/O体系结构

为了确保计算机能够正常工作,必须提供数据通路,让信息在连接到个人计算机的CPU、RAM和I/O设备之间流动。
这些数据通路总称为总线,担当计算机内部主通信通道的作用。

所有计算机都拥有一条系统总线,它连接大部分内部硬件设备。
一种典型的系统总线是PCl(Peripheral Component Interconnect)总线。
目前使用其他类型的总线也很多,例如ISA、EISA、MCA、SCSI和USB。
典型的情况是,一台计算机包括几种不同类型的总线,它们通过被称作“桥”的硬件设备连接在一起。
两条高速总线用于在内存芯片上来回传送数据:
前端总线将CPU连接到RAM控制器上,
而后端总线将CPU直接连接到外部硬件的高速缓存上。
主机上的桥将系统总线和前端总线连接在一起。

任何I/O设备有且仅能连接一条总线。
总线的类型影响I/O设备的内部设计,也影响着内核如何处理设备。
本节我们将讨论所有PC体系结构共有的功能性特点,而不具体介绍特定总线类型的技术细节。

CPU和I/O设备之间的数据通路通常称为I/O总线。
80x86微处理器使用I6位的地址总线对I/O设备进行寻址,使用8位、16位或32位的数据总线传输数据。
每个I/O设备依次连接到I/O总线上,这种连接使用了包含3个元素的硬件组织层次:
I/O端口、接口和设备控制器。
图13-1显示了I/O体系结构的这些成分。

在这里插入图片描述

I/O端口

每个连接到I/O总线上的设备都有自己的I/O地址集,通常称为I/O端口(1/O port)。
在IBM PC体系结构中,I/O地址空间一共提供了65536个8位的I/O端口。
可以把两个连续的8位端口看成一个16位端口,但是这必须从偶数地址开始。
同理,也可以把两个连续的I6位端口看成一个32位端口,但是这必须是从4的整数倍地址开始。
有四条专用的汇编语言指令可以允许CPU对I/O端口进行读写,
它们是in、ins、out.和outs。
在执行其中的一条指令时,
CPU使用地址总线选择所请求的I/O端口,
使用数据总线在CPU寄存器和端口之间传送数据。

I/O端口还可以被映射到物理地址空间。
因此,处理器和I/O设备之间的通信就可以使用对内存直接进行操作的汇编语言指令(例如,mov、and、or等等)。
现代的硬件设备更倾向于映射的I/O,因为这样处理的速度较快,并可以和DMA结合起来。

系统设计者的主要目的是对I/O编程提供统一的方法,但又不牺牲性能。
为了达到这个目的,每个设备的I/O端口都被组织成如图13-2所示的一组专用寄存器。
CPU把要发送给设备的命令写入设备控制寄存器(device control register),
并从设备状态寄存器(device status register)中读出表示设备内部状态的值。
CPU还可以通过读取设备输入寄存器(device input register)的内容从设备取得数据,
也可以通过向设备输出寄存器(device output register)中写入字节而把数据输出到设备。

在这里插入图片描述

为了降低成本,通常把同一I/O端口用于不同目的。
例如,某些位描述设备的状态,而其他位指定向设备发出的命令。
同理,也可以把同一I/O端口用作输入寄存器或输出寄存器。

访问I/O端口

in、out、ins和outs汇编语言指令都可以访问I/O端口。内核中包含了以下辅助函数来简化这种访问:
inb(),inw(),inl()
	分别从I/O端口读取1、2或4个连续字节。后缀“b”、“w”、“I”分别代表一个字节(8位)、一个字(16位)以及一个长整型(32位)。
inb_p(),inw_p(),inl_p()
	分别从I/O端口读取1、2或4个连续字节,然后执行一条“哑元(dummy,即空指令)”指令使CPU暂停。
outb(),outw(),outl()
	分别向一个I/O端口写入1、2或4个连续字节。
outb_p(),outw_p(),outl_p()
	分别向一个I/O端口写入1、2或4个连续字节,然后执行一条“哑元”指令使CPU 暂停。
insb(),insw(),insl()
	分别从I/O端口读取以1、2或4个字节为一组的连续字节序列。字节序列的长度由该函数的参数给出。
outsb(),outsw(),outsl()
	分别向I/O端口写入以1、2或4个字节为一组的连续字节序列。
虽然访问I/O端口非常简单,但是检测哪些I/O端口已经分配给I/O设备可能就不这么简单了,对基于ISA总线的系统来说更是如此。
通常,I/O设备驱动程序为了探测硬件设备,需要盲目地向某一I/O端口写入数据;
但是,如果其他硬件设备已经使用了这个端口,那么系统就会崩溃。
为了防止这种情况的发生,内核必须使用“资源”来记录分配给每个硬件设备的I/O端口。

资源(resource)表示某个实体的一部分,这部分被互斥地分配给设备驱动程序。
在我们的情况中,一个资源表示I/O端口地址的一个范围。每个资源对应的信息存放在resource数据结构中,其字段如表13-1所示。
所有的同种资源都插入到一个树型数据结构中;
例如,表示I/O端口地址范围的所有资源都包含在一个根节点为ioport_resource 的树中。

在这里插入图片描述

	节点的孩子被收集在一个链表中,其第一个元素由child指向。sibling字段指向链表中的下一个节点。
	为什么使用树?
	例如,考虑一下IDE硬盘接口所使用的I/O端口地址——比如说从0xf000到0xf00f。
	然后,start字段为0xf000且end字段为0xf00f的这样一个资源包含在树中,控制器的常规名字存放在name字段中。
	但是,IDE设备驱动程序需要记住另外的信息,
	也就是IDE链(IDE chain)的主盘(master disk)使用0xf000~0xf007 的子范围,
	从盘(slave disk)使用0xf008~0xf00f的子范围。
	为了做到这点,设备驱动程序把两个子范围对应的孩子插入到0xf000~0xf00f的整个范围对应的资源下。
	一般来说,树中的每个节点肯定相当于父节点对应范围的一个子范围。
	I/O端口资源树(ioport_resource)的根节点跨越了整个I/O地址空间(从端口0~65535)。

	任何设备驱动程序都可以使用下面三个函数,传递给它们的参数为资源树的根节点和要插入的新资源数据结构的地址:
request_resource()
	把一个给定范围分配给一个I/O设备。
allocate_resource()
	在资源树中寻找一个给定大小和排列方式的可用范围;
	若存在,就将这个范围分配给一个I/O设备
	(主要由PCI设备驱动程序使用,这种驱动程序可以配置成使用任意的端口号和主板上的内存地址对其进行配置)。
release_resource()
	释放以前分配给I/O设备的给定范围。
内核也为以上应用于I/O端口的函数定义了一些快捷函数:
request_region()分配I/O 端口的给定范围,
release_region()释放以前分配给I/O端口的范围。
当前分配给I/O 设备的所有I/O地址的树都可以从/proc/ioports文件中获得。

I/O接口

I/O接口(1/0 interface)是处于一组I/O端口和对应的设备控制器之间的一种硬件电路。
它起翻译器的作用,即把I/O端口中的值转换成设备所需要的命令和数据。
在相反的方向上,它检测设备状态的变化,并对起状态寄存器作用的I/O端口进行相应的更新。
还可以通过一条IRQ线把这种电路连接到可编程中断控制器上,以使它代表相应的设备发出中断请求。
有两种类型的接口:
专用1/0接口
	专门用于一个特定的硬件设备。在一些情况下,设备控制器与这种I/O接口处于同一块卡中(注1)。
	连接到专用I/O接口上的设备可以是内部设备(位于PC机箱内部的设备),也可以是外部设备(位于PC机箱外部的设备)。
通用I/O接口
	用来连接多个不同的硬件设备。连接到通用I/O接口上的设备通常都是外部设备。
每块卡都要插入PC的一个可用空闲总线插槽中。
如果一块卡通过一条外部电缆连接到一个外部设备上,那么在PC后面的面板中就有一个对应的连接器。

专用IO接口

专用I/O接口的种类很多,因此目前已装在PC上设备的种类也很多,我们无法一一列出,在此只列出一些最通用的接口:
键盘接口
	连接到一个键盘控制器上,这个控制器包含一个专用微处理器。
	这个微处理器对按下的组合键进行译码,产生一个中断并把相应的键盘扫描码写入输入寄存器。
图形接口
	和图形卡中对应的控制器封装在一起,图形卡有自己的帧缓冲区,还有一个专用处理器以及存放在只读存储器(ROM)芯片中的一些代码。
	帧缓冲区是显卡上固化的存储器,其中存放的是当前屏幕内容的图形描述。
磁盘接口
	由一条电缆连接到磁盘控制器,通常磁盘控制器与磁盘放在一起。
	例如,IDE接口由一条40线的带形电缆连接到智能磁盘控制器上,在磁盘本身就可以找到这个控制器。
总线鼠标接口
	由一条电缆把接口和控制器连接在一起,控制器就包含在鼠标中。
网络接口
	与网卡中的相应控制器封装在一起,用以接收或发送网络报文。虽然广泛采用的网络标准很多,但还是以太网(IEEE 802.3)最为通用。

通用IO接口

现代PC都包含连接很多外部设备的几个通用I/O接口。最常用的接口有:
并口
	传统上用于连接打印机,它还可以用来连接可移动磁盘、扫描仪、备份设备、其他计算机等等。数据的传送以每次1字节(8位)为单位进行。
串口
	与并口类似,但数据的传送是逐位进行的。
	串口包括一个通用异步收发器(UART)芯片,它可以把要发送的字节信息拆分成位序列,也可以把接收到的位流重新组装成字节信息。
	由于串口本质上速度低于并口,因此主要用于连接那些不需要高速操作的外部设备,如调制解调器、鼠标以及打印机。
CMCIA接口
	大多数便携式计算机都包含这种接口。
	在不重新启动系统的情况下,这种形状类似于信用卡的外部设备可以被插入插槽或从插槽中拔走。
	最常用的PCMCIA设备是硬盘、调制解调器、网卡和扩展RAM。
SCSI(小型计算机系统接口)接口
	是把PC主总线连接到次总线(称为SCSI总线)的电路。
	SCSI-2总线允许一共8 个PC和外部设备(硬盘、扫描仪、CR-ROM刻录机等等)连接在一起。
	如果有附加接口,宽带SCSI-2和新的SCSI-3接口可以允许你连接多达16个以上的设备。
	SCSI标准是通过SCSI总线连接设备的通信协议。
通用串行总线(USB)
	高速运转的通用I/O接口,可用于连接外部设备,代替传统的并口、串口以及SCSI接口。

设备控制器

复杂的设备可能需要一个设备控制器(device controller)来驱动。从本质上说,控制器起两个重要作用:
1.对从I/O接口接收到的高级命令进行解释,并通过向设备发送适当的电信号序列强制设备执行特定的操作。
2.对从设备接收到的电信号进行转换和适当地解释,并修改(通过I/O接口)状态寄存器的值。
典型的设备控制器是磁盘控制器,它从微处理器(通过I/O接口)接收诸如“写这个数据块”之类的高级命令,
并将其转换成诸如“把磁头定位在正确的磁道上”和“把数据写入这个磁道”之类的低级磁盘操作。
现代的磁盘控制器相当复杂,因为它们可以把磁盘数据快速保存到内存的高速缓存中,
还可以根据实际磁盘的几何结构重新安排CPU的高级请求,使其最优化。

比较简单的设备没有设备控制器,
可编程中断控制器(参见第四章中的“中断和异常”一节)和可编程间隔定时器(参见第六章中的“可编程间隔定时器(PIT)一节)”就是这样的设备。

很多硬件设备都有自己的存储器,通常称之为I/O共享存储器。
例如,所有比较新的图形卡在帧缓冲区中都有几MB的RAM,用它来存放要在屏幕上显示的屏幕映像。
我们将在本章的“访问I/O共享存储器”一节中讨论I/O共享存储器。

设备驱动程序模型

Linux内核的早期版本为设备驱动程序的开发者提供微不足道的基本功能:
分配动态内存,
保留I/O地址范围或中断请求(IRQ),
激活一个中断服务例程来响应设备的中断。
事实上,在更老的硬件设备上编程棘手而困难重重,
还有即使两种不同的硬件设备连在同一条总线上,但二者也很少有共同点。
因此,试图为这种硬件设备的驱动程序开发者提供一种统一的模型是难以做到的。

现在的情形大不一样。
诸如PCI这样的总线类型对硬件设备的内部设计提出了强烈的要求;
因此,新的硬件设备即使类型不同但也有相似的功能。对这种设备的驱动程序应当特别关注:
1.电源管理(控制设备电源线上不同的电压级别)
2.即插即用(配置设备时透明的资源分配)
3.热插拔(系统运行时支持设备的插入和移走)
系统中所有硬件设备由内核全权负责电源管理。
例如,
在以电池供电的计算机进入“待机”状态时,内核应立刻强制每个硬件设备(硬盘、显卡、声卡、网卡、总线控制器等等)处于低功率状态。
因此,
每个能够响应“待机”状态的设备驱动程序必须包含一个回调函数,它能够使得硬件设备处于低功率状态。
而且,硬件设备必须按准确的顺序进人“待机”状态,
否则一-些设备可能会处于错误的电源状态。
例如,
内核必须首先将硬盘置于“待机”状态,
然后才是它们的磁盘控制器,
因为若按照相反的顺序执行,磁盘控制器就不能向硬盘发送命令。

为了实现这些操作,Linux 2.6提供了一些数据结构和辅助函数,它们为系统中所有的总线、设备以及设备驱动程序提供了一个统一的视图;
这个框架被称为设备驱动程序模型。

sysfs文件系统

sysfs文件系统是一种特殊的文件系统,被安装于/sys目录下的/proc文件系统相似。
/proc 文件系统是首次被设计成允许用户态应用程序访问内核内部数据结构的一种文件系统。
/sysfs文件系统本质上与/proc有相同的目的,但是它还提供关于内核数据结构的附加信息;
此外,/sysfs的组织结构比/proc更有条理。或许,在不远的将来,/proc和/sysfs将会继续共存。
sysfs文件系统的目标是要展现设备驱动程序模型组件间的层次关系。该文件系统的相应高层目录是:
block
	块设备,它们独立于所连接的总线。
devices
	所有被内核识别的硬件设备,依照连接它们的总线对其进行组织。
bus
	系统中用于连接设备的总线。
drivers
	在内核中注册的设备驱动程序。
class
	系统中设备的类型(声卡、网卡、显卡等等);同一类可能包含由不同总线连接的设备,于是由不同的驱动程序驱动。
power
	处理一些硬件设备电源状态的文件。
firmware
	处理一些硬件设备的固件的文件。
sysfs文件系统中所表示的设备驱动程序模型组件之间的关系就像目录和文件之间符号链接的关系一样。
例如,
文件/sys/block/sda/device可以是一个符号链接,
指向在/sys/devices/pci0000:00(表示连接到PCI总线的SCSI控制器)中嵌入的一个子目录。
此外,
文件/sys/block/sda/device/block是到目录/sys/block/sda的一个符号链接,这表明这个PCI设备是SCSI磁盘的控制器。

sysfs文件系统中普通文件的主要作用是表示驱动程序和设备的属性。
例如,
位于目录/sys/block/hda下的dev文件含有第一个IDE链主磁盘的主设备号和次设备号。

kobject

设备驱动程序模型的核心数据结构是一个普通的数据结构,叫做kobject,
它与sysfs文件系统自然地绑定在一起:每个kobject对应于sysfs文件系统中的一个目录。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/879534.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Hugging News #0814: Llama 2 学习资源大汇总

每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新、社区活动、学习资源和内容更新、开源库和模型更新等,我们将其称之为「Hugging News」。本期 Hugging News 有哪些有趣的消息&#xff0…

时序预测 | MATLAB实现WOA-CNN-BiLSTM鲸鱼算法优化卷积双向长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现WOA-CNN-BiLSTM鲸鱼算法优化卷积双向长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现WOA-CNN-BiLSTM鲸鱼算法优化卷积双向长短期记忆神经网络时间序列预测预测效果基本介绍程序设计学习总结参考资料 预测效果 基本介绍 时序预测 | MATLAB实现…

java练习3.分块查找

题目: 数组 arr{12,43,11,23,54,123,56,12,34} 利用分块排序, 进行从小到大的排序 public class recursionDemo {public static void main(String[] args) {int[] arr{12,43,11,23,54,123,56,12,34};//1.找到无序组 是从哪个元素开始的int startIndex0;for (int i 0; i < …

别人直播的时候怎么录屏?分享一些录屏方法

​随着互联网的快速发展&#xff0c;直播已经成为人们日常生活中不可或缺的一部分。但是&#xff0c;有时候我们可能会错过某些重要的直播内容&#xff0c;这时候就需要录屏来保存和观看。那么&#xff0c;如何录屏别人的直播呢&#xff1f;本文将分享一些录屏方法和技巧&#…

【计算机设计大赛】国赛一等奖项目分享——基于多端融合的化工安全生产监管可视化系统

文章目录 一、计算机设计大赛国赛一等奖二、项目背景三、项目简介四、系统架构五、系统功能结构六、项目特色&#xff08;1&#xff09;多端融合&#xff08;2&#xff09;数据可视化&#xff08;3&#xff09;计算机视觉&#xff08;目标检测&#xff09; 七、系统界面设计&am…

QGIS3.28的二次开发五:VS使用QT插件创建UI界面

前面我们说了在创建项目时创建的是一个空项目&#xff0c;即不使用 Qt 提供的综合开发套件 Qt Creator&#xff0c;也不使用 Qt Visual Studio Tools 这类工具。 但是后面发现&#xff0c;如果我想要有更加满意的界面布局&#xff0c;还是要自己写一个UI文件&#xff0c;如果不…

无涯教程-Perl - s函数

描述 这不是功能。这是正则表达式替换运算符。根据PATTERN中指定的正则表达式,将数据替换为REPLACE。与m //一样,分隔符由s后的第一个字符定义。 语法 以下是此函数的简单语法- s/PATTERN/REPLACE/返回值 如果失败,此函数返回0,如果成功,则返回替换次数。 例 以下是显示…

C数据结构与算法——常见排序算法时间复杂度比较 应用

实验任务 (1) 掌握常见比较排序算法的实现&#xff1b; (2) 掌握常用比较排序算法的性能及其适用场合。 实验内容 (1) 平均时间复杂度O(n2)和O(nlog2n)的算法至少各选两种实现&#xff1b; (2) 待排序的无重复关键字存放在一维整型数组中&#xff0c;数量为60000个&#xff…

TypeScript的泛型是什么,泛型约束是什么?

目录 一、泛型定义 二、泛型函数 1. 定义泛型函数 2. 调用泛型函数 3.简化泛型函数调用 三、泛型约束 1. 指定更加具体的类型 2. 添加约束 3.多个类型变量 四、泛型接口 一、泛型定义 在TypeScript中的泛型&#xff08;Generics&#xff09;允许我们在保证类型安全前…

微信小程序开发--4.2预览文件/图片

预览文件 wx.downloadFile({url:, success (res) {console.log(res)if (res.statusCode 200) {wx.openDocument({filePath: res.tempFilePath, showMenu: true,fileType: "xlsx",//文件类型success: function (res) {},fail:function(err){}})}}}) wx.openDocumen…

IO多线程newfd问题

1&#xff0c;多线程中的newfd&#xff0c;能否修改成全局&#xff1f; 答&#xff1a;不能&#xff0c;代码如下。 一共挂了4个客户端&#xff0c;前3个只能运行1次&#xff0c;第4个客户端可以发送多次。 说明后面的客户端覆盖了之前的客户端。前面的客户端一直阻塞在acce…

【力扣每日一题】2023.8.15 字符中的查找与替换

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目很长&#xff0c;简而言之就是检查字符串中对应索引的位置是否有特定的字符串&#xff0c;如果有&#xff0c;那么替换&#xff0c;返…

点击base64编码过的图片在另一个页面显示

开始的代码是这样的&#xff0c;新开一个窗口显示经过base64编码后的图片&#xff0c;但是url太长了显示失败。 openImage(imgSrc) {window.open(imgSrc, _blank); }, 解决方法&#xff1a;这段代码接收一个Base64编码的图像数据&#xff0c;把它转换为一个Blob对象。 Blob&…

《算法竞赛·快冲300题》每日一题:“房间划分”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 房…

考公-判断推理-组合排列

例题 例题 例题 代入法 例题 排除法 例题

AMD限制资源用量CU_MASK

通过配置两个环境变量来控制进程所使用的CU&#xff1a; CU_MASK_0 CU_MASK_1 举例&#xff1a; 使用每个ES中的一半CU则配置如下&#xff1a; export CU_MASK_00xcccccccc export CU_MASK_10xcccccccc

判断推理 -- 图形推理 -- 位置规律

一组图&#xff1a;从前往后找规律。 二组图&#xff1a;从第一组图找规律&#xff0c;第二组图应用规律。 九宫格&#xff1a; 90%横着看找规律&#xff0c;第一行找规律&#xff0c;第二行验证规律&#xff0c;第三行应用规律。 所有有元素组成都是线&#xff0c;三角形&…

【C++ STL基础入门】初识STL

文章目录 前言一、STL是什么&#xff1f;1.STL概念2.容器是什么&#xff1f;3.STL的优势 二、将会学习到的stl和算法1.将会学到的容器2.算法3.字符串基础字符串字符串视图(basic_string_view) 总结 前言 本系列STL是以VS2022为编译器&#xff0c;C20为标准来写的一套STL。 ST…

笔记04:全局内存

一、CUDA内存模型概述 寄存器、共享内存、本地内存、常量内存、纹理内存和全局内存 一个核函数中的线程都有自己私有的本地内存。 一个线程块有自己的共享内存&#xff0c;对同一个线程块中所有的线程都可见&#xff0c;其内容持续线程块的整个生命周期。 所有线程都可以访问…

武汉地铁19号线完成5G专网全覆盖,现场测试下行速率超千兆!

近日&#xff0c;极目新闻记者从中国移动湖北公司获悉&#xff0c;随着武汉地铁19号线全线隧道正式贯通&#xff0c;湖北移动目前已完成新月溪公园至鼓架山站5G网络覆盖&#xff0c;轨行区5G专网全覆盖&#xff0c;并成功进行试车验证&#xff0c;19号线成为国内首条全线实现5G…