Specifications
This is the Title of the Book, eMatter Edition
Copyright © 2005 O’Reilly & Associates, Inc. All rights reserved.
The mmap Device Operation
|
431
map the physical page located at address 64 KB—instead, we see a page full of zeros
(the host computer in this example is a PC, but the result would be the same on
other platforms):
morgana.root# ./mapper /dev/mem 0x10000 0x1000 | od -Ax -t x1
mapped "/dev/mem" from 65536 to 69632
000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
001000
The inability of remap_pfn_range to deal with RAM suggests that memory-based
devices like scull can’t easily implement mmap, because its device memory is conven-
tional RAM, not I/O memory. Fortunately, a relatively easy workaround is available
to any driver that needs to map RAM into user space; it uses the nopage method that
we have seen earlier.
Remapping RAM with the nopage method
The way to map real RAM to user space is to use vm_ops->nopage to deal with page
faults one at a time. A sample implementation is part of the scullp module, intro-
duced in Chapter 8.
scullp is a page-oriented char device. Because it is page oriented, it can implement
mmap on its memory. The code implementing memory mapping uses some of the
concepts introduced in the section “Memory Management in Linux.”
Before examining the code, let’s look at the design choices that affect the mmap
implementation in scullp:
• scullp doesn’t release device memory as long as the device is mapped. This is a
matter of policy rather than a requirement, and it is different from the behavior
of scull and similar devices, which are truncated to a length of
0 when opened for
writing. Refusing to free a mapped scullp device allows a process to overwrite
regions actively mapped by another process, so you can test and see how pro-
cesses and device memory interact. To avoid releasing a mapped device, the
driver must keep a count of active mappings; the
vmas field in the device struc-
ture is used for this purpose.
• Memory mapping is performed only when the scullp
order parameter (set at mod-
ule load time) is
0. The parameter controls how __get_free_pages is invoked (see
the section “get_free_page and Friends” in Chapter 8). The zero-order limitation
(which forces pages to be allocated one at a time, rather than in larger groups) is
dictated by the internals of __get_free_pages, the allocation function used by
scullp. To maximize allocation performance, the Linux kernel maintains a list of
free pages for each allocation order, and only the reference count of the first page
in a cluster is incremented by get_free_pages and decremented by free_pages. The
mmap method is disabled for a scullp device if the allocation order is greater than
zero, because nopage deals with single pages rather than clusters of pages. scullp
,ch15.13676 Page 431 Friday, January 21, 2005 11:04 AM