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)