当前位置:文档之家› Linux设备驱动程序学习(20)-内存映射和DMA-基本概念

Linux设备驱动程序学习(20)-内存映射和DMA-基本概念

Linux设备驱动程序学习(20)-内存映射和DMA-基本概念
Linux设备驱动程序学习(20)-内存映射和DMA-基本概念

Linux设备驱动程序学习(20)-内存映射和DMA-基本概念 (2011-09-25 15:47) 标签: 虚拟内存设备驱动程序Linux技术分类:Linux设备驱动程序

这部分主要研究 Linux 内存管理的基础知识, 重点在于对设备驱动有用的技术. 因为许多驱动编程需要一些对于虚拟内存(VM)子系统原理的理解。

而这些知识主要分为三个部分:

1、 mmap系统调用的实现原理:它允许设备内存直接映射到一个用户进程地址

空间. 这样做对一些设备来说可显著地提高性能.

2、与mmap的功能相反的应用原理:内核态代码如何跨过边界直接存取用户空间的内存页. 虽然较少驱动需要这个能力. 但是了解如何映射用户空间内存到内

核(使用 get_user_pages)会有用.

3、直接内存存取( DMA ) I/O 操作, 它提供给外设对系统内存的直接存取.

但所有这些技术需要理解 Linux 内存管理的基本原理, 因此我将先学习VM子

系统的基本原理.

一、Linux的内存管理

这里重点是 Linux 内存管理实现的主要特点,而不是描述操作系统的内存管理理论。Linux虚拟内存管理非常的复杂,要写可以写一本书:《深入理解Linux 虚拟内存管理》。学习驱动无须如此深入, 但是对它的工作原理的基本了解是必要的.

解了必要的背景知识后,才可以学习内核管理内存的数据结构.

Linux是一个虚拟内存系统(但是在没有MMU的CPU中跑的ucLinux除外), 意味着在内核启动了MMU 之后所有使用的地址不直接对应于硬件使用的物理地址,这些地址(称之为虚拟地址)都经过了MMU转换为物理地址之后再从CPU的内存总线中发出,读取/写入数据.

这样 VM 就引入了一个间接层, 它是许多操作成为可能: 1、系统中运行的程序可以分配远多于物理内存的内存空间,即便单个进程都可拥有一个大于系统的物理内存的虚拟地址空间. 2、虚拟内存也允许程序对进程的地址空间运用多种技巧, 包括映射程序的内存到设备内存.等等~~~

1、地址类型

Linux 系统处理几种类型的地址, 每个有它自己的含义:

用户虚拟地址:User virtual addresses,用户程序见到的常规地址. 用户地址在长度上是 32 位或者 64 位, 依赖底层的硬件结构, 并且每个进程有它自己

的虚拟地址空间.

总线地址:Bus addresses,在外设和内存之间使用的地址,但是这不是必要. 一些体系可提供一个 I/O 内存管理单元(IOMMU), 它在总线和主内存之间重映射地址.

物理地址:Physical addresses,在处理器和系统内存之间使用的地址. 有32bit 或64bit等。

以下的概念很重要,一定要理解了再往下看:

内核逻辑地址:Kernel logical addresses,他们是虚拟地址(需要经过MMU转换的地址),这些组成了常规的内核地址空间.这些地址映射了部分(也许全部)主存并且常常被当作物理内存. 在大部分的体系上, 逻辑地址和它们的相关物理地址只差一个常量偏移. 逻辑地址常常存储于 unsigned long 或者 void * 类型的变量中. 从 kmalloc 返回的内存就是内核逻辑地址.

内核虚拟地址:Kernel virtual addresses,它们都是从内核地址空间到物理地址的映射,但是内核虚拟地址并不必像逻辑地址空间一样具备线性的、一对一到物理地址的映射。所有的逻辑地址是内核虚拟地址, 但是许多内核虚拟地址不是逻辑地址. (也就是说在启动MMU后所有的地址都是内核虚拟地址,但是有一部分可以称为内核逻辑地址,因为他们具有上面介绍的特性:线性且连续、与对应的物理地址只差一个常量偏移)

对于内核虚拟地址,vmalloc 分配的内存是虚拟地址. kmap 函数也返回虚拟地址. 虚拟地址常常存储于指针变量.

如果有内核逻辑地址, 可通过宏 __pa() ( 在 中定义,但是也可能在它包含的头文件中)返回它关联的物理地址. 同时物理地址也可被映射回逻辑地址使用 __va(), 但是只适用于低端内存(后面会讲到).不同的内核函数需要不同类型地址.

2、物理地址和页

物理内存被划分为离散的单元称为页. 系统内部的许多内存处理都基于单个页. 页大小依赖体系结构, 大部分系统使用 4K字节为一页(ARM就是4KB/page). 在不同的体系上,常量 PAGE_SIZE (定义在 ) 给出了页大小的具体定义.

1.物理内存会划分为固定大小的页来处理的原因,个人认为主要是由于MMU

的分页机制决定的(X86正常情况下MMU的页大小为4KB,ARM的MMU的

小页的页大小也是4KB)。有的CPU的MMU分页的页大小是可调的,这可能使得内核配置的PAGE_SIZE也随之改变,比如MIPS构架的页大小可能

是4KB、8KB、16KB、32KB和64KB。

一个内存地址(虚拟或物理),它可分为一个页帧号和一个页内的偏移. 以使用4KB页为例, 低12 位有效位是偏移, 而剩下的高位为页帧号. 若忽略偏移并向右移动地址 offset 位, 结果即为页帧号 (PFN). 移位来在页帧号和地址之间转换是一个相当普通的操作. 宏 PAGE_SHIFT 告诉必须移动多少位来进行这个转换.

3、高端与低端内存

在拥有大量内存的 32bit系统中,内核逻辑地址和虚拟地址之间的差异就会突显出来。 32 bit 系统可寻址4G内存. 但是因为建立虚拟地址空间的限制(不能把所有虚拟地址空间都用完,必须留下一些作为临时的映射和IO空间映射之用),早

期的在 32bit Linux系统被限制使用少于4G的内存,比如我的DELL vostro 120笔记本,我升级到4G内存,原来的ubuntu 8.10 32bit只认到3G,且64bit根本装不上。后来似乎是升级到了ubuntu 10.10 32bit才认到了4G内存。

内核(在x86体系的缺省配置里)划分4GB虚拟地址空间为用户空间和内核空间;在2个上下文中使用同一套映射.一个典型的划分:3GB用户空间-1GB内核空间。内核的代码和数据结构必须要匹配这个空间,

占用内核地址空间最大部分的是物理内存的虚拟映射(包括逻辑地址映射和虚拟地址映射(如果有高端内存)). 内核不能直接操作没有映射到内核地址空间的内存. 换句话说, 内核对任何内存的访问需使用它自己的虚拟地址。因此, 多年来, 能够被内核处理的最大物理内存量是能够映射到虚拟地址的内核部分的大小再减去内核代码自身的空间.因此,基于x86的Linux系统可以使用的最大内存量会比1GB稍小。

为了使用更多内存, 在不破坏 32bit应用和系统的兼容性的情况下,处理器制造商在产品中增加了"地址扩展"特性. 这样,即便32bit处理器也能够寻址多于4GB物理内存. 但可被直接用逻辑地址映射的内存大小限制还存在.这样内存的最低部分(根据硬件和内核配置一般是 1到2 GB, )有逻辑地址; 剩下的(高端内存)没有. 在访问一个特定高地址页前, 内核必须建立一个明确的虚拟映射来使此页可在内核地址空间中被访问. 因此, 许多内核数据结构必须放在低端内存; 高端内存主要为用户进程页所保留.

所以定义如下:

Low memory:低端内存

在内核空间中拥有逻辑地址的内存. 在大部分系统中(ARM构架几乎都是),几乎所有的内存都是低端内存.

High memory:高端内存

没有逻辑地址映射的内存,它位于内核逻辑地址范围之外,使用前必须使用vmalloc等内核函数做好映射.

在 i386 系统上, 低和高内存之间的分界在内核配置时可被改变,但常常设置在1GB以下。这个边界与硬件无关.它是由内核自身设置的。

其实我认为这个分界线和两个内核配置因素有关:

(1)内核对于内核空间和用户空间比例的配置。1GB :3GB、2GB :2GB、3GB :1GB等(例如比例是2GB :2GB,内核又有3G内存,则低端内存是可以超过1G的~~)(2)分配给内核虚拟地址空间的大小vmalloc,这个是可以在启动参数中设置的。

1.vmalloc=nn[KMG]

2.强制指定vmalloc区域的大小。可用于增加vmalloc区域的最小尺寸(x86默认

128MB),也可以用于减少vmalloc的大小,增加更多的空间用于直接映射内核RAM。

当然硬件上的限制就是RAM的大小,低端内存和高端内存的和总不能超过RAM 总大小吧~~~

关于X86这方面的更详细的资料,我觉得可以参考以下链接:

linux的物理内存与线性地址空间布局--1

还有就是陈莉君老师的《解惑-linux内核空间(二)》

那么对于ARM构架来说,情况是一样的。虽然说ARM构架中你很少能找到存在高端内存的设备,但是如果内存足够大(例如1GB、2GB的板子也不是没有,比如TI芯片DM8168的16路D1解决方案就用了1GB或2GB内存,当然其中一部分要分给视频协处理器和DSP),然后将vmalloc设置大些,也可以在系统中出现高端内存。

对于ARM构架,我稍微对内核的启动时的高低内存设置做了下跟踪,有兴趣的朋友可以看看:《Linux内核高-低端内存设置代码跟踪(ARM构架)》

最后对于LDD3的图,我感觉意思表达得不太好,自己画了一个。我的理解是这样的,如果您觉得我错了,请指出来,先谢谢了!

linux内存管理子系统 笔记

4-4 linux内存管理子系统 4-4-1 linux内存管理(参考课件) 物理地址:cpu地址总线上寻址物理内存的地址信号,是地址变换的最终结果 逻辑地址:程序代码经过编译后,出现在汇编程序中的地址(程序设计时使用的地址) 线性地址:又名虚拟地址,32位cpu架构下4G地址空间 CPU要将一个逻辑地址转换为物理地址,需要两步: 1、首先CPU利用段式内存管理单元,将逻辑地址转换成线性地址; 2、再利用页式内存管理单元,把线性地址最终转换为物理地址 相关公式: 逻辑地址=段基地址+段内偏移量(段基地址寄存器+段偏移寄存器)(通用的) 16位CPU:逻辑地址=段基地址+段内偏移量(段基地址寄存器+段偏移寄存器) 线性地址=段寄存器的值×16+逻辑地址的偏移部分 物理地址=线性地址(没有页式管理) 32位CPU:逻辑地址=段基地址+段内偏移量(段基地址寄存器+段偏移寄存器) 线性地址=段寄存器的值+逻辑地址的偏移部分 物理地址<——>线性地址(mapping转换) ARM32位:逻辑地址=段基地址+段内偏移量(段基地址寄存器+段偏移寄存器) 逻辑地址=段内偏移量(段基地址为0) 线性地址=逻辑地址=段内偏移量(32位不用乘以32) 物理地址<——>线性地址(mapping转换) ************************!!以下都是x86模式下!!********************************* 一、段式管理 1.1、16位CPU:(没有页式管理) 1.1.1、段式管理的由来: 16位CPU内部有20位地址总线,可寻址2的20次方即1M的内存空间,但16位CPU 只有16位的寄存器,因此只能访问2的16次方即64K。因此就采用了内存分段的管理模式,在CPU内部加入了段寄存器,这样1M被分成若干个逻辑段,每个逻辑段的要求如下: 1、逻辑段的起始地址(段地址)必须是16的整数倍,即最后4个二进制位须全是0 (因此不必保存)。 2、逻辑段的最大容量为64K。 1.1.2、物理地址的形成方式: 段地址:将段寄存器中的数值左移4位补4个0(乘以16),得到实际的段地址。 段偏移:在段偏移寄存器中。 1)逻辑地址=段基地址+段内偏移量(段基地址寄存器+段偏移寄存器) 2)由逻辑地址得到物理地址的公式为:(因为没有页式管理,所以这一步就得到了物理地址)物理地址PA=段寄存器的值×16+逻辑地址的偏移部分(注意!!)(段与段可能会重叠)

Linux设备驱动程序举例

Linux设备驱动程序设计实例2007-03-03 23:09 Linux系统中,设备驱动程序是操作系统内核的重要组成部分,在与硬件设备之间 建立了标准的抽象接口。通过这个接口,用户可以像处理普通文件一样,对硬件设 备进行打开(open)、关闭(close)、读写(read/write)等操作。通过分析和设计设 备驱动程序,可以深入理解Linux系统和进行系统开发。本文通过一个简单的例子 来说明设备驱动程序的设计。 1、程序清单 //MyDev.c 2000年2月7日编写 #ifndef __KERNEL__ #define __KERNEL__//按内核模块编译 #endif #ifndef MODULE #define MODULE//设备驱动程序模块编译 #endif #define DEVICE_NAME "MyDev" #define OPENSPK 1 #define CLOSESPK 2 //必要的头文件 #include //同kernel.h,最基本的内核模块头文件 #include //同module.h,最基本的内核模块头文件 #include //这里包含了进行正确性检查的宏 #include //文件系统所必需的头文件 #include //这里包含了内核空间与用户空间进行数据交换时的函数宏 #include //I/O访问 int my_major=0; //主设备号 static int Device_Open=0; static char Message[]="This is from device driver"; char *Message_Ptr; int my_open(struct inode *inode, struct file *file) {//每当应用程序用open打开设备时,此函数被调用 printk ("\ndevice_open(%p,%p)\n", inode, file); if (Device_Open) return -EBUSY;//同时只能由一个应用程序打开 Device_Open++; MOD_INC_USE_COUNT;//设备打开期间禁止卸载 return 0; } static void my_release(struct inode *inode, struct file *file)

DMA、TRIX指标原理和详解

DMA指标原理和详解 DMA指标又叫平行线差指标,是目前股市分析技术指标中的一种中短期指标,它常用于大盘指数和个股的研判。 第一节 DMA指标的原理及计算方法 一、 DMA指标的原理 DMA指标是属于趋向类指标,也是一种趋势分析指标。DMA是依据快慢两条移动平均线的差值情况来分析价格趋势的一种技术分析指标。它主要通过计算两条基准周期不同的移动平均线的差值,来判断当前买入卖出的能量的大小和未来价格走势的趋势。 二、 DMA指标的计算方法 DMA指标的计算方法比较简单,其计算过程如下: DMA=短期平均值—长期平均值 AMA=短期平均值 以求10日、50日为基准周期的DMA指标为例,其计算过程具体如下: DMA(10)=10日平均值—50日平均值 AMA(10)=10日平均值 和其他指标的计算一样,由于选用的计算周期的不同,DMA指标也包括日DMA指标、周DMA指标、月DMA指标年DMA指标以及分钟DMA指标等各种类型。经常被用于股市研判的是日DMA指标和周DMA 指标。虽然它们的计算时的取值有所不同,但基本的计算方法一样。另外,随着股市软件分析技术的发展,投资者只需掌握DMA形成的基本原理和计算方法,无须去计算指标的数值,更为重要的是利用DMA 指标去分析、研判股票行情。 第二节 DMA指标的一般研判标准 一、DMA和AMA的值及线的运动方向 1、当DMA和AMA均大于0(即在图形上表示为它们处于零线以上)并向上移动时,一般表示为股市处于多头行情中,可以买入或持股; 2、当DMA和AMA均小于0(即在图形上表示为它们处于零线以下)并向下移动时,一般表示为股市处于空头行情中,可以卖出股票或观望。 3、当DMA和AMA均大于0(即在图形上表示为它们处于零线以上),但在经过一段比较长时间的向上运动后,如果两者同时从高位向下移动时,一般表示为股票行情处于退潮阶段,股票将下跌,可以卖出股票和观望; 4、当DMA和AMA均小于0时(即在图形上表示为它们处于零线以下),但在经过一段比较长时间的的向下运动后,如果两者同时从低位向上移动时,一般表示为短期行情即将启动,股票将上涨,可以短期买进股票或持股待涨。 二、DMA曲线和股价曲线的配合使用

化工原理重要概念和公式

《化工原理》重要概念 第八章气体吸收 吸收的目的和基本依据吸收的目的是分离气体混合物,吸收的基本依据是混合物中各组份在溶剂中的溶解度不同。 主要操作费溶剂再生费用,溶剂损失费用。解吸方法升温、减压、吹气。 选择吸收溶剂的主要依据溶解度大,选择性高,再生方便,蒸汽压低损失小。 相平衡常数及影响因素m 、 E 、 H 均随温度上升而增大, E 、 H 与总压无关, m 反比于总压。 漂流因子P/P Bm 表示了主体流动对传质的贡献。 ( 气、液 ) 扩散系数的影响因素气体扩散系数与温度、压力有关;液体扩散系数与温度、粘度有关。 传质机理分子扩散、对流传质。 气液相际物质传递步骤气相对流,相界面溶解,液相对流。 有效膜理论与溶质渗透理论的结果差别有效膜理论获得的结果为k ∝ D ,溶质渗透理论考虑到微元传质的非定态性,获得的结果为k ∝ D 0.5 。 传质速率方程式传质速率为浓度差推动力与传质系数的乘积。因工程上浓度有多种表达,推动力也就有多种形式,传质系数也有多种形式,使用时注意一一对应。 传质阻力控制传质总阻力可分为两部分,气相阻力和液相阻力。当 mky<>kx 时,为液相阻力控制。 低浓度气体吸收特点① G 、 L 为常量,② 等温过程,③ 传质系数沿塔高不变。 建立操作线方程的依据塔段的物料衡算。 返混少量流体自身由下游返回至上游的现象。最小液气比完成指定分离任务所需塔高为无穷大时的液气比。 NOG 的计算方法对数平均推动力法,吸收因数法,数值积分法。 第九章液体精馏 蒸馏的目的及基本依据蒸馏的目的是分离液体混合物,它的基本依据 ( 原理 ) 是液体中各组分挥发度的不同。 主要操作费用塔釜的加热和塔顶的冷却。 双组份汽液平衡自由度自由度为 2(P 一定, t ~ x 或 y ; t 一定, P ~ x 或 y) ; P 一定后,自由度为 1 。泡点泡点指液相混合物加热至出现第一个汽泡时的温度。露点露点指气相混合物冷却至出现第一个液滴时的温度。非理想物系汽液相平衡关系偏离拉乌尔定律的成为非理想物系。总压对相对挥发度的影响压力降低,相对挥发度增加。平衡蒸馏连续过程且一级平衡。简单蒸馏间歇过程且瞬时一级平衡。 连续精馏连续过程且多级平衡。间歇精馏时变过程且多级平衡。 特殊精馏恒沸精馏、萃取精馏等加第三组分改变α。 实现精馏的必要条件回流液的逐板下降和蒸汽逐板上升,实现汽液传质、高度分离。 理论板离开该板的汽液两相达到相平衡的理想化塔板。板效率经过一块塔板之后的实际增浓与理想增浓之比。 恒摩尔流假设及主要条件在没有加料、出料的情况下,塔段内的汽相或液相摩尔流率各自不变。组分摩尔汽化热相近,热损失不计,显热差不计。 加料热状态参数 q 值的含义及取值范围一摩尔加料加热至饱和汽体所需热量与摩尔汽化潜热之比,表明加料热状态。取值范围: q<0 过热蒸汽, q=0 饱和蒸汽, 01 冷液。 建立操作线的依据塔段物料衡算。 第十章气液传质设备 板式塔的设计意图①气液两相在塔板上充分接触,②总体上气液逆流,提供最大推动力。 对传质过程最有利的理想流动条件总体两相逆流,每块板上均匀错流。 三种气液接触状态鼓泡状态:气量低,气泡数量少,液层清晰。泡沫状态:气量较大,液体大部分以液膜形式存在于气泡之间,但仍为连续相。喷射状态:气量很大,液体以液滴形式存在,气相为连续相。 转相点由泡沫状态转为喷射状态的临界点。 板式塔内主要的非理想流动液沫夹带、气泡夹带、气体的不均匀流动、液体的不均匀流动。

linux复习题

一单选题 1.最初开发了Linux系统的是() A.Andrew S. Tanwnbaum B.Linus Torvalds C.Ken Thompson D.Dennis Ritchie 2.linux操作系统内核创始人是() A.Bill Gates B.Richard Stallman C.Linus Torvalds D.Dennis Ritchie 3.linux操作系统下有很多应用软件,其中大部分软件包括linux本身属于() A.商业软件 B. 共享软件 C.自由软件 D.其他类型软件 4.Linux系统是一个什么样的操作系统() A.单用户、单任务B.单用户、多任务 C.多用户、单任务D.多用户、多任务 5.Linux 核心的许可证是什么() A.NDA B.GDP C.GPL D.GNU 6.若要将鼠标从VM中释放出来,可按什么键来实现() A. Ctrl + Alt B. Ctrl +Alt +Del C. Ctrl +Alt +Enter D Ctrl +Enter 7.用"rm -i",系统会提示什么来让你确认() A. 命令行的每个选项 B. 是否真的删除 C. 是否有写的权限 D. 文件的位置 8.下列提法中,不属于ifconfig命令作用范围的是() A 配置本地回环地址 B 配置网卡的IP地址 C 激活网络适配器 D 加载网卡到内核中 9.下列文件中,包含了主机名到IP地址的映射关系的文件是() A /etc/HOSTNAME B /etc/hosts C /etc/resolv.conf D /etc/networks 10.在shell中变量的赋值有四种方法,其中,采用name=12的方法称() A 直接赋值B使用read命令 C 使用命令行参数D使用命令的输出 11.显示文件的头部的命令是() A.fdisk B.mount C.head D.man 12.删除不需要的文件的命令是() A.mkdir B.rm C.mv D.remove 13.Linux的根分区的文件系统类型是() A.FAT16 B.FAT32 C.ext3 D.NTFS 14.登录后希望重新加载fstab文件中的所有条目,我们可以以root身份执行哪个命令 () A.mount –d B.mount –c C.mount –a D.mount -b 15.下面不具备循环功能的语句是() A.if B.for C.while D.until 16.内核不包括的子系统是() A 进程管理系统 B 内存管理系统 C 文件管理系统D硬件管理系统 17.对名为fido的文件用chmod 551 fido 进行了修改,则它的许可权是() A -rwxr-xr-x B -rwxr--r-- C -r--r--r-- D -r-xr-x--x

一个简单的演示用的Linux字符设备驱动程序.

实现如下的功能: --字符设备驱动程序的结构及驱动程序需要实现的系统调用 --可以使用cat命令或者自编的readtest命令读出"设备"里的内容 --以8139网卡为例,演示了I/O端口和I/O内存的使用 本文中的大部分内容在Linux Device Driver这本书中都可以找到, 这本书是Linux驱动开发者的唯一圣经。 ================================================== ===== 先来看看整个驱动程序的入口,是char8139_init(这个函数 如果不指定MODULE_LICENSE("GPL", 在模块插入内核的 时候会出错,因为将非"GPL"的模块插入内核就沾污了内核的 "GPL"属性。 module_init(char8139_init; module_exit(char8139_exit; MODULE_LICENSE("GPL"; MODULE_AUTHOR("ypixunil"; MODULE_DESCRIPTION("Wierd char device driver for Realtek 8139 NIC"; 接着往下看char8139_init( static int __init char8139_init(void {

int result; PDBG("hello. init.\n"; /* register our char device */ result=register_chrdev(char8139_major, "char8139", &char8139_fops; if(result<0 { PDBG("Cannot allocate major device number!\n"; return result; } /* register_chrdev( will assign a major device number and return if it called * with "major" parameter set to 0 */ if(char8139_major == 0 char8139_major=result; /* allocate some kernel memory we need */ buffer=(unsigned char*(kmalloc(CHAR8139_BUFFER_SIZE, GFP_KERNEL; if(!buffer { PDBG("Cannot allocate memory!\n"; result= -ENOMEM;

化工原理重要概念和公式

《化工原理》重要概念 第一章流体流动 质点含有大量分子的流体微团,其尺寸远小于设备尺寸,但比起分子自由程却要大得多。 连续性假定假定流体是由大量质点组成的、彼此间没有间隙、完全充满所占空间的连续介质。 拉格朗日法选定一个流体质点 , 对其跟踪观察,描述其运动参数 ( 如位移、速度等 ) 与时间的关系。 欧拉法在固定空间位置上观察流体质点的运动情况,如空间各点的速度、压强、密度等,即直接描述各有关运动参数在空间各点的分布情况和随时间的变化。 轨线与流线轨线是同一流体质点在不同时间的位置连线,是拉格朗日法考察的结果。流线是同一瞬间不同质点在速度方向上的连线,是欧拉法考察的结果。 系统与控制体系统是采用拉格朗日法考察流体的。控制体是采用欧拉法考察流体的。 理想流体与实际流体的区别理想流体粘度为零,而实际流体粘度不为零。 粘性的物理本质分子间的引力和分子的热运动。通常液体的粘度随温度增加而减小,因为液体分子间距离较小,以分子间的引力为主。气体的粘度随温度上升而增大,因为气体分子间距离较大,以分子的热运动为主。 总势能流体的压强能与位能之和。 可压缩流体与不可压缩流体的区别流体的密度是否与压强有关。有关的称为可压缩流体,无关的称为不可压缩流体。 伯努利方程的物理意义流体流动中的位能、压强能、动能之和保持不变。 平均流速流体的平均流速是以体积流量相同为原则的。 动能校正因子实际动能之平均值与平均速度之动能的比值。 均匀分布同一横截面上流体速度相同。 均匀流段各流线都是平行的直线并与截面垂直 , 在定态流动条件下该截面上的流体没有加速度 , 故沿该截面势能分布应服从静力学原理。

层流与湍流的本质区别是否存在流体速度 u 、压强 p 的脉动性,即是否存在流体质点的脉动性。 第二章流体输送机械 管路特性方程管路对能量的需求,管路所需压头随流量的增加而增加。 输送机械的压头或扬程流体输送机械向单位重量流体所提供的能量 (J/N) 。 离心泵主要构件叶轮和蜗壳。 离心泵理论压头的影响因素离心泵的压头与流量,转速,叶片形状及直径大小有关。 叶片后弯原因使泵的效率高。 气缚现象因泵内流体密度小而产生的压差小,无法吸上液体的现象。 离心泵特性曲线离心泵的特性曲线指 H e~ q V ,η~ q V , P a~ q V 。 离心泵工作点管路特性方程和泵的特性方程的交点。 离心泵的调节手段调节出口阀,改变泵的转速。 汽蚀现象液体在泵的最低压强处 ( 叶轮入口 ) 汽化形成气泡,又在叶轮中因压强升高而溃灭,造成液体对泵设备的冲击,引起振动和侵蚀的现象。 必需汽蚀余量 (NPSH)r 泵入口处液体具有的动能和压强能之和必须超过饱和蒸汽压强能多少 离心泵的选型 ( 类型、型号 ) ①根据泵的工作条件,确定泵的类型;②根据管路所需的流量、压头,确定泵的型号。 正位移特性流量由泵决定,与管路特性无关。 往复泵的调节手段旁路阀、改变泵的转速、冲程。 离心泵与往复泵的比较 ( 流量、压头 ) 前者流量均匀,随管路特性而变,后者流量不均匀,不随管路特性而变。前者不易达到高压头,后者可达高压头。前者流量调节用泵出口阀,无自吸作用,启动时关出口阀;后者流量调节用旁路阀,有自吸作用,启动时开足管路阀门。 通风机的全压、动风压通风机给每立方米气体加入的能量为全压 (Pa=J/m 3 ) ,其中动能部分为动风压。

Linux设备驱动程序学习(18)-USB 驱动程序(三)

Linux设备驱动程序学习(18)-USB 驱动程序(三) (2009-07-14 11:45) 分类:Linux设备驱动程序 USB urb (USB request block) 内核使用2.6.29.4 USB 设备驱动代码通过urb和所有的 USB 设备通讯。urb用 struct urb 结构描述(include/linux/usb.h )。 urb以一种异步的方式同一个特定USB设备的特定端点发送或接受数据。一个USB 设备驱动可根据驱动的需要,分配多个 urb 给一个端点或重用单个 urb 给多个不同的端点。设备中的每个端点都处理一个 urb 队列, 所以多个 urb 可在队列清空之前被发送到相同的端点。 一个 urb 的典型生命循环如下: (1)被创建; (2)被分配给一个特定 USB 设备的特定端点; (3)被提交给 USB 核心; (4)被 USB 核心提交给特定设备的特定 USB 主机控制器驱动; (5)被 USB 主机控制器驱动处理, 并传送到设备; (6)以上操作完成后,USB主机控制器驱动通知 USB 设备驱动。 urb 也可被提交它的驱动在任何时间取消;如果设备被移除,urb 可以被USB 核心取消。urb 被动态创建并包含一个内部引用计数,使它们可以在最后一个用户释放它们时被自动释放。 struct urb

struct list_head urb_list;/* list head for use by the urb's * current owner */ struct list_head anchor_list;/* the URB may be anchored */ struct usb_anchor *anchor; struct usb_device *dev;/* 指向这个 urb 要发送的目标 struct usb_device 的指针,这个变量必须在这个 urb 被发送到 USB 核心之前被USB 驱动初始化.*/ struct usb_host_endpoint *ep;/* (internal) pointer to endpoint */ unsigned int pipe;/* 这个 urb 所要发送到的特定struct usb_device 的端点消息,这个变量必须在这个 urb 被发送到 USB 核心之前被 USB 驱动初始化.必须由下面的函数生成*/ int status;/*当 urb开始由 USB 核心处理或处理结束, 这个变量被设置为 urb 的当前状态. USB 驱动可安全访问这个变量的唯一时间是在 urb 结束处理例程函数中. 这个限制是为防止竞态. 对于等时 urb, 在这个变量中成功值(0)只表示这个 urb 是否已被去链. 为获得等时 urb 的详细状态, 应当检查 iso_frame_desc 变量. */ unsigned int transfer_flags;/* 传输设置*/ void*transfer_buffer;/* 指向用于发送数据到设备(OUT urb)或者从设备接收数据(IN urb)的缓冲区指针。为了主机控制器驱动正确访问这个缓冲, 它必须使用 kmalloc 调用来创建, 不是在堆栈或者静态内存中。对控制端点, 这个缓冲区用于数据中转*/ dma_addr_t transfer_dma;/* 用于以 DMA 方式传送数据到 USB 设备的缓冲区*/ int transfer_buffer_length;/* transfer_buffer 或者 transfer_dma 变量指向的缓冲区大小。如果这是 0, 传送缓冲没有被 USB 核心所使用。对于一个 OUT 端点, 如果这个端点大小比这个变量指定的值小, 对这个USB 设备的传输将被分成更小的块,以正确地传送数据。这种大的传送以连续的 USB 帧进行。在一个 urb 中提交一个大块数据, 并且使 USB 主机控制器去划分为更小的块, 比以连续地顺序发送小缓冲的速度快得多*/

化工原理基本概念

基本定义 理想溶液 ideal solution(s):溶液中的任一组分在全部浓度范围内都符合拉乌尔定律[1]的溶液称为理想溶液。 这是从宏观上对理想溶液的定义。从分子模型上讲,各组分分子的大小及作用力,彼此相似,当一种组分的分子被另一种组分的分子取代时,没有能量的变化或空间结构的变化。换言之,即当各组分混合成溶液时,没有热效应和体积的变化。即这也可以作为理想溶液的定义。除了光学异构体的混合物、同位素化合物的混合物、立体异构体的混合物以及紧邻同系物的混合物等可以(或近似地)算作理想溶液外,一般溶液大都不具有理想溶液的性质。但是因为理想溶液所服从的规律较简单,并且实际上,许多溶液在一定的浓度区间的某些性质常表现得很像理想溶液,所以引入理想溶液的概念,不仅在理论上有价值,而且也有实际意义。以后可以看到,只要对从理想溶液所得到的公式作一些修正,就能用之于实际溶液。 各组成物质在全部浓度范围内都服从拉乌尔定律的溶液。[2]对于理想溶液,拉乌尔定律与亨利定律反映的就是同一客观规律。其微观模型是溶液中各物质分子的大小及各种分子间力(如由A、B二物质组成的溶液,即为A-A、B-B及A-B 间的作用力)的大小与性质相同。由此可推断:几种物质经等温等压混合为理想溶液,将无热效应,且混合前后总体积不变。这一结论也可由热力学推导出来。理想溶液在理论上占有重要位臵,有关它的平衡性质与规律是多组分体系热力学的基础。在实际工作中,对稀溶液可用理想溶液的性质与规律作各种近似计算。 泡点: 液体混合物处于某压力下开始沸腾的温度,称为在这压力下的泡点。 若不特别注明压力的大小,则常常表示在0.101325MPa下的泡点。泡点随液体组成而改变。对于纯化合物,泡点也就是在某压力下的沸点。 一定组成的液体,在恒压下加热的过程中,出现第一个气泡时的温度,也就是一定组成的液体在一定压力下与蒸气达到汽液平衡时的温度。泡点随液相组成和压力而变。当泡点与液相组成的关系中,出现极小值或极大值时,这极值温度相应称为最低恒沸点或最高恒沸点,这时,汽相与液相组成相同,相应的混合物称为恒沸混合物。汽液平衡时,液相的泡点即为汽相的露点。

主板芯片和内存映射

astrotycoon 大道至简,贵在恒久力行

Diagram for modern motherboard. The northbridge and southbridge make up the chipset.

(补充: 北桥芯片用于与CPU、内存和AGP视频接口,这些接口具有很高的传输速率。北桥芯片还起着存储器控制作用,因此Intel把该芯片标号为MCH(Memory Controller Hub)芯片。南桥芯片用来管理低、中速的组件,例如,PCI总线、IDE硬盘接口、USB端口等,因此南桥芯片的名称为ICH(I/O Controller Hub)) As you look at this, the crucial thing to keep in mind is that the CPU doesn’t really know anything about what it’s connected to. It talks to the outside world through its pins bu t it doesn’t care what that outside world is. It might be a motherboard in a computer but it could be a toaster, network router, brain implant, or CPU test bench. There are thre e main ways by which the CPU and the outside communicate: memory address space, I/O address space, and interrupts. We only worry about motherboards and memory for now. 正如你所看到的,其实CPU是完全不知道自己与哪些外部器件相连接的。 CPU仅仅通过自己的引脚与外界沟通,而它并不关心自己是与什么设备在沟通。或许是另一台计算机的主板,或许是烤面包机,网络路由器,脑植入医疗设备,又或许是CPU测试仪。 CPU主要通过三种方式与外界通信:内存地址空间,IO地址空间,和中断。我们目前只关注主板和内存。 In a motherboard the CPU’s gateway to the world is the front-side bus connecting it to the northbridge. Whenever the CPU needs to read or write memory it does so via this b us. It uses some pins to transmit the physical memory address it wants to write or read, while other pins send the value to be written or receive the value being read. An Intel Core 2 QX6600 has 33 pins to transmit the physical memory address (so there are 233 choices of memory locations) and 64 pins to send or receive data (so data is transmitte d in a 64-bit data path, or 8-byte chunks). This allows the CPU to physically address 64 gigabytes of memory (233 locations * 8 bytes) although most chipsets only handle up to 8 gigs of RAM. CPU通过前端总线与北桥芯片连接,作为与外界通信的桥梁。无论何时,CPU都可以通过前端总线来读写内存。 CPU通过一些引脚来传送想要读写物理内存的地址,同时通过另一些引脚来发送将要写入内存的数据或者接收从内存读取到的数据。 Intel Core 2 QX6600 用33个引脚来传送物理内存地址(因此共有233 个内存地址),并且用64个引脚来发送或接收数据(所以数据在64位通道中传输,也就是8字节的数据块)。因此C PU可以访问64G的物理内存(233*8字节),尽管多数芯片组只能处理8G大小的物理内存。 Now comes the rub. We’re used to thinking of memory only in terms of RAM, the stuff programs read from and write to all the time. And indeed most of the memory requests from the processor are routed to RAM modules by the northbridge. But not all of them. Physical memory addresses are also used for communication with assorted devices on t he motherboard (this communication is called memory-mapped I/O). These devices include video cards, most PCI cards (say, a scanner or SCSI card), and also the flash mem ory that stores the BIOS. 那么现在的问题是,通常一提起内存我们仅仅联想到RAM,以为程序一直读写的就只是RAM。的确,绝大多数来自CPU的内存访问请求都被北桥芯片映射到了RAM。但是,注意,不是全部。物理内存同样可以用来与主板上的各种设备通信(这种通信方式被称为I/O内存映射)。这些设备包括显卡,大多数PCI卡(比如,扫描仪,或者是SCSI卡),也包括存储BIOS的flash存储器。 When the northbridge receives a physical memory request it decides where to route it: should it go to RAM? Video card maybe? This routing is decided via the memory addres s map. For each region of physical memory addresses, the memory map knows the device that owns that region. The bulk of the addresses are mapped to RAM, but when the y aren’t the memory map tells the chipset which device should service requests for those addresses. This mapping of memory addresses away from RAM modules causes the c lassic hole in PC memory between 640KB and 1MB. A bigger hole arises when memory addresses are reserved for video cards and PCI devices. This is why 32-bit OSes have pr oblems using 4 gigs of RAM. In Linux the file /proc/iomem neatly lists these address range mappings. The diagram below shows a typical memory map for the first 4 gigs of p hysical memory addresses in an Intel PC:

化工原理基本概念和原理

化工原理基本概念和原理 蒸馏––––基本概念和基本原理 利用各组分挥发度不同将液体混合物部分汽化而使混合物得到分离的单元操作称为蒸馏。这种分离操作是通过液相和气相之间的质量传递过程来实现的。 对于均相物系,必须造成一个两相物系才能将均相混合物分离。蒸馏操作采用改变状态参数的办法(如加热和冷却)使混合物系内部产生出第二个物相(气相);吸收操作中则采用从外界引入另一相物质(吸收剂)的办法形成两相系统。 一、两组分溶液的气液平衡 1.拉乌尔定律 理想溶液的气液平衡关系遵循拉乌尔定律: p A =p A 0x A p B =p B 0x B =p B 0(1—x A ) 根据道尔顿分压定律:p A =Py A 而P=p A +p B 则两组分理想物系的气液相平衡关系: x A =(P—p B 0)/(p A 0—p B 0)———泡点方程 y A =p A 0x A /P———露点方程 对于任一理想溶液,利用一定温度下纯组分饱和蒸汽压数据可求得平衡的气液相组成;反之,已知一相组成,可求得与之平衡的另一相组成和温度(试差法)。

2.用相对挥发度表示气液平衡关系 溶液中各组分的挥发度v可用它在蒸汽中的分压和与之平衡的液相中的摩尔分率来表示,即v A=p A/x A v B=p B/x B 溶液中易挥发组分的挥发度对难挥发组分的挥发度之比为相对挥发度。其表达式有: α=v A/v B=(p A/x A)/(p B/x B)=y A x B/y B x A 对于理想溶液:α=p A0/p B0 气液平衡方程:y=αx/[1+(α—1)x] Α值的大小可用来判断蒸馏分离的难易程度。α愈大,挥发度差异愈大,分离愈易;α=1时不能用普通精馏方法分离。 3.气液平衡相图 (1)温度—组成(t-x-y)图 该图由饱和蒸汽线(露点线)、饱和液体线(泡点线)组成,饱和液体线以下区域为液相区,饱和蒸汽线上方区域为过热蒸汽区,两曲线之间区域为气液共存区。 气液两相呈平衡状态时,气液两相温度相同,但气相组成大于液相组成;若气液两相组成相同,则气相露点温度大于液相泡点温度。 (2)x-y图

Linux设备驱动程序学习(20)-内存映射和DMA-基本概念

Linux设备驱动程序学习(20)-内存映射和DMA-基本概念 (2011-09-25 15:47) 标签: 虚拟内存设备驱动程序Linux技术分类:Linux设备驱动程序 这部分主要研究 Linux 内存管理的基础知识, 重点在于对设备驱动有用的技术. 因为许多驱动编程需要一些对于虚拟内存(VM)子系统原理的理解。 而这些知识主要分为三个部分: 1、 mmap系统调用的实现原理:它允许设备内存直接映射到一个用户进程地址 空间. 这样做对一些设备来说可显著地提高性能. 2、与mmap的功能相反的应用原理:内核态代码如何跨过边界直接存取用户空间的内存页. 虽然较少驱动需要这个能力. 但是了解如何映射用户空间内存到内 核(使用 get_user_pages)会有用. 3、直接内存存取( DMA ) I/O 操作, 它提供给外设对系统内存的直接存取. 但所有这些技术需要理解 Linux 内存管理的基本原理, 因此我将先学习VM子 系统的基本原理. 一、Linux的内存管理 这里重点是 Linux 内存管理实现的主要特点,而不是描述操作系统的内存管理理论。Linux虚拟内存管理非常的复杂,要写可以写一本书:《深入理解Linux 虚拟内存管理》。学习驱动无须如此深入, 但是对它的工作原理的基本了解是必要的. 解了必要的背景知识后,才可以学习内核管理内存的数据结构. Linux是一个虚拟内存系统(但是在没有MMU的CPU中跑的ucLinux除外), 意味着在内核启动了MMU 之后所有使用的地址不直接对应于硬件使用的物理地址,这些地址(称之为虚拟地址)都经过了MMU转换为物理地址之后再从CPU的内存总线中发出,读取/写入数据. 这样 VM 就引入了一个间接层, 它是许多操作成为可能: 1、系统中运行的程序可以分配远多于物理内存的内存空间,即便单个进程都可拥有一个大于系统的物理内存的虚拟地址空间. 2、虚拟内存也允许程序对进程的地址空间运用多种技巧, 包括映射程序的内存到设备内存.等等~~~ 1、地址类型 Linux 系统处理几种类型的地址, 每个有它自己的含义: 用户虚拟地址:User virtual addresses,用户程序见到的常规地址. 用户地址在长度上是 32 位或者 64 位, 依赖底层的硬件结构, 并且每个进程有它自己 的虚拟地址空间.

linux设备驱动中常用函数

Linux2.6设备驱动常用的接口函数(一) ----字符设备 刚开始,学习linux驱动,觉得linux驱动很难,有字符设备,块设备,网络设备,针对每一种设备其接口函数,驱动的架构都不一样。这么多函数,要每一个的熟悉,那可多难啦!可后来发现linux驱动有很多规律可循,驱动的基本框架都差不多,再就是一些通用的模块。 基本的架构里包括:加载,卸载,常用的读写,打开,关闭,这是那种那基本的咯。利用这些基本的功能,当然无法实现一个系统。比方说:当多个执行单元对资源进行访问时,会引发竞态;当执行单元获取不到资源时,它是阻塞还是非阻塞?当突然间来了中断,该怎么办?还有内存管理,异步通知。而linux 针对这些问题提供了一系列的接口函数和模板框架。这样,在实际驱动设计中,根据具体的要求,选择不同的模块来实现其功能需求。 觉得能熟练理解,运用这些函数,是写号linux设备驱动的第一步。因为是设备驱动,是与最底层的设备打交道,就必须要熟悉底层设备的一些特性,例如字符设备,块设备等。系统提供的接口函数,功能模块就像是工具,能够根据不同的底层设备的的一些特性,选择不同的工具,方能在linux驱动中游刃有余。 最后就是调试,这可是最头疼的事。在调试过程中,总会遇到这样,那样的问题。怎样能更快,更好的发现并解决这些问题,就是一个人的道行咯!我个人觉得: 发现问题比解决问题更难! 时好时坏的东西,最纠结! 看得见的错误比看不见的错误好解决! 一:Fops结构体中函数: ①ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); 用来从设备中获取数据. 在这个位置的一个空指针导致 read 系统调用以-EINVAL("Invalid argument") 失败. 一个非负返回值代表了成功读取的字节数( 返回值是一个 "signed size" 类型, 常常是目标平台本地的整数类型). ②ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); 发送数据给设备. 如果 NULL, -EINVAL 返回给调用 write 系统调用的程序. 如果非负, 返回值代表成功写的字节数 ③loff_t (*llseek) (struct file *, loff_t, int); llseek 方法用作改变文件中的当前读/写位置, 并且新位置作为(正的)返回值. loff_t 参数是一个"long offset", 并且就算在 32位平台上也至少 64 位宽. 错误由一个负返回值指示. 如果这个函数指针是 NULL, seek 调用会以潜在地无法预知的方式修改 file 结构中的位置计数器( 在"file 结构" 一节中描述). ④int (*open) (struct inode *, struct file *);

Linux内核空间和用户空间

Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数据可能不在内存中。 Linux内核地址映射模型 x86 CPU采用了段页式地址映射模型。进程代码中的地址为逻辑地址,经过段 页式地址映射后,才真正访问物理内存。 段页式机制如下图。 Linux内核地址空间划分

通常32位Linux内核地址空间划分0~3G为用户空间,3~4G为内核空间。注意这里是32位内核地址空间划分,64位内核地址空间划分是不同的。 Linux内核高端内存的由来 当内核模块代码或线程访问内存时,代码中的内存地址都为逻辑地址,而对应到真正的物理内存地址,需要地址一对一的映射,如逻辑地址0xc0000003对应的物理地址为0×3,0xc0000004对应的物理地址为0×4,… …,逻辑地址与物理地址对应的关系为 物理地址= 逻辑地址– 0xC0000000

么物理地址为0×40000001的内存,内核该怎么去访问呢?代码中必须要有内存逻辑地址的,0xc0000000 ~ 0xffffffff的地址空间已经被用完了,所以无法访问物理地址0×40000000以后的内存。 显然不能将内核地址空间0xc0000000 ~ 0xfffffff全部用来简单的地址映射。因此x86架构中将内核地址空间划分三部分:ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。 ZONE_HIGHMEM即为高端内存,这就是内存高端内存概念的由来。 在x86结构中,三种类型的区域如下: ZONE_DMA 内存开始的16MB ZONE_NORMAL 16MB~896MB ZONE_HIGHMEM896MB ~ 结束 Linux内核高端内存的理解 前面我们解释了高端内存的由来。Linux将内核地址空间划分为三部分ZONE_DMA、 ZONE_NORMAL和ZONE_HIGHMEM,高端内存HIGH_MEM地址空间范围为0xF8000000 ~ 0xFFFFFFFF(896MB~1024MB)。那么如内核是如何借助128MB高端内存地址空间是如何实现访问可以所有物理内存?

相关主题
文本预览
相关文档 最新文档