【问题标题】:How to repair segmentation fault?如何修复分段错误?
【发布时间】:2012-09-04 20:05:07
【问题描述】:

我需要在自定义硬件上的嵌入式 Linux 环境中使用 TMS320DM368 读取异步外部存储器接口 (AEMIF)。 我实际上还没有硬件,所以我正在 Leopardboard 368 上测试 vala 代码(如下)。 引导加载程序使用第一个 AEMIF 来读取 nand flash。 我的代码正在尝试使用第二个 AEMIF 来读取不在 Leopardboard 上但将在自定义硬件上的 SRAM。 我怀疑分段错误是由于我试图访问受保护的内存而引起的。 实际的自定义硬件将有几 M 需要读取的 SRAM,但我试图让这个测试代码读取读取 256 个字节。 如何修复由下面的测试代码引起的分段错误? 我需要向内核添加驱动程序吗? 如果可能的话,我宁愿不要弄乱内核。 是否有嵌入式 Linux 方法来配置或声明某些地址范围不受保护?

uint8 * source = (uint8 *)0x04000000; // AEMIF Data (CE1)
uint32 * pA2CR = (uint32 *)0x01D10014; // AEMIF 2 Config Reg (CS3 space)
const uint32 READ_SETUP = 1; // Read setup: EMIF clock cycles - 1
*pA2CR = (READ_SETUP << 13);
const size_t size = 256;
var dest = new uint8[size];
memset(dest, 0, size);
memcpy(dest, source, size);

【问题讨论】:

  • 段错误可能不是保护违规,而只是访问未映射到物理内存的用户内存。一个短期的解决方案是mmap() 一个文件来代替 SRAM。请注意,mmap() 可以提供一个虚拟地址以供使用或将返回一个虚拟地址。顺便说一句,如果您有“自定义硬件”,那么您将不得不“弄乱内核”。另见stackoverflow.com/questions/11500291/…
  • @sawdust 定制硬件几乎与 Leopoardboard 相同,这款 SRAM IF 可能是唯一的出发点。如果我必须更改内核,我会的。
  • Vala 方面的一些小注释:您不需要 memset(Vala 将为您将新缓冲区初始化为 0)。此外,像unowned uint8[] source = (uint8[]) 0x04000000; 这样的操作可能更容易,然后您可以使用数组切片来获取您想要的数据(例如,var dest = source[0:256];)。你真的几乎不需要在 Vala 中使用原始指针,尽管一些绑定(特别是 libxml2 和 posix)会诱使你这样做。
  • 那么这个地址存在于设备上吗?在基于 Linux 的系统上,每当我需要访问物理地址时,我都会使用 devmem2。这可以帮助您检查您是否可以访问该地址并编写类似的代码。 (你可以在这里找到它的副本:elinux.org/images/a/aa/Devmem2.c
  • Linux 内核不允许用户进程随意更改您想要的任何物理内存位置。您要么需要编写设备驱动程序,要么需要在设备的 I/O 范围内编写内存映射(如果您的内核支持)。但后者是有问题的,因为没有好的方法来控制对 I/O 区域的访问。因此,您可能会与正在发生的其他事情发生冲突并导致各种问题。您真的应该从内核中执行此操作。

标签: kernel arm embedded-linux vala mmu


【解决方案1】:

我不熟悉 DM386,但我曾经在 DM6446 上工作过。在 DM6446 中,但我希望在 DM368 上也一样,重新映射物理地址。

我不知道您的情况,但我认为您可以使用 miscdevice 编写驱动程序,并为您的用户空间程序提供读写操作支持。

在我的内核模块中,我使用IO_ADDRESS 宏来进行重新映射和访问寄存器。举个例子:

#define REG_PINMUX1     (*((volatile unsigned long *) (IO_ADDRESS(PINMUX1))))

然后在代码中我有类似的命令

REG_PINMUX0 &= ~(0x01000000);

所以我认为你遇到了段错误,因为你有一个错误的指针。并且尝试在没有内核模块的情况下从用户空间程序访问硬件寄存器并不是一个好的策略。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-21
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 2019-06-20
    • 2015-07-15
    相关资源
    最近更新 更多