Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to parse mmap memory Mapping in Linux driver

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

Today, I will talk to you about how to parse the mmap memory mapping in the Linux driver. Many people may not know much about it. In order to make you understand better, the editor has summarized the following contents for you. I hope you can get something according to this article.

Where is mmap in linux?

What is mmap?

As shown in the figure above, mmap is a way to operate these devices. The so-called operating devices, such as IO ports (lighting a LED), LCD controllers, and disk controllers, are actually reading and writing data to the physical address of the device.

However, because the application can not directly manipulate the device hardware address, the operating system provides such a mechanism-memory mapping, which maps the device address to the process virtual address, and mmap is the interface to implement memory mapping.

There are many ways to operate the device, such as ioctl, ioremap

The advantage of mmap is that mmap maps device memory to virtual memory, so users operating virtual memory is equivalent to directly operating devices, eliminating the replication process from user space to kernel space, and increasing data throughput compared with IO operations.

What is memory mapping?

Since mmap is the interface that implements memory mapping, what is memory mapping? Look at the picture below.

The driver runs in kernel space, so the driver is oriented to all processes.

There are two ways to switch from user space to kernel space:

(1) system call, namely soft interrupt

(2) hardware interrupt

What is in the virtual address space?

Knowing what the virtual address space is, what is inside the virtual address space? Look at the picture below.

It is now known that memory mapping maps device addresses to process space addresses (note: not all memory mappings are mapped to process address space, ioremap is mapped to kernel virtual space, mmap is mapped to process virtual addresses), essentially assigning a vm_area_struct structure to the process address space, that is, mapping device addresses to this structure The mapping process is what the driver does.

Implementation of memory Mapping

Take the character device driver as an example, the general operation of the character device is as follows

The following is the source code for mmap_driver.c

[cpp] view plain copy

/ / all module code contains the following two header files

# include

# include

# include / / define dev_t type

# include / / define struct cdev structure and related operations

# include / / define kmalloc interface

# include / / define virt_to_phys interface

# include / / remap_pfn_range

# include

# define MAJOR_NUM 990

# define MM_SIZE 4096

Static char driver_name [] = "mmap_driver1"; / / driver module name

Static int dev_major = MAJOR_NUM

Static int dev_minor = 0

Char * buf = NULL

Struct cdev * cdev = NULL

Static int device_open (struct inode * inode, struct file * file)

{

Printk (KERN_ALERT "device open\ n")

Buf = (char *) kmalloc (MM_SIZE, GFP_KERNEL); / / the kernel applies for memory only by page, so that it can be treated as a virtual device later.

Return 0

}

Static int device_close (struct inode * indoe, struct file * file)

{

Printk ("device close\ n")

If (buf)

{

Kfree (buf)

}

Return 0

}

Static int device_mmap (struct file * file, struct vm_area_struct * vma)

{

Vma- > vm_flags | = VM_IO;// indicates the mapping to the device IO space

Vma- > vm_flags | = VM_RESERVED;// indicates that the memory area cannot be swapped out. In the device driver, the relationship between virtual pages and physical pages should be long-term, should be retained, and cannot be casually swapped out by other virtual pages.

If (remap_pfn_range (vma,// virtual memory area, that is, the device address will be mapped here

Vma- > start address of vm_start,// virtual space

Virt_to_phys (buf) > > the page frame number of PAGE_SHIFT,// corresponding to physical memory. The physical address is moved 12 bits to the right.

Vma- > vm_end-vma- > vm_start,// mapping area size, which is generally an integral multiple of the page size

Vma- > vm_page_prot)) / / Protection attribute

{

Return-EAGAIN

}

Return 0

}

Static struct file_operations device_fops =

{

.owner = THIS_MODULE

.open = device_open

.release = device_close

.mmap = device_mmap

}

Static int _ init char_device_init (void)

{

Int result

Dev_t dev;// high 12 bits represent primary equipment number, and low 20 bits represent secondary device number.

Printk (KERN_ALERT "module init2323\ n")

Printk ("dev=%d", dev)

Dev = MKDEV (dev_major, dev_minor)

Cdev = cdev_alloc (); / / allocate space for character device cdev

Printk (KERN_ALERT "module init\ n")

If (dev_major)

{

Result = register_chrdev_region (dev, 1, driver_name); / / statically assign device number

Printk ("result =% d\ n", result)

}

Else

{

Result = alloc_chrdev_region (& dev, 0,1, driver_name); / / dynamically assign device number

Dev_major = MAJOR (dev)

}

If (result

< 0) { printk(KERN_WARNING"Cant't get major %d\n", dev_major); return result; } cdev_init(cdev, &device_fops);//初始化字符设备cdev cdev->

Ops = & device_fops

Cdev- > owner = THIS_MODULE

Result = cdev_add (cdev, dev, 1); / / registers character devices with the kernel

Printk ("dffd =% d\ n", result)

Return 0

}

Static void _ exit char_device_exit (void)

{

Printk (KERN_ALERT "module exit\ n")

Cdev_del (cdev)

Unregister_chrdev_region (MKDEV (dev_major, dev_minor), 1)

}

Module_init (char_device_init); / / Module loading

Module_exit (char_device_exit); / / Module exit

MODULE_LICENSE ("GPL")

MODULE_AUTHOR ("ChenShengfa")

Here is the test code test_mmap.c

[cpp] view plain copy

# include

# include

# include

# include

# include

Int main (void)

{

Int fd

Char * buffer

Char * mapBuf

Fd = open ("/ dev/mmap_driver", O_RDWR); / / Open the device file, and the kernel can get the index node of the device file and populate the inode structure

If (fd

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report