Reproduced:
Request_mem_region,ioremap and Phys_to_virt ()
Linux defines three macros that operate on I/O memory resources in header file Include/linux/ioport.h:
(1) request_mem_region () macro, request to allocate the specified I/O memory resource.
(2) Check_mem_region () macro to check whether the specified I/O memory resource is already occupied.
(3) Release_mem_region () macro to release the specified I/O memory resource.
The three macros are defined as follows:
#define Request_mem_region (Start,n,name) __request_region (&iomem_resource, (start), (n), (name))
#define Check_mem_region (Start,n) __check_region (&iomem_resource, (start), (n))
#define Release_mem_region (Start,n) __release_region (&iomem_resource, (start), (n))
Where the parameter start is the starting physical address of the I/O memory resource (the physical address of the CPU in the physical address space of the RAM), parameter n Specifies the size of the I/O memory resource. After the request IO memory resource succeeds, the mapping operation is started with Ioremap.
void * __IOREMAP (unsigned long phys_addr, unsigned long size, unsigned long flags) maps an IO address space to the virtual address space of the kernel for easy access. Ingress: Phys_addr is the IO address where the start of the map is to be mapped; the size of the space to be mapped; flag is the flag that is associated with the permission to map the IO space;
Implementation: To determine the IO address space to be mapped, the low Pci/isa address does not need to be remapped, does not allow the user to map the IO address space to the RAM in use, and finally applies a vm_area_struct structure, calling Remap_area_pages to fill out the page table, If the filling process is unsuccessful, the Vm_area_struct space for the application is released, and the page table is modified based on the virtual address and the physical address to be mapped, and the kernel can then use this virtual address to access the mapped physical address.
For direct mapped I/O addresses Ioremap do nothing (for example, a physical address is returned directly in a uclinux without the MMU). With Ioremap (and Iounmap), the device can access any I/O memory space, regardless of whether it is mapped directly to the virtual address space. However, these addresses can never be used directly (as the address returned by Kmalloc), but with readb functions.
/***********************************************************************/
The same is true from the physical address assigned to the virtual address, and the following function: Phys_to_virt () the actual address is converted to a virtual address, the two are different. Using ioremap and phys_to_virt to do physical address conversions to virtual addresses found:
addr = (unsigned int volatile *)Ioremap(0x56000088,12);
PRINTK (Kern_alert "%x\n", addr);
addr = (unsigned int volatile *) Phys_to_virt (0x56000088);
PRINTK (Kern_alert "%x\n", addr);
The addr value returned by two functions is not the same. The reason is:
(1) Phys_to_virt in the kernel simply subtracts a fixed offset from the address:
#ifndef __virt_to_phys
#define __virt_to_phys (x) ((x)-Page_offset + phys_offset)
#define __PHYS_TO_VIRT (x) ((x)-Phys_offset + page_offset)
#endif
Note: Phys_offset =0x50000000, in the kernel with MMU, Page_offset is 0xc0000000; in the kernel without the MMU, with Phys_offset.
(2) the principle of Ioremap() is that the kernel creates a new Mapping page table based on the specified physical address, and the relationship between the physical address and the virtual address is set up by these page tables! :
This can be seen from the ioremap function body.
Reference Original: Http://blog.csdn.net/fuyjlu/archive/2009/12/20/5039782.aspx
Reference Original: Http://blog.csdn.net/xdicac/archive/2009/10/30/4743708.aspx
Reference Original: Http://blog.csdn.net/unbutun/archive/2009/08/28/4488768.aspx
Request_mem_region,ioremap and Phys_to_virt ()