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内核在资源管理与优化方面的细致考量,通过灵活的映射机制,有效支持了系统的高效运行。