I hav written a kernel program for memory read/write operation.
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/init.h>
#include<linux/io.h>
static uint32_t *mem_alloc(void)
{
uint32_t *base, *mem;
base=kmalloc(5*sizeof(uint32_t),GFP_KERNEL);
mem开发者_StackOverflow=ioremap(base,5*sizeof(uint32_t));
return(mem);
}
static void mem_write(uint32_t *memory)
{
uint32_t *mem1;
mem1=memory;
int i;
for(i=0;i<5;i++)
{
*mem1=0x1010F0F0;
mem1++;
}
}
static int __init insert(void)
{
uint32_t *memory;
memory=mem_alloc();
mem_write(memory);
return 0;
}
static void __exit remove(uint32_t *memory)
{
kfree(memory);
}
in this program a bus error occurs when executing the instruction
*mem1=0x1010F0F0;
ioremap() is used to map the bus memory into the CPU space.
ioremap performs a platform specific sequence of operations to make bus memory CPU accessible via the readb/readw/readl/writeb/ writew/writel functions and the other mmio helpers. The returned address is not guaranteed to be usable directly as a virtual address.
kmalloc allocate the memory in contiguous memory location in physical memory and returns it's virtual address pointer.
ioremap expects the physical address in input, but you are giving the virtual address as physical address to ioremap.That virtual address value may same as the physical address value of the any of bus and it was mapping that physical bus space to virtual (and we have to access the device registers using readb/readw/readl/writeb/writew/writel), because of that it was giving error.
This is what I find as a reference for ioremap:
void* ioremap (unsigned long phys_addr,
unsigned long size
)Remap I/O memory into kernel address space.
Parameters: phys_addr begin of physical address range
size size of physical address rangeReturns: virtual start address of mapped range Here no real mapping is done. Only the virtual address is returned.
Looks like it maps a hardware device address into virtual memory, not a memory block allocated from real memory.
精彩评论