内存读/写操作中的总线错误

时间:2011-05-20 09:11:30

标签: c linux linux-kernel linux-device-driver embedded-linux

我为内存读/写操作编写了一个内核程序。

#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=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);
}

在此程序中,执行指令

时发生总线错误
 *mem1=0x1010F0F0;

2 个答案:

答案 0 :(得分:3)

ioremap()用于将总线内存映射到CPU空间。

ioremap 执行特定于平台的操作序列以生成总线内存CPU    可通过readb / readw / readl / writeb / writew / writel函数和其他mmio助手访问。 不保证返回的地址可以直接用作虚拟地址。

kmalloc 在物理内存中的连续内存位置分配内存并返回它的虚拟地址指针。

ioremap需要输入中的物理地址,但您将虚拟地址作为物理地址提供给ioremap 。该虚拟地址值可能与物理地址值相同任何总线,它将物理总线空间映射到虚拟(我们必须使用readb / readw / readl / writeb / writew / writel访问设备寄存器),因为它给出了错误。

答案 1 :(得分:0)

我发现这是ioremap的参考:

  

void * ioremap(unsigned long phys_addr,
                 无符号长尺寸        )

     

将I / O内存重新映射到内核地址空间。

     

参数:    phys_addr物理地址范围的开始
   物理地址范围的大小

     

返回:   映射范围的虚拟起始地址   这里没有真正的映射。仅返回虚拟地址。

看起来它将硬件设备地址映射到虚拟内存,而不是从真实内存分配的内存块。