Download presentation
1
Linux ‘Demand-Paging’
Using ‘nopage()’ with ‘mmap()’
2
Recall ‘mysis.c’ device-driver
Demonstrated the ‘mmap()’ driver-method Used ‘remap_page_range()’ function Mapped video frame-buffer to user space Set up all page-table entries in advance Driver was tested using ‘mmwhere.cpp’ NOTE: A flaw was spotted by Qing Huang A revised version now posted on website
3
Deferring page-table setups
An alternative ‘mmap()’ driver-method Don’t set up all page-tables in advance Many entries might never be needed Waste of cpu time to build unused entries Our frame-buffer may span 128 MB Each page-directory entry controls 4 MB So there may be 32 (=128/4) page-tables! Our screen display needs less than 8 MB
4
Linux ‘nopage()’ mechanism
Avoids using ‘remap_page_range()’ Requires a ‘vm_operations_struct’ object This object contains ‘callback’ functions The main one is named ‘nopage()’ We can implement a ‘nopage()’ method It will get called by the ‘page_fault’ handler It can set up a needed page-table entry
5
Prototype for ‘nopage()’
struct page * my_vma_nopage( struct vm_area_struct *vma, unsigned long address, int write_access );
6
Less to do for ‘mmap()’ In device-driver’s ‘mmap()’ method:
Does not call ‘remap_page_range()’ Installs ‘callback’ functions instead: vma->vm_ops = &my_vm_ops;
7
Demo: ‘mynopage.c’ A working example is on course website
It can be tested using ‘mmwhere.cpp’ Changes are ‘transparent to application But offer improved efficiency inside kernel Less memory consumed by page-tables Less processor time used for table setups
8
An idea for further efficiency
Bypass ‘mmap()’ mechanism altogether Use Pentium’s ‘Page-Size Extensions’ Use page-directory entries for 4MB frames Avoids allocating/initializing page-tables Avoids creating/inserting ‘vm_area_struct’ Mapping done by driver’s ‘open()’ method Unmapping is done by ‘release()’ method
9
Page-Directory is modified
Where is task’s page-directory located? long *pgdir = current->mm->pgd; Which directory-entries do we modify? What page attributes should we assign? Demo maps frame-buffer to 0x Why? It seems kernel won’t contend this
10
Loop to setup directory entries
long physaddr = fb_base; long virtaddr = 0x ; long entry_index = (virtaddr >> 22); long entry_count = (fb_size >> 22); for (i = 0; i < entry_count; i++) { pgdir[ entry_index ] = physaddr | 0x87; physaddr += (1<<22); ++entry_index; }
11
‘mmtest.cpp’ Simple application to test ‘mymmfb.c’
It opens the device file ‘/dev/vram’ It uses ‘lseek()’ to get frame-buffer’s size Then it directly writes to the frame-buffer It uses the agreed-upon virtual-address: long *vram = (long)0x ;
12
Is this a ‘safe’ approach?
Can we create a confliting application? We could read the Linux source-code Or we could perform some experiments! Try using ‘malloc()’ to allocate regions See if any regions overlay our frame-buffer But how would we know if they did?
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.