jollen.org

Jollen 的 Blog
Jollen's email: jollen # jollen.org
more:  Jollen's Training

[教育訓練紀錄] Mmap and remap_page_range(), in the nutshell.

.作者:jollen/
.日期:April 22, 2007 10:34 AM


繼 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:

// refer to: bttv-dirver.c
int do_card_mmap(struct vm_area_struct *vma, char *adr, unsigned long size)
{
    unsigned long start = (unsigned long)adr;
    unsigned long page, pos;

    pos = (unsigned long)BaseIOAddress;
#if 1  // page or the total size ?
    while (size >0) {
       page = pos;
       if (remap_page_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
	   return -EAGAIN;
       start+=PAGE_SIZE;
       pos+=PAGE_SIZE;
       size-=PAGE_SIZE;
    }
#else
    if (remap_page_range(vma, start, pos, size, PAGE_SHARED))
       return -EAGAIN;
#endif
    return 0;
}

// refer to: videodev.c
int card_mmap(struct file *filp, struct vm_area_struct *vma)
{
   do_card_mmap(vma, (char *)vma->vm_start, (unsigned long)(vma->vm_end-vma->vm_start));
   return 0;
}
/**************************************************/

struct file_operations card_fops = {
  open:card_open,
  release:card_release,
  ioctl:card_ioctl,
  mmap:card_mmap,
};

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

同學對此部份如有觀念上的疑問,可透過 forum 討論。

來源: Jollen's Blog

Tags:

純手工打造說明:技術專欄文章為 Jollen 原創,內容皆為人工撰寫,無 AI 生成。轉載請註明出處與作者,並全文引用。轉載時請在文章開頭或結尾明顯處註明「本文出處:https://www.jollen.org,已取得原作者同意並授權使用。」
訂閱電子報:不定期 Jollen's Blog 精選文章隨 Moko365 電子報寄送;請透過 Moko365 電子報訂閱(可隨時取消)。

Copyright(c) 2001–2007 www.jollen.org. All rights reserved.
Last update: 2026-07-22