ioremaplinux
⑴ Linux中的kmap
Linux中的kmap機制用於在系統啟動後,ioremap()功能可用之前,提供一個臨時的映射區域,即PKmap region。該區域在早期用於early_ioremap(),系統啟動後則作為持久性的kmap區域,支持kmap()或kmap_atomic()函數進行虛擬地址與物理內存的映射。
kmap與vmalloc區域類似,都屬於臨時映射,但與之不同的是,vmalloc主要用於物理內存的分配及映射,而kmap則更側重於短期映射操作,且單次映射僅支持一個page。
臨時映射的持久性體現在其快速建立與釋放的特性上,比如初始化page cache中的某個page frame內容為0的操作,可以迅速完成,而無需長時間佔用資源。
在x86架構中,PKmap region的大小設定為4MB,與每個page的大小4KB相匹配,最多可以映射1024個page。這樣的設計使查找未被映射的虛擬地址更加高效,避免了遍歷所有頁面以尋找空閑地址所耗費的時間。
kmap使用hash table管理頁面映射關系,相較於vmalloc/vmap,其查找機制更為簡潔高效。每個映射關系由page_address_map結構表示,包含指向物理頁面的struct page和映射後的虛擬地址信息。
查找空閑虛擬地址的具體過程涉及page_address()函數,它不僅能夠映射high memory zone的物理頁面,也能用於獲取low memory zones(如ZONE_NORMAL和ZONE_DMA)的物理頁面通過線性映射得到的虛擬地址。
對於low memory zones,lowmem_page_address()函數通過memory model和page_to_pfn()轉換,將物理地址轉換為虛擬地址。對於high memory zone中的頁面,則通過hash演算法找到對應的page_address_slot,遍歷其中的page_address_map,匹配到struct page,完成映射。
如果找到空閑的虛擬地址,會通過set_pte_at()建立虛擬地址與page frame的映射,並將映射關系存儲在page_address_map中。整個過程通過流程圖直觀展現,kmap_atomic()則提供了一個不會阻塞的映射選項。
kmap的實現與管理機制體現了Linux內核在資源管理與優化方面的細致考量,通過靈活的映射機制,有效支持了系統的高效運行。