MMIO和PIO


1、概念

內存映射I/O(MMIO)【統一編址】和端口映射I/O(PMIO)【獨立/單獨編址】是兩種互為補充的I/O方法,用於設備驅動程序和設備通信,即在CPU和外部設備之間。

(1)在MMIO中,內存和I/O設備共享同一個地址空間。 MMIO是應用得最為廣泛的一種IO方法,它使用相同的地址總線來處理內存和I/O設備,I/O設備的內存和寄存器被映射到與之相關聯的地址。當CPU訪問某個內存地址時,它可能是物理內存,也可以是某個I/O設備的內存。因此,用於訪問內存的CPU指令也可來訪問I/O設備。每個I/O設備監視CPU的地址總線,一旦CPU訪問分配給它的地址,它就做出響應,將數據總線連接到需要訪問的設備硬件寄存器。為了容納I/O設備,CPU必須預留給I/O一個地址區域,該地址區域不能給物理內存使用。

實現MMIO:內核使用ioremap()將IO設備的物理內存地址映射到內核空間的虛擬地址上; 用戶空間程序使用mmap(2)系統調用將IO設備的物理內存地址映射到用戶空間的虛擬內存地址上,一旦映射完成,用戶空間的一段內存就與IO設備的內存關聯起來,當用戶訪問用戶空間的這段內存地址范圍時,實際上會轉化為對IO設備的訪問。iowrite8(u8 value, void *addr);  iowrite16/iowrite32 

(2)PMIO(IO端口也可以映射到虛擬地址空間進行訪問ioport_map)。在PMIO中,內存和I/O設備有各自的地址空間。 端口映射I/O通常使用一種特殊的CPU指令,專門執行I/O操作。在Intel的微處理器中,使用的指令是IN和OUT。這些指令可以讀/寫1,2,4個字節(例如:outb, outw, outl)從/到IO設備上。I/O設備有一個與內存不同的地址空間,為了實現地址空間的隔離,要么在CPU物理接口上增加一個I/O引腳,要么增加一條專用的I/O總線。

用戶空間想訪問IO端口:必須使用ioperm和iopl系統調用(#include ) 來獲得進行操作I/O端口的權限。ioperm 為獲取單個端口的操作許可,iopl 為獲取整個I/O空間許可。這2個函數都是x86特有的。

x86 CPU的I/O空間就只有64KB(0-0xffff)。

Linux內核必須使用“資源”來記錄分配給每個硬件設備的I/O端口。資源表示某個實體的一部分,這部分被互斥地分配給設備驅動程序。在這里,資源表示I/O端口地 址的一個范圍。每個資源對應的信息存放在resource數據結構中

 

2、區別

(1)在MMIO中,IO設備和內存共享同一個地址總線,因此它們的地址空間是相同的;而在PMIO中,IO設備和內存的地址空間是隔離的。

(2)在MMIO中,無論是訪問內存還是訪問IO設備,都使用相同的指令(mov類型的讀寫內存的指令);而在PMIO中,CPU使用特殊的指令訪問IO設備,在Intel微處理器中,使用的指令是IN和OUT。

(3)對MMIO操作是申請-映射-訪問-釋放(訪問流程:request_mem_region() -> ioremap() -> ioread8()/iowrite8() -> iounmap() -> release_mem_region() );PMIO是申請-訪問-釋放(不映射到內存空間,直接使用 intb()/outb()之類的函數來讀寫IO端口。

(4)MMIO:CPU需要截獲虛擬機訪問的具體地址,並發生了異常,從VM-mode下退出來,讓qemu繼續處理,模擬硬件的行為即可。這就是MMIO下的設備模擬過程,CPU截獲MMIO的是misconfig異常;PMIO:CPU只要截獲VM(Virtual Machine)的in、out指令,就可以知道CPU想要訪問設備,那么用軟件來模擬硬件的行為,就可以讓VM覺得自己有設備。

(5)MMIO:cat /proc/iomem命令查看外設的IO內存物理地址分布情況;PMIO:cat /proc/ioport,列出了系統所有的IO端口分布情況,注意這邊看到的地址不是物理地址,而是IO端口號的分布情況,跟物理地址沒有關系,CPU訪問外設寄存器就是通過傳入這些端口號來訪問外設寄存器的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM