微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Cyclone V:Cortex A9 dma_alloc_coherent() 内部错误

如何解决Cyclone V:Cortex A9 dma_alloc_coherent() 内部错误

我正在尝试在 Linux 内核中的 CycloneV ARM9 上分配一些内存。

这是驱动中的代码

typedef struct tx_dma_buf {
    volatile phys_addr_t phys_addr;
    volatile unsigned int *virt_addr;
    volatile unsigned int *dma_regs;
    dma_addr_t *dma_handle;
    struct device *dev;
} buf_t;

typedef struct bufs
{
    buf_t *tx_buf;
    buf_t *rx_buf;
    struct cdev cdev;
    struct class *class;
    dev_t dev_node;
} buffers_t;

buf_t *tx_buf;
buf_t *rx_buf;
buffers_t *buf;
static int __init my_init(void)
{
    int err;

    printk(KERN_INFO,"my_init\n");
    buf = (buffers_t*)kmalloc(sizeof(buffers_t*),GFP_KERNEL);
    tx_buf = (buf_t *) kmalloc(sizeof(buf_t),GFP_KERNEL);
    tx_buf->dev = (struct device*)kmalloc(sizeof(struct device),GFP_KERNEL);
    tx_buf->virt_addr = dma_alloc_coherent(tx_buf->dev,BUFFER_SIZE,tx_buf->dma_handle,GFP_KERNEL);

    rx_buf = (buf_t *) kmalloc(sizeof(buf_t),GFP_KERNEL);
    rx_buf->dev = (struct device*)kmalloc(sizeof(struct device),GFP_KERNEL);
    rx_buf->phys_addr = dma_alloc_coherent(rx_buf->dev,rx_buf->dma_handle,GFP_KERNEL);

    buf->tx_buf = tx_buf;
    buf->rx_buf = rx_buf;

然后在加载模块时的 dmesg

[  138.309547] buff_alloc: loading out-of-tree module taints kernel.
[  138.316499] ------------[ cut here ]------------
[  138.321165] WARNING: cpu: 0 PID: 344 at kernel/dma/mapping.c:303 dma_alloc_attrs+0x114/0x124
[  138.329624] Modules linked in: buff_alloc(O+)
[  138.333979] cpu: 0 PID: 344 Comm: insmod Tainted: G           O      5.4.44-05622-gcda983e75c17 #3
[  138.342896] Hardware name: Altera SOCFPGA
[  138.346889] Backtrace:
[  138.349340] [<c010d5a0>] (dump_backtrace) from [<c010d8b8>] (show_stack+0x20/0x24)
...

[  138.539173] 8<--- cut here ---
[  138.542223] Unable to handle kernel paging request at virtual address 6e69622f
[  138.549442] pgd = 954810e3
[  138.552142] [6e69622f] *pgd=00000000
[  138.555731] Internal error: Oops: 5 [#1] SMP ARM
[  138.560335] Modules linked in: buff_alloc(O+)
[  138.564683] cpu: 0 PID: 344 Comm: insmod Tainted: G        W  O      5.4.44-05622-gcda983e75c17 #3
[  138.573598] Hardware name: Altera SOCFPGA
[  138.577598] PC is at string_nocheck+0x28/0x90
[  138.581938] LR is at 0xffffffff
[  138.585065] pc : [<c08ad3d4>]    lr : [<ffffffff>]    psr: a00f0013
...

我认为驱动程序中的所有内容都已分配,因此 dma_alloc_coherent 没有收到不应该接收的 NULL。我能够让 kmalloc 工作,但是在使用 kmalloc 时,我认为操作系统和与 SDRAM 交互的固件之间存在缓存一致性问题。如果代码有明显的问题,我不会看到它,但如果是调用操作系统(内核中的某些东西)的更深层次的问题,我将需要帮助来诊断问题。

更新

我尝试将相同的调用放入探测函数并使用 platform_device dev。我查看了 Xilinx 驱动程序示例,似乎就是这样做的。 https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842418/Linux+DMA+From+User+Space?preview=/18842418/18848721/dma-proxy.zip

它似乎以同样的方式失败。这是我的新片段

static int dmabuffer_probe(struct platform_device *pdev)
{

    printk(KERN_INFO "dmabuffer module initialized\n");

        buf = (buf_t*)kmalloc(sizeof(buf_t*),GFP_KERNEL);
        buf->dev = &pdev->dev;
        buf->virt_addr = dma_alloc_coherent(buf->dev,buf->dma_handle,GFP_KERNEL);

    return 0;
} 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。