Mmap and remap_page_range(), in the nutshell.

心已赠人 2022-08-24 04:16 137阅读 0赞














繼 Linux programming 課程紀錄「








小談 mmap() 與 VMA」後,今天在 Linux device driver 課程再聊到有關 VMA 與 mmap driver function 的重要觀念;重點紀錄如下。

當 user-space 呼叫 mmap() system call wrapper function 後,kernel 會在 process address space 裡建立新的 VMA,並在 callback mmap driver function 時將「該」VMA 傳遞給我們的驅動程式。

因此,在驅動程式裡,只需要利用 remap_page_range() 將 kernel-space 的 memory:

- I/O memory

- RAM(reserved pages)

- Virtual address space(reserved pages)

對應到該 VMA 即可。最後,寫出了以下的 skeleton code:

  1. // refer to: bttv-dirver.c
  2. int do_card_mmap(struct vm_area_struct *vma, char *adr, unsigned long size)
  3. {
  4. unsigned long start = (unsigned long)adr;
  5. unsigned long page, pos;
  6. pos = (unsigned long)BaseIOAddress;
  7. #if 1 // page or the total size ?
  8. while (size >0) {
  9. page = pos;
  10. if (remap_page_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
  11. return -EAGAIN;
  12. start+=PAGE_SIZE;
  13. pos+=PAGE_SIZE;
  14. size-=PAGE_SIZE;
  15. }
  16. #else
  17. if (remap_page_range(vma, start, pos, size, PAGE_SHARED))
  18. return -EAGAIN;
  19. #endif
  20. return 0;
  21. }
  22. // refer to: videodev.c
  23. int card_mmap(struct file *filp, struct vm_area_struct *vma)
  24. {
  25. do_card_mmap(vma, (char *)vma->vm_start, (unsigned long)(vma->vm_end-vma->vm_start));
  26. return 0;
  27. }
  28. /**************************************************/
  29. struct file_operations card_fops = {
  30. open:card_open,
  31. release:card_release,
  32. ioctl:card_ioctl,
  33. mmap:card_mmap,
  34. };

remap_page_range() 的原理是去修改 page table,但是要不要以 “page” 為最小單位做 page table 的修改(呼叫 ‘remap_page_range’),必須視情況而定!

发表评论

表情:
评论列表 (有 0 条评论,137人围观)

还没有评论,来说两句吧...

相关阅读