问题描述
我正在尝试在 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 (将#修改为@)