https://www.kernel.org/doc/Documentation/devicetree/usage-model.txt
The “ Open Firmware Device Tree” , or simply Device Tree (DT), is a data
structure and language for describing hardware. More specifically, it is a
description of hardware that is readable by an operating system
so that the operating system doesn’t need to hard code details of the
machine.
提供一种语言来解耦硬件配置信息
- 最早: 2005 PowerPC Linux
- 现在: arm, microblaze, mips, powerpc, sparc, x86 Openrisc, c6x
X86: arch/x86/platform/ce4100 (intel凌动处理器)
设备端
使用设备树之前, 硬件的描述信息放置到一个个arch/xxx/mach-xxx/board-xxx.c的C文件中,例如下面的程序
static struct resource dm9000_resource1[] = {
{
.start = 0x20100000,
.end = 0x20100000 + 1,
.flags = IORESOURCE_MEM
…
.start = IRQ_PF15,
.end = IRQ_PF15,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE
}
};
static struct platform_device dm9000_device1 = {
.name = "dm9000",
.id = 0,
.num_resources = ARRAY_SIZE(dm9000_resource1),
.resource = dm9000_resource1,
};
static struct platform_device *ip0x_devices[] __initdata = {
&dm9000_device1,
&dm9000_device2,
};
static int __init ip0x_init(void)
{
platform_add_devices(ip0x_devices, ARRAY_SIZE(ip0x_devices));
}
由于硬件的信息使用代码描述 Linus 发邮件给 ARM 社区
ARM: F*cking pain in the ass
Gaah. Guys, this whole ARM thing is a
f*cking pain in the ass.
Linus, 2011,
http://lkml.org/lkml/2011/3/17/492
使用设备树之后, 硬件的描述信息,放置到一个个arch/xxx/boot/dts目录的.dtsi和.dts文件中 arch/powerpc/boot/dts 和 arch/arm/boot/dts
使用了设备树之后就可以很好的用 DTS 进行描述硬件资源,驱动可以在 c 里实现
驱动端
驱动从 DTS 读取硬件信息: drivers/xxx/
static int dm9000_probe(struct platform_device *pdev)
{
…
db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
…
}
static struct dm9000_plat_data *dm9000_parse_dt(struct device *dev)
{
...
if (of_find_property(np, "davicom,ext-phy", NULL))
pdata->flags |= DM9000_PLATF_EXT_PHY;
if (of_find_property(np, "davicom,no-eeprom", NULL))
pdata->flags |= DM9000_PLATF_NO_EEPROM;
mac_addr = of_get_mac_address(np);
...
}
static struct platform_driver dm9000_driver = {
.driver = {
.name = "dm9000",
.pm = &dm9000_drv_pm_ops