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

系统总线:1、链接CPU、RAM、I/O设备之间的数据流动。例如:PCI、ISA、EISA、MCA、SCSI、USB2、任何I\O设备有且仅能链接一条总线。

I\O端口:1、每个连接到I\O总线上的设备都有自己的I\O地址集,通常称为I\O端口。2、一共提供了65536个8位的端口3、可以讲2个8位的看作一个16位的(必须从偶数开始),2个16位的看作一个32位的端口(必须从4倍数开始)4、对端口对读写命令 in、ins、out、outs5、为了提高性能提供控制寄存器、状态寄存器、输入寄存器、输出寄存器

I\O接口:1、专用I\O接口:专门用于一个特定的硬件设备;键盘接口、图形接口、磁盘接口、鼠标接口、网络接口2、通用I\O接口:用来连接多个不同的硬件设备,通常是外部设备。并口、串口、PCMCIA接口、SCSI接口、USB

设备控制器:1、复杂的设备需要,典型的是磁盘控制器,可以用来解析高级命令,转换成处理磁盘的低级磁盘操作。2、简单的设备不需要,比如可编程中断控制器、可编程间隔定时器。设备驱动程序模型:1、电源管理(控制设备电源线上不同的电压级别)
2、即插即用(配置设备时透明的资源分配)3、热插拔(系统运行时支持设备的插入和移除)4、内核全权负责所有硬件设备的电源管理,当计算机进入待机时,内核立即强制每个能够响应‘待机’状态的设备安装一定的顺序进入待机状态5、为了满足上述功能,为系统中所有的总线、设备以及设备驱动程序提供了一个统一的视图,即设备驱动程序模型。

设备文件:1、I\O设备可以被当作设备文件(device file)这种所谓的特殊文件来处理,即可以对其使用系统调用read、write2、根据设备驱动程序的基本特性,设备文件可以分位两种块和字符3、块设备的数据可以被随机访问,传输数据的时间少,且大致相同。例如硬盘、软盘、CD-ROM驱动器、DVD播放器等4、字符设备的数据或者不可以被随机访问;或者可以但是访问随机数据的时间很大程度依赖数据在设备内的位置,例如磁带驱动器5、一般设备文件名是无关紧要的,关键是设备类型、主设备号、次设备号6、主设备号和次设备号最大为65536,Linux 2.6对其进行了扩展主设备号12位,次设备号20位7、最好的解决方案时动态分配设备号;动态创建设备文件

设备驱动程序:1、实现文件对象read方法的foo_read函数2、处理中断的foo_interrupt函数3、当用户在设备文件上发出read系统调用,一条命令被发往设备的控制寄存器,一段时间间隔后,设备把一个字节的数据放入输入寄存器,作为read系统调用的结果返回

直接访问内存(DMA):1、不经过CPU,设备直接和RAM互传数据2、如果DMA和CPU同时访问同一内存,冲突由叫做内存仲裁器的硬件电路来解决3、使用最多的是磁盘驱动器和其他需要一次传输大量字节的设备。4、DMA的设置时间较长,少量数据时使用CPU效率更高5、同步DMA由进程触发,例如播放电影、音乐;播放音乐时,将内存数据采用DMA传到声卡播放6、异步DMA有硬件设备触发,例如网卡;网卡接收到数据,产生中断,将数据采用DMA方式传到内存

内核支持的I\O级别:1、根本不支持:应用程序只能用适当的in、out汇编语言直接与设备I|O端口交互

2、最小支持: 内核不识别硬件设备,但是能识别I\O接口,用户程序将I\O接口视为能够读写字符流的顺序设备3、扩展支持:内核能识别硬件,并处理I\O接口本身。这种设备可能没有对应的设备文件。

字符设备驱动程序:1、比较简单,不涉及复杂到缓存策略,磁盘高速缓存2、有些必须实现复杂到通信协议
时间: 2024-08-01 21:09:20

深入理解Linux内核-I/O体系结构和设备驱动程序的相关文章

准备把深入理解Linux内核这本书细看一遍

第一章 绪论 Linux与其他类Unix内核的比较 硬件的依赖性 Linux版本 操作系统基本概念 Unix文件系统概述 Unix内核概述 第二章 内存寻址 内存地址 硬件中的分段 Linux中的分段 硬件中的分页 Linux中的分页 第三章 进程 进程.轻量级进程和线程 进程描述符 进程切换 创建进程 撤销进程 第四章 中断和异常 中断信号的作用 中断和异常 中断和异常处理程序的嵌套执行 初始化中断描述符表 异常处理 软中断及tasklet 工作队列 从中断和异常返回 第五章 内核同步 内核如

【深入理解Linux内核】《第一章 绪论》笔记

1.商用Unix操作系统包括: - AT&T公司开发的(System V Release 4) SVR4. - 加州伯克利分校发布的4.4BSD - Dec公司(现属于HP)的Digital Unix - IBM公司的AIX - HP公司的HP-UX - Sun公司的Solaris   - Apple公司的Mac OS X 所有商业版本都是SVR4或4.4BSD的变体,并且都趋向于遵循某些通用标准:如IEEE的POSIX(Portable Operating Systems based on U

【笔记】深入理解Linux内核--内存寻址(一)

<深入理解Linux内核>中关于内存管理一共有三章,这是其中的一章,还有第八章,讨论内核怎样给自己分配主存,以及第九章,考虑怎样给进程分配线性地址. 内存地址 -- (P40) 以下三种地址是相对与8086处理器来说的. 逻辑地址(logical address) 包含在机器语言指令中用来指定一个操作数或一条指令的地址.比如下面反汇编代码中最左边的地址即逻辑地址. 1 40052d: 55 push %rbp 2 40052e: 48 89 e5 mov %rsp,%rbp 3 400531:

20150514我读《深入理解linux内核》之虚拟文件系统笔记

20150514我读<深入理解linux内核>之虚拟文件系统笔记 2015-05-14 Lover雪儿 虚拟文件系统所隐含的思想就是把很多不同种类的文件系统的共同信息放入内核,其中有一个字段或者函数来支持Linux所支持的所有实际文件系统所提供的任何操作.对所调用的每个读.写或者其他函数,内核都能把他们替换成支持本地Linux文件系统.NTFS文件系统,或者文件所在的任何其他文件系统的实际函数. 虚拟文件系统可以称为虚拟文件系统转换,是一个内核软件层,用来处理与Unix标准文件系统相关的所有系

【深入理解Linux内核】《第二章 内存寻址》笔记 (2014-06-28 12:38)

2.1 内存地址 逻辑地址:段+偏移 线性地址(虚拟地址) 物理地址 2.2硬件中的分段 2.2.1 段选择符和段寄存器 15                                                3  2  1   0 ------------------------------------------------|                                                    |TI |RPL  ||         索引号 

【读书笔记::深入理解linux内核】内存寻址

我对linux高端内存的错误理解都是从这篇文章得来的,这篇文章里讲的 物理地址 = 逻辑地址 – 0xC0000000:这是内核地址空间的地址转换关系. 这句话瞬间让我惊呆了,根据我的CPU的知识,开启分页之后,任何寻址都要经过mmu的转换,也就是一个二级查表的过程(386) 难道内核很特殊,当mmu看到某个逻辑地址是内核传来的之后,就不查表了,直接减去0xC0000000,然后就传递给内存控制器了??? 我发现网上也有人和我问了同样的问题,看这个问题 这句话太让人费解了,让人费解到以至于要怀疑

【深入理解Linux内核架构】第3章:内存管理

3.1 概述 内存管理涵盖了许多领域: 内存中物理内存页的管理: 分配大块内存的伙伴系统: 分配小块内存的slab.slub.slob分配器: 分配非连续内存块的vmalloc机制: 进程的地址空间. Linux内核一般将虚拟地址空间划分为两部分:底部较大的部分用于用户进程,顶部则用于内核.虽然(在两个用户进程之间)上下文切换期间会改变下半部分,但是虚拟地址空间的内核部分中总是不变[这其实很好理解,内核是系统管理员,不能说因为每换一批游客,景区管理员都得跟着换一批?!].在IA-32系统上,虚拟

深入理解Linux内核 第一章 绪论

Unix 文件系统概述 Unix的每个进程都有一个当前工作目录. 为标识一个特定的文件,进程使用路径名.如果路径名第一个字符是斜杠,那么这个路径是绝对路径,其起点是根目录:如果第一项是目录名或者文件名,那么这个路径就是相对路径,其起点是进程的当前目录. 硬链接的限制 1)不允许用户给目录创建硬链接,因为这可能把目录的树形结构变成环形结构. 2)只有在同一文件系统中的文件之间才能创建硬链接.此限制较大,因为现代Unix系统可能包含多种文件系统,这些文件系统位于不同的磁盘和/或分区,用户也无法知道他

【深入理解Linux内核架构】3.3 页表

页表:用于建立用户进程空间的虚拟地址空间和系统物理内存(内存.页帧)之间的关联. 向每个进程提供一致的虚拟地址空间. 将虚拟内存页映射到物理内存,因而支持共享内存的实现. 可以在不增加物理内存的情况下,将页换出到块设备来增加有效的可用内存空间. 内核内存管理总是假定使用四级页表. 3.3.1 数据结构 内核源代码假定void *和unsigned long long类型所需的比特位数相同,因此他们可以进行强制转换而不损失信息.即:假定sizeof(void *) == sizeof(unsign