0

我是 Linux 驱动程序开发的新手。我想DMA read在指定的目标地址触发一个操作,但我没有关于如何做的基本概念。我应该为我的声卡写一个新的驱动程序吗?或者只是调用当前声卡驱动程序提供的一些 API(如果有的话)?

我可以想象我想要的看起来像这样(来自 LDD3 Ch15),

int dad_transfer(struct dad_dev *dev, int write, void *buffer, 
                 size_t count)
{
    dma_addr_t bus_addr;

    /* Map the buffer for DMA */
    dev->dma_dir = (write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
    dev->dma_size = count;
    bus_addr = dma_map_single(&dev->pci_dev->dev, buffer, count, 
                              dev->dma_dir);
    dev->dma_addr = bus_addr;

    /* Set up the device */

    writeb(dev->registers.command, DAD_CMD_DISABLEDMA);
    writeb(dev->registers.command, write ? DAD_CMD_WR : DAD_CMD_RD);
    writel(dev->registers.addr, cpu_to_le32(bus_addr));
    writel(dev->registers.len, cpu_to_le32(count));

    /* Start the operation */
    writeb(dev->registers.command, DAD_CMD_ENABLEDMA);
    return 0;
}

但是这应该是一个用户空间程序还是一个模块?我在哪里可以获取更多特定于设备的详细信息,以便了解registers应该编写哪些以及如何编写?

4

1 回答 1

1

你有几个问题埋在这里,所以我会一次回答一个:

  1. 我应该编写一个新的驱动程序还是调用一些 API 函数调用?

如果现有驱动程序具有可从用户空间访问的此类功能,是的,您应该使用它们-它们将是最简单的选择。如果它们不存在,您将不得不编写驱动程序,因为您无法从用户空间直接访问内核的 D​​MA 引擎。你需要一个司机来帮助你。

  1. 这应该是用户空间程序还是模块?

它必须是一个模块,以便它可以访问低级内核功能。以您包含的代码为例,您不能从用户空间调用“dma_map_single”或访问 PCI 设备的设备结构。您需要在内核空间中执行此操作,这需要驱动程序模块或静态内核驱动程序。

  1. 我在哪里可以获得更多特定于设备的详细信息?

(我假设您的意思是 Grep。)您必须获取您要访问的设备的程序员指南。普通用户手册没有您需要的详细程度(寄存器地址、位模式等),因此您可能必须联系制造商以获取驱动程序编写者指南。您还可以在内核源代码中找到一些示例。检查http://lxr.free-electrons.com/以获取整个内核源代码的可搜索的最新列表。如果您查看 /drivers/,您可能会找到一些示例来帮助您入门。

于 2014-09-23T21:36:51.353 回答