Chapter 15 Memory Mapping and DMA
Memory mapping is one of the most interesting features of modern Unix systems. As far as drivers are concerned, memory mapping can be implemented to provide user programs with direct access to device memory.
The mm_struct and vm_area_struct
Vitrual memory area, aka. VMA, is the kernel data structure used to manage distinct regions of a process’s address space.When a user-space process calls mmap to map device memory into its address space, the system responds by creating a new VMA to represent that mapping. A driver that supports mmap needs to help that process by completing the initialization of that VMA.
mmap Advantage:
High throughput. For instance, X server, which transfers a lot of data to and from video memory; mapping the graphic display to user space dramatically improves the throughput, as opposed to an lseek/write operations. And, for PCI device. Most PCI periperals map their control registers to a memory address, and a high-performance applciation might prefer to have direct access to the registers instead of repeatedly having to call ioctl to get its work done.
Page size granularity:
The limitation of mmap is that the mapping is PAGE_SIZE grained; therefore, the mapped area must be a multiple of PAGE_SIZE and must live in physical memory starting at an address that is a multiple of PAGE_SIZE.
The mmap method is part of the file_operations structure and is invoked when the mmap system call is issued(Finally I figured haha). A struct Refresh from here(kernel 2.4.2):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *filp, struct vm_area_struct *vma);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*readv) (struct file *, const struct iovec *, unsigned long,
loff_t *);
ssize_t (*writev) (struct file *, const struct iovec *, unsigned long,
loff_t *);
};
Copyright: all contents are from Linux Device Driver3e(LDD).