drivers中file_operations的mmap操作的作用是:
將設備驅動內(nèi)核空間的內(nèi)存映射到用戶空間里,可以通過用戶空間中的mmap系統(tǒng)調(diào)用代替系統(tǒng)調(diào)用write和read。目的是提高讀寫效率。
系統(tǒng)調(diào)用mmap:
void* mmap (caddr_t addr, size_t len, int prot, int flags, off_t offset)
其中addr一般為NULL,目的是使內(nèi)核自動分配可用的虛擬空間地址,并通過返回值返回,并與MAP_FAILED比較;
prot一般為PROT_WRITE | PROT_READ; flags為MAP_SHARED或MAP_PRIVATE之一;offset表示從設備文件都開始多大偏移處映射,一般為0。
文件操作mmap :
int (*mmap) (struct file* filp, struct vm_area_struct* vma)
定義struct vm_operations_struct xxx_vm_ops = {
.open = xxx_vm_open,
.close = xxx_vm_close,
.nopage = xxx_vm_nopage,
};
編寫mmap文件操作函數(shù)的方式有兩種:
一.使用remap_pfn_range一次性申請,不需要定義nopage函數(shù)
1.在mmap中調(diào)用remap_pfn_range;
2.在mmap中對vma->vm_ops進行附值;
3.在mmap結尾處主動調(diào)用vm_ops中的open;
二.定義nopage函數(shù),在發(fā)生缺頁時由內(nèi)核申請內(nèi)存中的物理頁,由driver在nopage中將page與vma掛鉤
1.mmap中除了對vma->vm_ops進行附值和主動調(diào)用vm_ops中的open外;
2.將設備內(nèi)存首先按PAGE_SIZE對齊,最終只將頁對齊的設備內(nèi)存映射到用戶空間中。然后將對齊操作處理后的虛擬地址逐頁進行SetPageReserved(virt_to_page(virt_addr))保留(可選)
3.在nopage函數(shù)中,首先計算缺頁的虛擬內(nèi)存地址實際的內(nèi)存頁物理地址與設備文件開始處的偏移量offset;然后比較該偏移量是否超過映射的設備文件大小;最后將該缺頁地址的虛擬地址變換成頁幀號并申請該頁。