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



我写了一个内核程序用于内存读/写操作。

#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;

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

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

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

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

这是我

发现的ioremap参考:

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

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

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

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

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

相关内容

  • 没有找到相关文章

最新更新