3

我是编写设备驱动程序的新手。

我想为 ARM 平台上的外围设备编写设备驱动程序。

第一个问题:在 ARM 平台上为外设编写设备驱动程序与在 Linux 中的 x86 上编写设备驱动程序有什么不同?

第二个问题:我检查了 /proc/iomem 文件以查看处理器的当前地址映射。但是,并非所有外围设备(包括我要访问的外围设备)都不存在于该文件中。如何包含外围设备的地址范围?

第三个问题:设备树在编写设备驱动程序中的重要性是什么?

4

3 回答 3

5

如果驱动程序不存在于内核源代码树中,并且设备是在设备地址空间中映射的内存,则必须在某处声明设备资源(地址区域、中断行)。在旧版本的内核中,这是板文件的职责,但现在它已移至设备树。

所以 x86 架构的主要区别不是你如何编写驱动程序,而是你如何匹配设备和驱动程序。在 x86 上,您有例如 pci 驱动程序和可发现的 pci 设备。在 ARM 上,通常没有这样的自描述硬件,为了模拟整个设备/驱动程序的舞蹈,创建了平台总线。

所以ARM上典型的设备驱动就是平台驱动,关联的设备就是平台设备。当前内核中的以太网 mac 驱动程序示例在这里

在上面链接的驱动程序中,驱动程序代码不知道设备所在的位置。此信息在探测时使用platform_device对象传递给驱动程序。平台设备可以这样描述(来源):

static struct platform_device at91sam9260_eth_device = {
        .name           = "macb",
        .id             = -1,
        .dev            = {
                                .dma_mask               = &eth_dmamask,
                                .coherent_dma_mask      = DMA_BIT_MASK(32),
                                .platform_data          = &eth_data,
        },
        .resource       = eth_resources,
        .num_resources  = ARRAY_SIZE(eth_resources),
};

平台设备可以从这里显示的 c 代码创建,也可以在设备树中描述。在这两种情况下,在驱动程序探测到设备之前,您都不会在 proc/iomem 中看到任何内容。这与大多数设备是 PCI 设备的 x86 世界形成鲜明对比。

这是相同的设备,但在设备树文件中进行了描述:

               macb0: ethernet@fffc4000 {
                        compatible = "cdns,at32ap7000-macb", "cdns,macb";
                        reg = <0xfffc4000 0x100>;
                        interrupts = <21 IRQ_TYPE_LEVEL_HIGH 3>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&pinctrl_macb_rmii>;
                        status = "disabled";
                };
于 2014-04-23T09:24:17.893 回答
4

1.只要外设接口与SoC类似(即在两个平台上使用相同的硬件接口),相同的驱动程序可以在x86和ARM上使用。这是开发独立于 Linux 内核核心的模块化驱动程序的优势。


2.如果当前地址映射()中不存在您的特定外围设备,/proc/iomem则可能意味着以下两种可能性之一:

  • 设备驱动程序尚未加载。
  • 设备使用其他形式的寻址(不是内存映射 I/O)

有关外围设备的任何其他信息?它是如何连接到 SoC 的?


3. Linux 内核中的设备树用于描述众多硬件(片上和外围设备)、它们的互连性以及适用于它们在特定平台/板上进行正确配置和初始化的基本参数写入设备树。

本质上,它执行与当前 Linux 内核中的“板文件”相同的功能。它还减少了 bootargs 对初始配置的依赖,因为它可以在设备树中提供。有关设备树的更多信息。

于 2013-08-05T02:20:49.300 回答
1

要将有关设备地址范围的信息导出到/proc用户空间接口,您必须在驱动程序中将此区域注册到内核:

request_mem_region()
于 2018-12-14T16:15:06.617 回答