Chapter 15 MMAPDMA 15 1 4 Virtual Memory























- Slides: 23
Chapter 15 MMAP與DMA
15. 1. 4 虛擬記憶區(Virtual Memory Areas)(2/6) 例:以下是init行程VMA的分布情形。cat /proc/1/maps 08048000 -0804 e 000 -0804 f 000 -08053000 40000000 -40015000 -40016000 -40017000 42000000 -4212 e 000 -42131000 -42133000 bffff 000 -c 0000000 ffffe 000 -fffff 000 r-xp rw-p rwxp r-xp rw-p rwxp ---p 00006000 00000000 00014000 00000000 0012 e 00000000 03: 01 00: 00 03: 01 00: 00 64652 0 96278 0 80290 0 /sbin/init text /sbin/init data zero-mapped BSS /lib/ld-2. 3. 2. so text /lib/ld-2. 3. 2. so data BSS for ld. so /lib/tls/libc-2. 3. 2. so BSS for libc Stack segment vsyscall page text data 各欄位的格式如下: start-end|perm|offset|major: minor|inode|imagename
14. 1. 4 虛擬記憶區(Virtual Memory Areas)(5/6) unsigned long vm_pgoff; 此區域在檔案的相對位置(以page為單位). unsigned long vm_flags; 一組描述VMA屬性的旗標. VM_IO表示此VMA映射到I/O region, VM_RESERVED要求記憶體管理系統不要將此VMA交 換到磁碟上. struct vm_operations_struct *vm_ops; 一組可供核心用來操作VMA的函式. void *vm_private_data; 供驅動程式用於儲存私有資訊的欄位.
15. 2 mmap作業方法 (1/2) 就驅動程式的觀點而言, 記憶映射可用來提供直接存取裝置記憶 體的能力給user-space應用程式. 觀察X Window System server的VMA如何映射到/dev/mem, 有助 於理解mmap()系統呼叫的典型用法. cat /proc/731/maps 000 a 0000 -000 c 0000 rwxs 000 a 0000 03: 01 282652 000 f 0000 -00100000 r-xs 000 f 0000 03: 01 282652 00400000 -005 c 0000 r-xp 0000 03: 01 1366927 006 bf 000 -006 f 7000 rw-p 001 bf 000 03: 01 1366927 2 a 95828000 -2 a 958 a 8000 rw-s fcc 00000 03: 01 282652 2 a 958 a 8000 -2 a 9 d 8 a 8000 rw-s e 8000000 03: 01 282652 /dev/mem /usr/X 11 R 6/bin/Xorg /dev/mem a 0000:VGA卡的視訊記憶體的標準位置 e 8000000:位於系統記憶體的頂端,直接對應到顯卡上的視訊記憶體 從/proc/iomem也可看出顯示卡上的各段I/O記憶體
15. 2. 2 簡單的mmap實作 簡單線性的映射作法,讓應用程式可透過user-space的某段虛 擬位址來存取裝置記憶體 static int simple_remap_mmap(struct file *filp, struct vm_area_struct *vma) { if (remap_pfn_range(vma, vma->vm_start, vm->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; vma->vm_ops = &simple_remap_vm_ops; simple_vma_open(vma); return 0; }
15. 2. 3 增添新的VMA作業方法 void simple_vma_open(struct vm_area_struct *vma) { printk(KERN_NOTICE "Simple VMA open, virt %lx, phys %lxn", vma->vm_start, vma->vm_pgoff << PAGE_SHIFT); } void simple_vma_close(struct vm_area_struct *vma) { printk(KERN_NOTICE "Simple VMA close. n"); } static struct vm_operations_struct simple_remap_vm_ops = {. open = simple_vma_open, . close = simple_vma_close, };
15. 3. 1實做直接I/O的關鍵函式 宣告於<linux/mm. h> int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, int len, int write, int force, struct page **pages, struct vm_area_struct **vmas); struct task_struct *tsk :指向要執行I/O的task_struct, struct mm_struct *mm:指向的mm_struct即是形成的虛擬位址空間 的所有VMA unsigned long start:user-space緩衝區的起始位址 int len:該緩衝區的長度 int write:非零值,映射的記憶頁是供write存取用 int force:不理會指定記憶頁的保護旗標,對驅動程式應設為零 struct page **pages:指向user-space緩衝區的struct page串列 此函式的回傳值:實際映射的記憶頁數量。























