MMIO 内存映射I/O 使用内存读写指令访问端口
问题1:
内存映射IO之后,将硬件IO端口地址映射到内存空间地址,那么之后用内存读写指令访问硬件,可是在硬件层解释不通啊,我们都知道CPU和外设都是有M/IO引脚的,当M/IO引脚表示访问内存时,外设是不会被使能的,这时候怎么可能访问外设?
举例来说 在X86环境下,intel处理器,我们有一个摄像头,32M的缓存ram
当我们把摄像头缓存ram映射到内存空间后,当我们访问显存时,使用mov 指令而不是in out 指令,那么这时候M/IO引脚肯定表示的是访问内存,这时候摄像头肯定是无法被使能的,那么怎么可能被CPU的mov指令访问呢?
问题2:
如果我们实用32位处理器模式,那么当我们给电脑配备4G内存时,是不是由于需要映射一些外设寄存器 缓存等等,所以这4G内存肯定不能全部被利用??
问题3:
在linux和win中,当我们写驱动时,如何查找哪个外设的寄存器和缓存被映射到了哪个地址上?也就是说我如何才能知道外设的某个寄存器的地址是多少?
问题4:
在IO独立编制时,x86环境下,外设寄存器访问和外设的ram访问是否是一样的,都是通过in out指令,只是访问地址不一样,外设的自身ram是一块连续的io地址? MMIO IO映射 端口访问
[解决办法]
问题1:
“硬件IO”端口是针对你的硬件而言,不是针对CPU。就用你的摄像头的例子,摄像头的“IO端口”实际上接在了CPU的“memory总线”上。实际上x86的IO端口(用in/out指令访问的端口)寻址范围仅仅64K,现在很少有使用“CPU IO端口”的设备了。
问题2:
你是对的。
问题3:
有两种情况。
对于非PNP设备,设备说明书或者设计人员(如果你们自己做线路板)会告诉你;
对于PNP设备,有一套硬件上的握手协议。总线驱动知道如何去做这些工作。你自己的设备驱动可以利用总线驱动提供的函数获取你想知道的寄存器地址。
问题4:
寄存器和RAM访问可能一样也可能不一样。见问题1。这取决于(设备侧的寄存器和RAM总线)与(CPU侧的IO总线和内存总线)如何连接。理论上,如果你将外设RAM连接到CPU的IO总线,你甚至可以用in/out指令访问外设RAM。不过一般来说,外设寄存器用in/out指令或访问内存的方式访问,而外设ram总是用访问内存的方式访问。
外设的自身ram地址一般来说是连续的,但不总是这样。这取决于外设的设计和驱动如何进行地址映射。这个问题深究起来十分复杂,好在一般来说总是连续的,所以不用管例外情况就是了。
[解决办法]
你要看一点硬件方面的知识,比如:总线,数据线,指令线,内部译码电路等。cpu给出的操作地址由于地址段不一样,最后作用在物理设备上的类型也是不同的。显卡ram,还有我们平时说的SDRAM,DDR 等内存,在cpu看来都是外设。就是外部设备。