1. 设备树起源与作用:为什么需要设备树?

大家好,我是你们的嵌入式Linux驱动讲师。今天咱们聊聊设备树的起源。

说实话,我刚开始做嵌入式Linux那会儿,还没有设备树这东西。那时候的驱动开发,说白了就是跟板级文件死磕。你想想看,每换一个硬件平台,就得重新写一遍代码,那滋味可不好受。

从板级文件到设备树的演进

在Linux 2.6时代,内核里充斥着大量的板级文件。比如arch/arm/mach-xxx目录下,每个板子都有自己的c文件和头文件。这些文件里定义了内存地址、中断号、GPIO映射等等。

我印象特别深,有一次公司要支持三块不同的开发板,每块板子的UART地址都不一样。我不得不复制粘贴代码,然后手动修改每个地址。那段时间,我做梦都在改宏定义。

板级文件的痛点:

  • 代码冗余:每个板子都要写大量重复代码
  • 维护困难:改一个硬件参数,要重新编译整个内核
  • 碎片化严重:厂商各自为政,内核越来越臃肿
  • 二进制不兼容:同一个内核镜像无法在不同板子上运行

为什么会这样?因为硬件描述和驱动代码完全耦合在一起。说白了,就是把硬件信息硬编码到了C语言里。

举个例子,以前我们这样描述一个LED:

// 板级文件中的写法
static struct gpio_led my_leds[] = {
    {
        .name = "power_led",
        .gpio = 32,  // GPIO编号硬编码
        .active_low = 0,
    },
};

static struct gpio_led_platform_data led_data = {
    .leds = my_leds,
    .num_leds = 1,
};

你看,GPIO编号、极性这些信息都写死在代码里。换一块板子,GPIO变成33了,就得改代码重新编译。这效率,说实话太低了。

设备树的诞生

2005年左右,PowerPC架构率先引入了设备树(Device Tree)的概念。后来ARM社区也意识到这个问题,从Linux 3.x开始全面采用设备树。

设备树的核心思想很简单:把硬件描述从驱动代码中分离出来。硬件信息用文本文件描述,驱动代码只负责解析这些描述。

我个人习惯把设备树比作硬件的"身份证"。它告诉内核:我是谁、我在哪、我有哪些资源。至于怎么用这些资源,那是驱动代码的事。

同样的LED,用设备树描述就变成了这样:

// 设备树中的写法
leds {
    compatible = "gpio-leds";
    power_led {
        label = "power";
        gpios = &gpio1 32 GPIO_ACTIVE_LOW;
        default-state = "on";
    };
};

嗯,这里要注意:设备树文件(.dts)是文本文件,编译成二进制(.dtb)后由bootloader传递给内核。内核启动时解析这个二进制文件,动态构建硬件信息。

设备树在Linux内核中的角色

设备树到底扮演什么角色?我用一张图来说明:

设备树在Linux内核中的角色 硬件层(CPU、内存、外设、总线) 设备树(.dts → .dtb) Linux内核(解析设备树,注册平台设备) 设备驱动(匹配设备树节点,操作硬件)

从这张图你能看到,设备树处于硬件和内核之间的桥梁位置。它把硬件信息抽象成树形结构,内核启动时读取这个结构,然后动态创建设备。

设备树解决了哪些问题?

我在项目中遇到过这样一个场景:客户要求同一款芯片支持两种不同的LCD屏。以前的做法是编译两个内核镜像,一个支持屏A,一个支持屏B。有了设备树,只需要在设备树里改几行参数,同一个内核镜像就能适配两种屏。

避坑指南:我曾经因为设备树里一个逗号写成了分号,导致整个系统启动不起来。调试了整整一天才发现。设备树的语法检查很严格,一个标点符号都不能错。

设备树带来的好处,总结起来有几点:

  1. 硬件描述与驱动分离:改硬件参数不用改驱动代码
  2. 内核镜像通用化:同一个zImage可以在不同板子上运行
  3. 减少内核碎片:不再需要为每个板子维护单独的代码
  4. 启动参数灵活:bootloader可以动态修改设备树
  5. 社区统一标准:所有架构都采用相同的描述方式

说白了,设备树让嵌入式Linux开发从"手工作坊"进入了"标准化生产"时代。你想想看,以前每个板子都是独一无二的,现在大家用同一套语言描述硬件,这效率提升不是一星半点。

核心要点:设备树不是万能的,但它解决了嵌入式Linux开发中最头疼的问题——硬件描述与驱动代码的耦合。理解这一点,你就抓住了设备树的精髓。

好了,这一章我们聊了设备树的起源和它在内核中的角色。下一章我会带你深入设备树的语法细节,包括节点、属性、标签这些核心概念。到时候我会分享一些实际项目中的踩坑经验,保证让你少走弯路。

可可精品资料库