Address Space in Linux

Address Space and Accessing Different Region


 Figure From Sysplay.in


1: virt_to_phys— map virtual addresses to physical
unsigned long virt_to_phys (volatile void * address);
address to remap
The returned physical address is the physical (CPU) mapping for the memory address given.
It is only valid to use this function on addresses directly mapped or allocated via kmalloc

2: phys_to_virt— map physical address to virtual
void * phys_to_virt (unsigned long address);
address to remap

The returned virtual address is a current CPU mapping for the memory address given. It is only valid to
use this function on addresses that have a kernel mapping.

3:ioremap— map bus memory into CPU space
void __iomem * ioremap (unsigned long offset , unsigned long size);
(bus address of the memory) (size of the resource to map)
ioremap performs a platform specific sequence of operations to make bus memory CPU accessible via
the readb/readw/readl/writeb/ writew/writel functions

4: iounmap - Unmaping bus memory
void iounmap(void * address);
            (bus address of the memory)


Address Types:
--------------

1:virtual addresses:
These are the regular addresses seen by user-space programs.
User addresses are either 32 or 64 bits in length based on Architecture.

2:Physical addresses:
The addresses used between the processor(CPU) and the system's memory.
Physical addresses are 32- or 64-bit based on Architecture.

3:Bus addresses:
The addresses used between peripheral buses and memory.
Often, they are the same as the physical addresses used by the processor,
but that is not necessarily the case.Some architectures can provide
an I/O memory management unit (IOMMU) that remaps addresses between a bus
and main memory

4:Kernel logical addresses:
5:Kernel Virtual Address space : provided by Kmalloc();

-----------------------------------------------------------------------------------
Every module for ex: GPIO module has its own memory map i.e. 4GB Mem Model Archict dependent.

physical address specified in the processor's technical reference manual.
First you need to check if the memory region is being used or not using check_mem_region. memory region using request_mem_region,
then map the GPIO module using ioremap or ioremap_nocache (map bus memory into CPU space),
which returns a void pointer.
The returned address is not guaranteed to be usable directly as a virtual address;
it is only usable by ioread*|iowrite*|read*|write*, etc.
functions. Use ioread8|16|32/iowrite8|16|32 functions to read or write from/to i/o ports.
Finally you need to iounmap to unmap the memory and then you need to release memory region using release_mem_region.
Usually in kernel space, most of the time there is no need check and request for the memory region.
You only need to map bus memory into CPU space using ioremap or ioremap_nocache and unmap using iounmap.

----------------------------------------------------------------------------------------------------------------------------

Driver development I/O memory and I/O ports
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

Requesting I/O ports:
====================
struct resource *request_region( unsigned long start, unsigned long len,char *name);

Tries to reserve the given region and returns NULL if unsuccessful.
Example:

request_region(0x0170, 8, "ide1");
void release_region( unsigned long start, unsigned long len);

Reading / writing on I/O ports:
-------------------------------
The implementation of the below functions and the exact unsigned
type can vary from platform to platform!

bytes:
------
unsigned inb(unsigned port);
void outb(unsigned char byte, unsigned port);

words:
------
unsigned inw(unsigned port);
void outw(unsigned char byte, unsigned port);

"long" integers:
---------------
unsigned inl(unsigned port);
void outl(unsigned char byte, unsigned port);

Requesting I/O memory:
======================

Equivalent functions with the same interface

struct resource * request_mem_region( unsigned long start, unsigned long len, char *name);

void release_mem_region( unsigned long start, unsigned long len);


Mapping I/O memory in virtual memory

To access I/O memory, drivers need to have a virtual address that the processor can handle.

ioremap functions satisfy this need:
#include <asm/io.h>;

void *ioremap(unsigned long phys_addr, unsigned long size);
void iounmap(void *address);

Accessing I/O memory:
--------------------
Directly reading from or writing to addresses returned by ioremap (“pointer dereferencing”)
may not work on some architectures.Use the below functions instead. They are always portable and safe:

unsigned int ioread8(void *addr); (same for 16 and 32)

void iowrite8(u8 value, void *addr); (same for 16 and 32
---------------------------------------------------------------------------------------------------

For EXAMPLE: GPIO module has its own memory map i.e. 4GB Mem Model Archict dependent.

physical address specified in the processor's technical reference manual.
First you need to check if the memory region is being used or not using check_mem_region. memory region using request_mem_region,
then map the GPIO module using ioremap or ioremap_nocache (map bus memory into CPU space),
which returns a void pointer.
The returned address is not guaranteed to be usable directly as a virtual address;
it is only usable by ioread*|iowrite*|read*|write*, etc.
functions. Use ioread8|16|32/iowrite8|16|32 functions to read or write from/to i/o ports.
Finally you need to iounmap to unmap the memory and then you need to release memory region using release_mem_region.
Usually in kernel space, most of the time there is no need check and request for the memory region.
You only need to map bus memory into CPU space using ioremap or ioremap_nocache and unmap using iounmap.

---------------------------------------------------------------------------------------------------

Post a Comment

0 Comments