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

发布于 2024-11-08 14:59:13 字数 739 浏览 8 评论 0原文

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我是男神闪亮亮 2024-11-15 14:59:13

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

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

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

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

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.

ま昔日黯然 2024-11-15 14:59:13

这是我找到的 ioremap 参考:

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

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

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

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

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

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 range

Returns:
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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文