DMA映射可参考:https://www.cnblogs.com/lethe1203/p/18092749
reserved_memory方式
1、定义保留内存的节点,由设备节点使用test_device_reserved: pmu_noc@0xe8000000 { compatible = "shared-dma-pool"; reg = <0x0 0xe8000000 0x0 0x800000>; reusable; }; &test_device { status = "okay"; memory-region = <&test_device_reserved>; };2、驱动probe中初始化reserved_mem,即提取memory-region信息绑定设备
ret = of_reserved_mem_device_init(&pdev->dev); 或 struct device_node *np = pdev->dev.of_node; ret = of_reserved_mem_device_init_by_idx(&pdev->dev, np, 0);
3、驱动中申请设备内存使用
dma_set_mask(&dev->dev, DMA_BIT_MASK(64)); // 可以访问64bit buf->virt = NULL; // 申请成功后得到的虚拟地址 buf->phys = 0; // 成功后phys值为设备树填写的物理地址 buf->size = size; // 要申请的长度 buf->dev = dev; buf->virt = dma_alloc_coherent(dev, buf->size, &buf->phys, GFP_KERNEL); ... ... dma_free_coherent(buf->dev, buf->size, buf->virt, buf->phys);
SMMU方式
使用smmu方式需要硬件上多一个TBU 例如:GPU需要一致性映射一块内存,不使用预留内存方式的话,就需要给GPU一块专属的TBU 此时需要协同smmu工程师协同调试。此时直接使用:dma_set_mask(dev, DMA_BIT_MASK(64)); virt = dma_alloc_coherent(dev, size, phys, GFP_KERNEL); ... ... dma_free_coherent(buf->dev, buf->size, buf->virt, buf->phys);得到的phys便是kernel看到的地址,virt表示GPU设备看到的地址 标签:DMA,phys,映射,dma,virt,dev,一致性,buf,size From: https://www.cnblogs.com/lethe1203/p/18092762