Axis Area
Public Area
Special pages
NOTE
This page provides an example of how to map kernel memory in a userspace application using a mmap() driver. The driver (for Linux 2.6) and userspace program should be looked upon as example code, you will most probably have to change the code to fit your needs. To gain more information about mmap() read the man page: 'man mmap' in a shell or in your browser by clicking here. Additional information on memory mapping can be found in chapter 15 “Memory Mapping and DMA” in the Linux Device Drivers book, Third Edition.
The code below can be downloaded as a tar.gz file: mmap.tar.gz.
#include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/mm.h> #define MAP_MAJOR 126 static int map_mmap(struct file *filp, struct vm_area_struct *vma); struct file_operations map_fops = { .open = nonseekable_open, .mmap = map_mmap }; static int map_mmap(struct file *filp, struct vm_area_struct *vma) { if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot)) { return -EAGAIN; } return 0; } static int __init map_init(void) { if (register_chrdev(MAP_MAJOR,"map", &map_fops) <0 ) { printk("unable to get major for map module\n"); return -EBUSY; } return 0; } void __exit map_cleanup(void) { unregister_chrdev(MAP_MAJOR,"map"); } MODULE_LICENSE("GPL"); module_init(map_init); module_exit(map_cleanup);
MODULE = map.o LINUX_2_6 = $(shell grep '^\#define UTS_RELEASE' \ $(AXIS_KERNEL_DIR)/include/linux/version.h \ | grep "2.6") objects-y += map_main.o ifneq ($(LINUX_2_6),) map-y = $(objects-y) else obj-y = $(objects-y) endif PREVENT_RECURSIVE_INCLUDE = 1 include $(AXIS_TOP_DIR)/modules/rules.build_modules install: local_install local_install: $(MKNOD) -m 0644 $(prefix)/dev/map c 126 0
This userspace program maps 3 MB (uncached) SDRAM and writes to it.
#include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> int main(void) { char* data; int fd = open("/dev/map", O_RDWR); data = mmap(0, 0x00300000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0xc0000000); close(fd); data[100] = 3; munmap(data, 0x00300000); return 0; }