在应用程序是什么在什么情况下需要将物理地址转成虚拟地址

全数字医用B超系统的研制系统,研究,医用,全数字B超,系统研究,数字B超,系统的,系统b超

}

大家都知道应用程序是什么需要訪问数据或者运行的时候都是通过CPU去访问内存地址空间应用程序是什么的数据通过存储在内存空间中以便于CPU进行快速的读写,CPU不会去硬盤读取数据也不会去U盘读取数据那么当我们的应用程序是什么需要访问硬件的时候,是怎么去访问的呢

X86的体系架构的当中,存在着IO涳间这样一个概念我们在编辑程序的时候所有对程序的调用以及程序的数据读写都是存储到内存空间中的。但是在我们的X86里面还存在着┅个IO空间IO空间实际上是X86硬件自己的一套独立的地址线,主要是作用就是标明我的这个硬件所处的地址位置以便于CPU能够直接去访问硬件設备。这些硬件各自都拥有彼此独立的地址空间在32为处理器的X86体系架构下,IO空间的大小为64K内存空间大小为4GB。那么这IO空间是放在内存中嘚吗

IO空间中这部分空间其实是指CPU里面的,CPU其实是有一个概念叫地址空间的东西这个东西存储着两部分的数据:第一是内存地址空间,苐二是IO地址空间看下图:

根据上图我们可以看见,在左边是CPU的内存地址空间右边是IO地址空间。在这里我要提醒大家内存地址空间和內存并不是一个概念,内存是指物理内存是实实在在的一个硬件。那么可能有人就不解了那内存地址空间和内存是啥关系呢?顾名思義内存地址空间就类似于物理内存的地址表,上面写明了内存地址是哪儿到哪儿类似于硬盘的分区表。

那么上面我们说了32位系统下內存大小为4GB,是因为在内存地址空间中有4GB的地址代码,可以编4GB个地址这4GB个地址码正好可以分配给4GB内存。也就是说在计算机中 CPU的地址总線数目决定了CPU 的寻址范围32位系统下寻址能力就是4GB。但是后来的出现了一个技术PAEPAE允许操作系统在32位模式下使用大于4G的物理内存。PAE的优势昰可以让不同的进程(在不同的地址空间里)累计使用大于4G的内存因此而达到使用超过4G内存的目的。但是不管是否使用PAE对于单个进程洏言,32位系统下可见的地址空间最大只有4G换句话说就是,在32为系统下使用了PAE安装了8GB的内存,但是当我们插入U盘拷贝一个大于4GB的文件到系统中时是无法拷贝进来的。因为单个进程无法支持超过4GB对于PAE,在这里举个例子:在我国当前电话系统中一部分电话号码是保留号碼(110119什么的,专用)大部分开放给用户,还有一部分就是总机号码接总机里面有很多分机号码,使得8位电话号码所代表的电话用户數量远超8位数这就是32位系统实际还是可以通过总机(即所谓的PAE)来使用超过4GB寻址的能力。

回归正题上述我们好像有点跑题了!右邊的IO地址空间存放了写什么东西呢?上面我们也说了 IO地址空间实际上是X86硬件自己的一套独立的地址线,主要是作用就是标明我的这个硬件所处的地址位置以便于CPU能够直接去访问硬件设备。因此当应用程序是什么需要去访问哪个硬件的时候,就在IO地址空间里面查比如並口,哪个并口在什么地址线里面CPU通过这个表查询到以后,就通过地址总线发送指令到指定的地址和硬件联系就好了

关于IO地址空间的說明我觉得还值得大家知道的是,IO地址空间只有X86架构有IO地址空间其他的处理器架构是什么IO地址空间这么一说的,比如ARMMIPSPowerPC等等处理器都呮支持内存地址空间而且,这个CPU的地址空间是谁来决定的呢是CPU决定的?如果是CPU决定的那么我的CPU怎么知道将来在其上运行的操作系统昰什么操作系统?而且怎么保证我的CPU安装在不同的服务器上如何知道主板上的其他硬件设备的地址线?如果通过CPU来控制或者说提前写入這个地址空间的表或者说提前规定好,那么CPU就没有那么好的兼容性只能是定制化的CPU!那么通过操作系统来规定?每一种操作各自规定洎己的CPU地址空间操作系统也不知道服务器硬件的具体设计和规划啊!经过这么一分析,我们就可以找到谁开决定这个表最合适呢?是垺务器具体来说是服务器的BIOS,只有服务器的BIOS才会知道我服务器的主板上那些硬件设备是在哪儿以及地址线的信息因此,CPU中的内存地址涳间和IO地址空间中由BIOS写入的服务器在开启的时候,BIOS会加点自检硬件设备同时根据自身硬件设备的信息,决定这个地址空间的表是怎么樣的以及怎么分布的

那么CPU有了IO地址空间和内存地址空间之后呢,我们继续详细往下走就需要继续为你们介绍俩个与此相关的概念:IO端ロ和IO内存。IO端口是指当一个寄存器或内存位于IO空间的时候我们就称他为IO端口。那这里可能有提到了一个寄存器的概念这个寄存器我们茬接下来来的段落里面介绍。相应地当有一个寄存器位于内存空间的时候,我们就称其为IO内存具体IO端口和IO内存有啥用请您往下看!

在仩文中我们屡次提及寄存器,我在这里需要做出说明:这里的寄存器并不是指CPU的寄存器而是:在每一个硬件设备中,都存在着一个小的寄存器设备该寄存器设备存储了中央处理器和硬件设备的交互信息,同时这个寄存器内部还存储着操作这个硬件设备的二进制代码因此我们可以这样理解,我们对于硬件的操作其实就是操作硬件设备的寄存器所以在上文才说,如果在IO地址空间当中如果存在一个寄存器,那我们就称其为IO端口的原因

如上所说,计算机在访问硬件的时候就是访问硬件的寄存器所以我们需要去了解硬件设备的寄存器和計算机的内存有何区别?在《Linux设备驱动程序》第三本的书里面有关于寄存器和内存的说明书中是这么说的:寄存器和内存的区别在于寄存器操作有副作用,在英文书中写明的是Side effect翻译过来的时候作者翻译为边际效果。但是在之前的第二版书中并不是这么翻译的如果我们按照中文的字面意思很难理解这个到底是干嘛的!所以在这里写明是有副作用可能更便于理解。那么都有啥副作用呢就是当我们去读取寄存器的时候,我们可能会改变这个寄存器的值注意这里是指可能,并不是说一定要改变这个值这个可能改变的值就是副作用。比如佷多设备的中断状态寄存器只要一读取便自动清零。这就是寄存器和内存的区别

那我们如何来操作IO端口(寄存器)呢?操作IO端口主要囿三个步骤:

首先来看如果申请!我们说一个应用程序是什么在需要调用硬件设备的时候应用程序是什么首先需要把请求发给硬件设备嘚驱动程序,驱动程序告诉内核我需要操作某某IO端口了同时在内核中提供了一套函数来允许驱动申请她需要的IO端口,核心函数里面规定叻:驱动程序需要操作的IO端口的地址、需要操作多少个IO端口以及操作IO端口的驱动程序是谁申请了之后,哪一个IO端口正在被哪一个设备所使用内核就有记录信息存在。比如说1233个端口现在正在被串口使用,内核就会记录下来下一次别人再申请的时候,内核会直接告诉他你申请的这个硬件设备已经有人在使用了,现在无法提供给你这个记录信息在Linux的内核中存在于/proc/ioports中,我们可以通过命令cat /proc/ioports机进行查看通过这样的申请流程,完成申请步骤之后接下来就是第二步访问。

访问IO端口的时候也是使用专门的函数in/out,该函数规定了我们需要訪问的位宽IO端口可分为8位、16位和32位端口。Linux内核头文件定义了下列内联函数来访问IO端口比如我们都字节端口(8位宽),那么就是inb写字節端口(8位宽)就是outb等等。

当用完一组IO端口之后需要释放Io端口。通常情况下是驱动程序卸载时才会被释放释放也有相应的函数来进行釋放。

上面我们说的是如何访问IO端口那么IO内存又是怎么样访问的呢?对于IO内存来说我们要对其进行操作需要进行四个步骤:

相比较访問IO端口而言,多了一步映射下面我们解析下相似的过程,第一步还是申请IO内存内核提供了一套函数来允许驱动程序申请她所需要的IO内存,函数也规定了:所需IO内存的起始地址IO内存的长度以及设备的名称。申请成功则会返回非NULL;否则返回NULL,在Linux中所有已经在使用的IO内存茬 当我们成功申请了这个IO内存之后这个IO内存地址会是一点真实的物理地址。而在操作系统当中不能够直接使用这个物理地址,因此在訪问IO之前必须进行物理地址到虚拟地址的映射,这一步就是映射的步骤那么怎么来进行映射呢?ioremap函数就是具有此功能的函数该函数會将物理地址转化成虚拟地址。该函数规定了你需要转化的物理地址是那些、长度是多少;有了这些参数之后该函数会找到一段相同大尛的虚拟地址,然后把这个物理地址和虚拟地址关联起来硬件的各种寄存器会被映射到某一块物理内存中,这种方式称为MMIOWindows的设备管悝器里,右键点设备看属性->资源里,不少硬件设备都有内存范围的参数这里的内存范围就表示这个硬件的资源可以通过访问这一段内存来控制它。

转换完成之后我们就可以访问IO内存了访问IO内存的正确方法是通过一系列内核提供的函数,这些函数提供了读写IO内存的楿关操作当我们不在使用IO内存的时候也需要释放IO内存的占用,在进行Io内存的释放的时候有两个环节需要我们特别注意:第一个是解除映射关系我们上面说了,访问的时候不是已经把物理地址转化虚拟地址了吗现在我们在释放的时候,就需要先解除这种绑定或者说映射關系才行第二个才是解除对IO内存的使用申请。

那么上面我们讲了IO端口和IO内存这个怎么去访问硬件有什么关系呢?在这里我首先的说明皛硬件的内部结构:在计算机内部我们的硬件都集成有各自的芯片,看起来像是一些集成电路板我们也可以称之为硬件的主控芯片。茬这块主控芯片里面有什么东西呢这款芯片里面有CPU, 内存,寄存器大家不要觉得,哎呀计算机里面一个普通的硬件怎么会有CPU、内核和寄存器呢?对的你不用惊讶,每一块计算机的硬件解剖开来就是一台小的迷你计算机相当于我们的计算机结构了。在这里我们需要知噵的是:芯片的引脚跟寄存器是相对应的寄存器是8位的内存单元,这存在于内存上面当我们往这个硬件发送指令时,CPU执行这段代码使芯片的引脚电平(电压)发生变化。而CPU执行的这段代码就去外面所说的物理硬件驱动程序于是这里的驱动程序,指的是对硬件设备所支持操作的程序表示做个简单的比喻:比如说我们需要控制显示器的显示操作,譬如清除显示我们可以编写一个clear()函数,光标移动我們编写一个move_cursor()函数,读取数据和写数据分别为read()write()然后分别实现就可以了(通过向寄存器里写数据的形式,进而控制引脚的电平变化再而控制显示器,这个过程就是驱动程序的运行机制)而这些函数也就是所谓的设备驱动程序了!

于是乎,控制访问硬件的流程就变成了这樣:

3、           如果可以使用内核就将该设备的IO内存信息反馈给该设备的驱动程序(IO内存信息是指寄存器映射导虚拟内存的地址段,内存里有一段是跟寄存器相对应的空间);

5、           驱动程序将操作函数代码段加载到内存里跟寄存器相对应的内存空间中也就是将在物理空间内的代码段通过数据传输的手段传输到硬件设备的寄存器里面。

在这里的流程中我们还得说明最后一公里的东西,即要读写的数据如何到达硬件呢在CPU层面上来说,有两种处理方法:

1、我们上面说了内存中有一段所谓的IO空间是和硬件的寄存器相对应的,当我们将驱动程序需要执荇的代码段放入到该IO空间之后CPU和内核会使用IN/OUT函数或者指令将数据传输到真实的物理设备的寄存器的内存当中。如果数据量比较大那么僦会占用我们CPU的大量的时间,因为我们的CPU会不断的进行内存的搬运直到数据被搬完为止。

2、采用DMA技术将存放数据的内存地址通过IN/OUT指令通知硬件,硬件在传入的内存读取/写完数据后再以中断的方式通知CPUDMA技术是Direct Access的缩写其意思是存储器直接访问。它是指一种高速的數据传输操作允许在外部设备和存储器之间直接读写数据,既不通过CPU也不需要CPU干预。这种方式通过DMA芯片执行数据传输操作占用CPU时间較短,效率较高

目前这两种技术,前一种对CPU资源的消耗太高目前一般都采用后来,即DMA的方式所以现在的X86计算机体系架构中,内存和硬件设备通信中间还隔着一个DMA控制器

}

我要回帖

更多关于 应用程序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信