Specifications
This is the Title of the Book, eMatter Edition
Copyright © 2005 O’Reilly & Associates, Inc. All rights reserved.
430
|
Chapter 15: Memory Mapping and DMA
Note that the user process can always use mremap to extend its mapping, possibly
past the end of the physical device area. If your driver fails to define a nopage
method, it is never notified of this extension, and the additional area maps to the
zero page. As a driver writer, you may well want to prevent this sort of behavior;
mapping the zero page onto the end of your region is not an explicitly bad thing to
do, but it is highly unlikely that the programmer wanted that to happen.
The simplest way to prevent extension of the mapping is to implement a simple
nopage method that always causes a bus signal to be sent to the faulting process.
Such a method would look like this:
struct page *simple_nopage(struct vm_area_struct *vma,
unsigned long address, int *type);
{ return NOPAGE_SIGBUS; /* send a SIGBUS */}
As we have seen, the nopage method is called only when the process dereferences an
address that is within a known VMA but for which there is currently no valid page
table entry. If we have used remap_pfn_range to map the entire device region, the
nopage method shown here is called only for references outside of that region. Thus,
it can safely return
NOPAGE_SIGBUS to signal an error. Of course, a more thorough
implementation of nopage could check to see whether the faulting address is within
the device area, and perform the remapping if that is the case. Once again, however,
nopage does not work with PCI memory areas, so extension of PCI mappings is not
possible.
Remapping RAM
An interesting limitation of remap_pfn_range is that it gives access only to reserved
pages and physical addresses above the top of physical memory. In Linux, a page of
physical addresses is marked as “reserved” in the memory map to indicate that it is
not available for memory management. On the PC, for example, the range between
640 KB and 1 MB is marked as reserved, as are the pages that host the kernel code
itself. Reserved pages are locked in memory and are the only ones that can be safely
mapped to user space; this limitation is a basic requirement for system stability.
Therefore, remap_pfn_range won’t allow you to remap conventional addresses,
which include the ones you obtain by calling get_free_page. Instead, it maps in the
zero page. Everything appears to work, with the exception that the process sees pri-
vate, zero-filled pages rather than the remapped RAM that it was hoping for. None-
theless, the function does everything that most hardware drivers need it to do,
because it can remap high PCI buffers and ISA memory.
The limitations of remap_pfn_range can be seen by running mapper, one of the sam-
ple programs in misc-progs in the files provided on O’Reilly’s FTP site. mapper is a
simple tool that can be used to quickly test the mmap system call; it maps read-only
parts of a file specified by command-line options and dumps the mapped region to
standard output. The following session, for instance, shows that /dev/mem doesn’t
,ch15.13676 Page 430 Friday, January 21, 2005 11:04 AM