io_mapping 函式¶
API¶
linux/io-mapping.h 中的 io_mapping 函式提供了一種抽象,用於高效地將 I/O 裝置的小區域對映到 CPU。最初的用途是支援 32 位處理器上的大型圖形孔徑,其中 ioremap_wc 無法用於將整個孔徑靜態對映到 CPU,因為它會佔用太多的核心地址空間。
在驅動程式初始化期間使用以下函式建立對映物件:
struct io_mapping *io_mapping_create_wc(unsigned long base,
unsigned long size)
“base”是要進行可對映區域的匯流排地址,“size”表示要啟用的對映區域的大小。兩者都以位元組為單位。
此 _wc 變體提供了一個對映,該對映只能與 io_mapping_map_atomic_wc()、io_mapping_map_local_wc() 或 io_mapping_map_wc() 一起使用。
透過此對映物件,可以根據要求臨時或長期對映單個頁面。當然,臨時對映效率更高。它們有兩種形式:
void *io_mapping_map_local_wc(struct io_mapping *mapping,
unsigned long offset)
void *io_mapping_map_atomic_wc(struct io_mapping *mapping,
unsigned long offset)
“offset”是已定義對映區域內的偏移量。訪問超出建立函式中指定區域的地址會產生未定義的結果。使用非頁面對齊的偏移量會產生未定義的結果。返回值指向 CPU 地址空間中的單個頁面。
此 _wc 變體返回頁面的寫合併對映,並且只能與 io_mapping_create_wc() 建立的對映一起使用。
臨時對映僅在呼叫者上下文中有效。不保證對映在全域性可見。
io_mapping_map_local_wc() 在 X86 32 位系統上有一個副作用,即它會停用遷移以使對映程式碼工作。任何呼叫者都不能依賴此副作用。
io_mapping_map_atomic_wc() 具有停用搶佔和頁面錯誤的副作用。不要在新程式碼中使用。請改用 io_mapping_map_local_wc()。
巢狀對映需要按相反順序撤銷,因為對映程式碼使用堆疊來跟蹤它們。
addr1 = io_mapping_map_local_wc(map1, offset1);
addr2 = io_mapping_map_local_wc(map2, offset2);
...
io_mapping_unmap_local(addr2);
io_mapping_unmap_local(addr1);
對映透過以下函式釋放:
void io_mapping_unmap_local(void *vaddr)
void io_mapping_unmap_atomic(void *vaddr)
“vaddr”必須是最後一次 io_mapping_map_local_wc() 或 io_mapping_map_atomic_wc() 呼叫返回的值。這將解除指定對映並撤銷對映函式的副作用。
如果需要在保持對映的同時休眠,可以使用常規變體,儘管這可能會顯著變慢:
void *io_mapping_map_wc(struct io_mapping *mapping,
unsigned long offset)
這與 io_mapping_map_atomic/local_wc() 的工作方式類似,只是它沒有副作用,並且指標是全域性可見的。
對映透過以下函式釋放:
void io_mapping_unmap(void *vaddr)
用於透過 io_mapping_map_wc() 對映的頁面。
在驅動程式關閉時,必須釋放 io_mapping 物件:
void io_mapping_free(struct io_mapping *mapping)