Example of MMAP Memory Page in "Deep Linux driver kernel mechanism" by Chen xuesong

Source: Internet
Author: User
Tags dmesg

In this example, a character device is used. The device applies for a piece of memory, and file_operations has the MMAP function. In test. C, the MMAP memory can be modified by operating the user memory.

Driver code mmap_demo.c

#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/device.h>#include <linux/cdev.h>#include <linux/fs.h>#include <linux/fcntl.h>#include <linux/gfp.h>#include <linux/string.h>#include <linux/mm_types.h>#include <linux/types.h>#include <linux/mm.h>#include <linux/highmem.h>#include <asm/io.h>#include <linux/miscdevice.h>#definemmap_printk(args...) do {printk(KERN_ALERT "MMAP_DEMO " args); } while(0)#defineKSTR_DEF"hello world from kernel virtual space"#definemmap_name"mmap_demo"static struct page *pg;static struct timer_list timer;static voidtimer_func (unsigned long data){  printk ("timer_func:%s\n", (char *) data);  timer.expires = jiffies + HZ * 10;  add_timer (&timer);}static intdemo_open (struct inode *inode, struct file *filp){  mmap_printk ("mmap_demo device open\n");  return 0;}static intdemo_release (struct inode *inode, struct file *filp){  mmap_printk ("mmap_demo device closed\n");  return 0;}static intdemo_mmap (struct file *filp, struct vm_area_struct *vma){  int err = 0;  unsigned long start = vma->vm_start;  unsigned long size = vma->vm_end - vma->vm_start;  err = remap_pfn_range (vma, start, vma->vm_pgoff, size, vma->vm_page_prot);  return err;}static struct file_operations mmap_fops = {  .owner = THIS_MODULE,  .open = demo_open,  .release = demo_release,  .mmap = demo_mmap,};static struct miscdevice misc = {  .minor = MISC_DYNAMIC_MINOR,  .name = mmap_name,  .fops = &mmap_fops,};static int __initdemo_map_init (void){  int ret = 0;  char *kstr;  pg = alloc_pages (GFP_HIGHUSER, 0);  SetPageReserved (pg);  kstr = (char *) kmap (pg);  strcpy (kstr, KSTR_DEF);  printk ("kpa = 0x%lx, kernel string = %s\n", page_to_phys (pg), kstr);  init_timer (&timer);  timer.function = timer_func;  timer.data = (unsigned long) kstr;  timer.expires = jiffies + HZ * 10;  add_timer (&timer);  ret = misc_register (&misc);  printk ("the mmap miscdevice registered\n");  return ret;}module_init (demo_map_init);static voiddemo_map_exit (void){  del_timer_sync (&timer);  misc_deregister (&misc);  printk ("the device misc_mmap deregistered\n");  kunmap (pg);  ClearPageReserved (pg);  __free_pages (pg, 0);}module_exit (demo_map_exit);MODULE_LICENSE ("DUAL BSD/GPL");MODULE_AUTHOR ("BG2BKK");

Makefile

KERNELDIR=/lib/modules/$(shell uname -r)/buildPWD=$(shell pwd)obj-m = mmap_demo.omodules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulestest: test.cgcc $< -o $@.oclean:rm -rf *.o *~ *.ko* *.order *.symvers *.mod*

Test code

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <sys/mman.h>#defineMAP_SIZE 4096#defineUSTR_DEF "String changed from the user space"int main(int argc, char *argv[]){int fd;char *pdata;if(argc <= 1){printf("USAGE: main devfile pamapped\n");return 0;}fd = open(argv[1], O_RDWR | O_NDELAY);if(fd  >= 0){pdata= (char *)mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, strtoul(argv[2], 0, 16));printf("USERAddr = %p, DATA from kernel %s\n",pdata, pdata);printf("Writing a string to the kernel space...\n");strcpy(pdata, USTR_DEF);printf("Done\n");munmap(pdata, MAP_SIZE);close(fd);}return 0;}

Test process

Make

Make Test

Sudo insmod mmap_demo.ko

Dmesg to view the Memory Page address in the mmap_demo device, and print the output

kpa = 0xc1f0000, kernel string = (null)the mmap miscdevice registered
timer_func:hello world from kernel virtual spacetimer_func:hello world from kernel virtual spacetimer_func:hello world from kernel virtual spacetimer_func:hello world from kernel virtual spacetimer_func:hello world from kernel virtual spacetimer_func:hello world from kernel virtual space

The address is 0xc1f0000.

Then sudo./test. O/dev/mmap_demo 0xc1f0000

Then the output is

USERAddr = 0xb7744000, DATA from kernel hello world from kernel virtual spaceWriting a string to the kernel space...Done

Dmesg output result is

timer_func:hello world from kernel virtual spacetimer_func:hello world from kernel virtual spaceMMAP_DEMO mmap_demo device openMMAP_DEMO mmap_demo device closedtimer_func:String changed from the user spacetimer_func:String changed from the user space

The original data in the memory.

Hello world from kernel virtual space changed
String changed from the user space

This example shows how to use a simple MMAP device.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.