Monday, October 3, 2011

how to write to a physical address in Linux?


 Usually you do this in several steps in a device driver:

1. Call request_mem_region() to request virtual memory region;
2. Call ioremap() to map physical address to virtual address;
3. Read/write mapped virtual address by using iowriteXX() /
ioreadXX(), etc. Here XX can be 8, 16, or 32 for example, represents
bit width.
4. Call iounmap() and release_mem_region() to release memory mapping;
[ NOTE: phys_to_virt() only works with directly mapped physical address. Using phys_to_virt() is the best idea, anyway.]


To make access generic
The addresses referring to RAM are termed as physical addresses,and those referring to device maps are bus addresses.In Linux, none of these are directly accessible, but are to mapped to virtual addresses and then accesses through them. This is to make RAM and device access generic.


void *ioremap (unsigned long device_bus_address, unsigned long device_region_size);
void iounmap (void *virt_addr);

Once mapped to virtual addresses, it depends on the device datasheet as to which set of device registers and/or device memory to read from or wirte into, by adding their offsets to the virtual address returned by ioremap().
unsigned int ioread8(void *virt_addr);
unsigned int ioread16(void *virt_addr);
unsigned int ioread32(void *virt_addr);

unsigned int iowrite8(u8 value, void *virt_addr);
unsigned int iowrite16(u16 value, void *virt_addr);
unsigned int iowrite32(u32 value, void *virt_addr);

 

No comments: