Memory-Mapped I/O

Basic Concept

Memory-mapped I/O 是一種讓 CPU 控制 device controller 的方式:OS 把 device-control registers 映射到 CPU 的 physical address space 中,讓 CPU 可以用一般的 load/store instruction 去讀寫這些地址。

這裡的「memory-mapped」不代表 device register 真的變成 DRAM,而是 CPU 發出某個 memory address 時,硬體會把這個 access 導向 device controller,而不是導向 main memory。因此同一套 CPU 指令可以同時用來存取 memory 和控制 I/O device。

CPU store to mapped address
→ bus 將這個 address 導向 device controller
→ controller 的 control/data register 被修改
→ device 開始執行對應操作

Motivation

CPU 要對 controller 下命令,必須能讀寫 controller 的 register。傳統做法是提供特殊 I/O instruction,讓 CPU 對 I/O port address 做 read/write。Memory-mapped I/O 的想法是:與其設計另一套特殊 instruction,不如把 controller registers 放進 CPU 原本的 address space,讓一般 memory access 就能控制 device。

這樣的好處是介面比較一致,而且對需要大量資料傳輸的裝置特別有用。例如 graphics controller 可以把 screen buffer 映射到一大段 memory region,程式只要改那段 address 的內容,controller 就能根據內容產生畫面。如果每個 pixel 都要靠特殊 I/O instruction 寫入,成本會高很多。

How it works

  1. 開機或 device initialization 時,OS / firmware 決定某個 Device registers 對應到哪些 physical addresses。
  2. Device driver 知道這些 addresses 對應的 register 語意,例如哪裡是 status、哪裡是 command、哪裡是 data-out。
  3. Driver 透過一般 memory read/write 操作讀 status 或寫 command。
  4. 硬體偵測到該 address 屬於 device controller,因此把操作送到 controller,而不是送到 DRAM。
  5. Controller 根據 register 的內容控制 device。

Protection Issue

因為 memory-mapped I/O 看起來像 memory access,如果 user process 可以任意寫這些 addresses,就等於可以直接控制硬體,可能造成資料破壞或 system crash。因此 protected-mode OS 會用 memory protection 把這些 mapping 限制在 kernel 或 privileged process 可用的範圍內。

MMIO vs Memory-Mapped File

Memory-mapped I/O 和 memory-mapped file 都使用「把某個東西映射成 memory address」的概念,但它們對象不同:

  • Memory-mapped I/O:address 對應到 device controller registers 或 device memory,用來控制硬體。
  • Memory-mapped file:address 對應到 file contents,透過 virtual memory / demand paging 讀寫檔案內容。

兩者都讓程式用 memory access 形式操作非一般 memory 的東西,但 MMIO 是硬體控制介面,memory-mapped file 是 file access interface。