在Linux中编写设备驱动程序

yil*_*lah 3 linux arm linux-device-driver linux-kernel device-tree

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

我想在ARM平台上为外设编写设备驱动程序.

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

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

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

sho*_*nex 5

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

因此,与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),
};
Run Code Online (Sandbox Code Playgroud)

可以从此处所示的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";
                };
Run Code Online (Sandbox Code Playgroud)