设备树解析

1.概要

2.内容

// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
 */

#include <dt-bindings/pinctrl/rockchip.h>
#include "rockchip-pinconf.dtsi"

/*
 * This file is auto generated by pin2dts tool, please keep these code
 * by adding changes at end of this file.
 */
&pinctrl {
	clk32k {
		/omit-if-no-ref/
		clk32k_out1: clk32k-out1 {
			rockchip,pins =
				/* clk32k_out1 */
				<2 RK_PC5 1 &pcfg_pull_none>;
		};

	};

	eth0 {
		/omit-if-no-ref/
		eth0_pins: eth0-pins {
			rockchip,pins =
				/* eth0_refclko_25m */
				<2 RK_PC3 1 &pcfg_pull_none>;
		};

	};

	fspi {
		/omit-if-no-ref/
		fspim1_pins: fspim1-pins {
			rockchip,pins =
				/* fspi_clk_m1 */
				<2 RK_PB3 3 &pcfg_pull_up_drv_level_2>,
				/* fspi_cs0n_m1 */
				<2 RK_PB4 3 &pcfg_pull_up_drv_level_2>,
				/* fspi_d0_m1 */
				<2 RK_PA6 3 &pcfg_pull_up_drv_level_2>,
				/* fspi_d1_m1 */
				<2 RK_PA7 3 &pcfg_pull_up_drv_level_2>,
				/* fspi_d2_m1 */
				<2 RK_PB0 3 &pcfg_pull_up_drv_level_2>,
				/* fspi_d3_m1 */
				<2 RK_PB1 3 &pcfg_pull_up_drv_level_2>;
		};

		/omit-if-no-ref/
		fspim1_cs1: fspim1-cs1 {
			rockchip,pins =
				/* fspi_cs1n_m1 */
				<2 RK_PB5 3 &pcfg_pull_up_drv_level_2>;
		};
	};

	gmac0 {
		/omit-if-no-ref/
		gmac0_miim: gmac0-miim {
			rockchip,pins =
				/* gmac0_mdc */
				<4 RK_PC4 1 &pcfg_pull_none>,
				/* gmac0_mdio */
				<4 RK_PC5 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		gmac0_clkinout: gmac0-clkinout {
			rockchip,pins =
				/* gmac0_mclkinout */
				<4 RK_PC3 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		gmac0_rx_bus2: gmac0-rx-bus2 {
			rockchip,pins =
				/* gmac0_rxd0 */
				<2 RK_PC1 1 &pcfg_pull_none>,
				/* gmac0_rxd1 */
				<2 RK_PC2 1 &pcfg_pull_none>,
				/* gmac0_rxdv_crs */
				<4 RK_PC2 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		gmac0_tx_bus2: gmac0-tx-bus2 {
			rockchip,pins =
				/* gmac0_txd0 */
				<2 RK_PB6 1 &pcfg_pull_none>,
				/* gmac0_txd1 */
				<2 RK_PB7 1 &pcfg_pull_none>,
				/* gmac0_txen */
				<2 RK_PC0 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		gmac0_rgmii_clk: gmac0-rgmii-clk {
			rockchip,pins =
				/* gmac0_rxclk */
				<2 RK_PB0 1 &pcfg_pull_none>,
				/* gmac0_txclk */
				<2 RK_PB3 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		gmac0_rgmii_bus: gmac0-rgmii-bus {
			rockchip,pins =
				/* gmac0_rxd2 */
				<2 RK_PA6 1 &pcfg_pull_none>,
				/* gmac0_rxd3 */
				<2 RK_PA7 1 &pcfg_pull_none>,
				/* gmac0_txd2 */
				<2 RK_PB1 1 &pcfg_pull_none>,
				/* gmac0_txd3 */
				<2 RK_PB2 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		gmac0_ppsclk: gmac0-ppsclk {
			rockchip,pins =
				/* gmac0_ppsclk */
				<2 RK_PC4 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		gmac0_ppstring: gmac0-ppstring {
			rockchip,pins =
				/* gmac0_ppstring */
				<2 RK_PB5 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		gmac0_ptp_refclk: gmac0-ptp-refclk {
			rockchip,pins =
				/* gmac0_ptp_refclk */
				<2 RK_PB4 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		gmac0_txer: gmac0-txer {
			rockchip,pins =
				/* gmac0_txer */
				<4 RK_PC6 1 &pcfg_pull_none>;
		};

	};

	hdmi {
		/omit-if-no-ref/
		hdmim0_tx1_cec: hdmim0-tx1-cec {
			rockchip,pins =
				/* hdmim0_tx1_cec */
				<2 RK_PC4 4 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		hdmim0_tx1_scl: hdmim0-tx1-scl {
			rockchip,pins =
				/* hdmim0_tx1_scl */
				<2 RK_PB5 4 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		hdmim0_tx1_sda: hdmim0-tx1-sda {
			rockchip,pins =
				/* hdmim0_tx1_sda */
				<2 RK_PB4 4 &pcfg_pull_none>;
		};
	};

	i2c0 {
		/omit-if-no-ref/
		i2c0m1_xfer: i2c0m1-xfer {
			rockchip,pins =
				/* i2c0_scl_m1 */
				<4 RK_PC5 9 &pcfg_pull_none_smt>,
				/* i2c0_sda_m1 */
				<4 RK_PC6 9 &pcfg_pull_none_smt>;
		};
	};

	i2c2 {
		/omit-if-no-ref/
		i2c2m1_xfer: i2c2m1-xfer {
			rockchip,pins =
				/* i2c2_scl_m1 */
				<2 RK_PC1 9 &pcfg_pull_none_smt>,
				/* i2c2_sda_m1 */
				<2 RK_PC0 9 &pcfg_pull_none_smt>;
		};
	};

	i2c3 {
		/omit-if-no-ref/
		i2c3m3_xfer: i2c3m3-xfer {
			rockchip,pins =
				/* i2c3_scl_m3 */
				<2 RK_PB2 9 &pcfg_pull_none_smt>,
				/* i2c3_sda_m3 */
				<2 RK_PB3 9 &pcfg_pull_none_smt>;
		};
	};

	i2c4 {
		/omit-if-no-ref/
		i2c4m1_xfer: i2c4m1-xfer {
			rockchip,pins =
				/* i2c4_scl_m1 */
				<2 RK_PB5 9 &pcfg_pull_none_smt>,
				/* i2c4_sda_m1 */
				<2 RK_PB4 9 &pcfg_pull_none_smt>;
		};
	};

	i2c5 {
		/omit-if-no-ref/
		i2c5m4_xfer: i2c5m4-xfer {
			rockchip,pins =
				/* i2c5_scl_m4 */
				<2 RK_PB6 9 &pcfg_pull_none_smt>,
				/* i2c5_sda_m4 */
				<2 RK_PB7 9 &pcfg_pull_none_smt>;
		};
	};

	i2c6 {
		/omit-if-no-ref/
		i2c6m2_xfer: i2c6m2-xfer {
			rockchip,pins =
				/* i2c6_scl_m2 */
				<2 RK_PC3 9 &pcfg_pull_none_smt>,
				/* i2c6_sda_m2 */
				<2 RK_PC2 9 &pcfg_pull_none_smt>;
		};
	};

	i2c7 {
		/omit-if-no-ref/
		i2c7m1_xfer: i2c7m1-xfer {
			rockchip,pins =
				/* i2c7_scl_m1 */
				<4 RK_PC3 9 &pcfg_pull_none_smt>,
				/* i2c7_sda_m1 */
				<4 RK_PC4 9 &pcfg_pull_none_smt>;
		};
	};

	i2c8 {
		/omit-if-no-ref/
		i2c8m1_xfer: i2c8m1-xfer {
			rockchip,pins =
				/* i2c8_scl_m1 */
				<2 RK_PB0 9 &pcfg_pull_none_smt>,
				/* i2c8_sda_m1 */
				<2 RK_PB1 9 &pcfg_pull_none_smt>;
		};
	};

	i2s2 {
		/omit-if-no-ref/
		i2s2m0_idle: i2s2m0-idle {
			rockchip,pins =
				/* i2s2m0_lrck_gpio */
				<2 RK_PC0 0 &pcfg_pull_none>,
				/* i2s2m0_sclk_gpio */
				<2 RK_PB7 0 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		i2s2m0_lrck: i2s2m0-lrck {
			rockchip,pins =
				/* i2s2m0_lrck */
				<2 RK_PC0 2 &pcfg_pull_none_smt>;
		};

		/omit-if-no-ref/
		i2s2m0_mclk: i2s2m0-mclk {
			rockchip,pins =
				/* i2s2m0_mclk */
				<2 RK_PB6 2 &pcfg_pull_none_smt>;
		};

		/omit-if-no-ref/
		i2s2m0_sclk: i2s2m0-sclk {
			rockchip,pins =
				/* i2s2m0_sclk */
				<2 RK_PB7 2 &pcfg_pull_none_smt>;
		};

		/omit-if-no-ref/
		i2s2m0_sdi: i2s2m0-sdi {
			rockchip,pins =
				/* i2s2m0_sdi */
				<2 RK_PC3 2 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		i2s2m0_sdo: i2s2m0-sdo {
			rockchip,pins =
				/* i2s2m0_sdo */
				<4 RK_PC3 2 &pcfg_pull_none>;
		};
	};

	pwm2 {
		/omit-if-no-ref/
		pwm2m2_pins: pwm2m2-pins {
			rockchip,pins =
				/* pwm2_m2 */
				<4 RK_PC2 11 &pcfg_pull_none>;
		};
	};

	pwm4 {
		/omit-if-no-ref/
		pwm4m1_pins: pwm4m1-pins {
			rockchip,pins =
				/* pwm4_m1 */
				<4 RK_PC3 11 &pcfg_pull_none>;
		};
	};

	pwm5 {
		/omit-if-no-ref/
		pwm5m2_pins: pwm5m2-pins {
			rockchip,pins =
				/* pwm5_m2 */
				<4 RK_PC4 11 &pcfg_pull_none>;
		};
	};

	pwm6 {
		/omit-if-no-ref/
		pwm6m2_pins: pwm6m2-pins {
			rockchip,pins =
				/* pwm6_m2 */
				<4 RK_PC5 11 &pcfg_pull_none>;
		};
	};

	pwm7 {
		/omit-if-no-ref/
		pwm7m3_pins: pwm7m3-pins {
			rockchip,pins =
				/* pwm7_ir_m3 */
				<4 RK_PC6 11 &pcfg_pull_none>;
		};
	};

	sdio {
		/omit-if-no-ref/
		sdiom0_pins: sdiom0-pins {
			rockchip,pins =
				/* sdio_clk_m0 */
				<2 RK_PB3 2 &pcfg_pull_none>,
				/* sdio_cmd_m0 */
				<2 RK_PB2 2 &pcfg_pull_up>,
				/* sdio_d0_m0 */
				<2 RK_PA6 2 &pcfg_pull_up>,
				/* sdio_d1_m0 */
				<2 RK_PA7 2 &pcfg_pull_up>,
				/* sdio_d2_m0 */
				<2 RK_PB0 2 &pcfg_pull_up>,
				/* sdio_d3_m0 */
				<2 RK_PB1 2 &pcfg_pull_up>;
		};
	};

	spi1 {
		/omit-if-no-ref/
		spi1m0_pins: spi1m0-pins {
			rockchip,pins =
				/* spi1_clk_m0 */
				<2 RK_PC0 8 &pcfg_pull_up_drv_level_1>,
				/* spi1_miso_m0 */
				<2 RK_PC1 8 &pcfg_pull_up_drv_level_1>,
				/* spi1_mosi_m0 */
				<2 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
		};

		/omit-if-no-ref/
		spi1m0_cs0: spi1m0-cs0 {
			rockchip,pins =
				/* spi1_cs0_m0 */
				<2 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
		};

		/omit-if-no-ref/
		spi1m0_cs1: spi1m0-cs1 {
			rockchip,pins =
				/* spi1_cs1_m0 */
				<2 RK_PC4 8 &pcfg_pull_up_drv_level_1>;
		};
	};

	spi3 {
		/omit-if-no-ref/
		spi3m0_pins: spi3m0-pins {
			rockchip,pins =
				/* spi3_clk_m0 */
				<4 RK_PC6 8 &pcfg_pull_up_drv_level_1>,
				/* spi3_miso_m0 */
				<4 RK_PC4 8 &pcfg_pull_up_drv_level_1>,
				/* spi3_mosi_m0 */
				<4 RK_PC5 8 &pcfg_pull_up_drv_level_1>;
		};

		/omit-if-no-ref/
		spi3m0_cs0: spi3m0-cs0 {
			rockchip,pins =
				/* spi3_cs0_m0 */
				<4 RK_PC2 8 &pcfg_pull_up_drv_level_1>;
		};

		/omit-if-no-ref/
		spi3m0_cs1: spi3m0-cs1 {
			rockchip,pins =
				/* spi3_cs1_m0 */
				<4 RK_PC3 8 &pcfg_pull_up_drv_level_1>;
		};
	};

	uart1 {
		/omit-if-no-ref/
		uart1m0_xfer: uart1m0-xfer {
			rockchip,pins =
				/* uart1_rx_m0 */
				<2 RK_PB6 10 &pcfg_pull_up>,
				/* uart1_tx_m0 */
				<2 RK_PB7 10 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart1m0_ctsn: uart1m0-ctsn {
			rockchip,pins =
				/* uart1m0_ctsn */
				<2 RK_PC1 10 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		uart1m0_rtsn: uart1m0-rtsn {
			rockchip,pins =
				/* uart1m0_rtsn */
				<2 RK_PC0 10 &pcfg_pull_none>;
		};
	};

	uart6 {
		/omit-if-no-ref/
		uart6m0_xfer: uart6m0-xfer {
			rockchip,pins =
				/* uart6_rx_m0 */
				<2 RK_PA6 10 &pcfg_pull_up>,
				/* uart6_tx_m0 */
				<2 RK_PA7 10 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart6m0_ctsn: uart6m0-ctsn {
			rockchip,pins =
				/* uart6m0_ctsn */
				<2 RK_PB1 10 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		uart6m0_rtsn: uart6m0-rtsn {
			rockchip,pins =
				/* uart6m0_rtsn */
				<2 RK_PB0 10 &pcfg_pull_none>;
		};
	};

	uart7 {
		/omit-if-no-ref/
		uart7m0_xfer: uart7m0-xfer {
			rockchip,pins =
				/* uart7_rx_m0 */
				<2 RK_PB4 10 &pcfg_pull_up>,
				/* uart7_tx_m0 */
				<2 RK_PB5 10 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart7m0_ctsn: uart7m0-ctsn {
			rockchip,pins =
				/* uart7m0_ctsn */
				<4 RK_PC6 10 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		uart7m0_rtsn: uart7m0-rtsn {
			rockchip,pins =
				/* uart7m0_rtsn */
				<4 RK_PC2 10 &pcfg_pull_none>;
		};
	};

	uart9 {
		/omit-if-no-ref/
		uart9m0_xfer: uart9m0-xfer {
			rockchip,pins =
				/* uart9_rx_m0 */
				<2 RK_PC4 10 &pcfg_pull_up>,
				/* uart9_tx_m0 */
				<2 RK_PC2 10 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart9m0_ctsn: uart9m0-ctsn {
			rockchip,pins =
				/* uart9m0_ctsn */
				<4 RK_PC5 10 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		uart9m0_rtsn: uart9m0-rtsn {
			rockchip,pins =
				/* uart9m0_rtsn */
				<4 RK_PC4 10 &pcfg_pull_none>;
		};
	};
};

这段代码是用于配置Rockchip(瑞芯微)平台上各个外设的引脚和引脚配置的Device Tree片段。Device Tree是一种描述硬件的数据结构,用于Linux内核,它允许内核在启动时动态地发现和配置硬件。以下是对代码中主要部分的解释:

  1. 引脚配置(rockchip,pins
    • 每个外设的引脚配置都通过一个数组来定义,数组中的每个元素代表一个引脚的配置。
    • 每个引脚配置由四个值组成:引脚号(例如<2 RK_PC5 1 &pcfg_pull_none>中的2),引脚功能(RK_PC5),驱动强度(1),和引脚配置(&pcfg_pull_none)。
  2. 引脚功能(例如RK_PC5
    • 这些值定义了引脚的具体功能。例如,RK_PC5可能代表GPIO引脚C5的某种特定功能(如SPI的MISO信号)。
  3. 引脚配置(例如&pcfg_pull_none
    • 这些值配置了引脚的电气特性,如是否启用上拉或下拉电阻(&pcfg_pull_up表示启用上拉电阻,&pcfg_pull_none表示不启用)。
  4. 外设配置
    • 代码为多个外设配置了引脚,包括时钟(clk32k)、以太网(eth0)、Flash SPI(fspi)、GPIO控制器(gmac0)、HDMI(hdmi)、I2C控制器(i2c0i2c8)、I2S(i2s2)、PWM(pwm2pwm7)、SDIO(sdio)、SPI控制器(spi1spi3)、UART(uart1uart6uart7uart9)等。
    • 每个外设的配置都详细指定了所需的引脚、引脚功能、驱动强度和电气配置。
  5. 条件编译(/omit-if-no-ref/
    • 这些注释用于指示如果相应的外设没有在Device Tree中被引用,则应该省略这些配置。这是一种优化,可以减少Device Tree的大小并提高加载速度。
  6. 自动生成注释
    • 文件开头的注释指出这部分代码是自动生成的,建议在代码末尾添加更改,以保持代码的可维护性。

总的来说,这段代码通过详细指定每个外设所需的引脚和配置,使得Linux内核能够在启动时正确初始化并控制这些硬件外设。

<think>好的,用户之前问过设备树每一层是否都会解析成device,现在又问设备树解析过程。我需要详细解释解析过程,但要注意和之前的回答有所区分,不能重复太多内容。用户可能是嵌入式开发者或者内核新手,想深入理解设备树的工作机制。 首先,应该从设备树的基础结构开始,但之前已经讲过树状结构,所以这里可以略过,直接进入解析步骤。要分阶段说明,比如启动阶段、展开、匹配驱动、设备创建等。需要强调关键点,比如compatible属性的作用,节点如何转化为设备,以及不同总线的作用。 用户可能想知道解析过程中的细节,比如OF组件的角色,节点与设备的绑定关系,以及实际例子帮助理解。还要注意特殊处理的情况,比如状态属性和动态设备。最后可以加入调试方法,方便用户自己验证。需要确保结构清晰,步骤明确,避免技术术语过于复杂,同时结合代码示例和实际路径,增强实用性。检查是否有遗漏的部分,比如设备树二进制转换、资源分配等,确保覆盖整个流程。</think>设备树(Device Tree)的解析是Linux内核启动过程中的关键环节,其核心目标是将硬件描述转换为内核可识别的设备结构。以下是**分步骤的解析过程详解**: --- ### 一、设备树数据流 1. **原始文件**:`.dts`(文本描述) → **编译** → `.dtb`(二进制) 2. **启动加载**:Bootloader(如U-Boot)将`.dtb`加载到内存,并传递地址给内核 --- ### 二、内核解析阶段 #### 阶段1:**扁平化展开(Flattening)** - 将树形结构转换为线性`device_node`链表 - **关键操作**:解析节点、属性、父子关系,生成`struct device_node` - **存储位置**:`/proc/device-tree`目录映射原始结构 #### 阶段2:**设备绑定(Binding)** - **核心机制**:通过`compatible`属性匹配驱动 ```dts // 设备树节点示例 uart0: serial@ff000000 { compatible = "ns16550a", "snps,dw-apb-uart"; // 驱动匹配优先级 reg = <0xff000000 0x100>; interrupts = <10>; }; ``` - **匹配规则**: - 按`compatible`列表顺序尝试匹配`of_device_id`表 - 匹配成功则调用驱动`probe`函数 #### 阶段3:**设备实例化** - 从`device_node`生成`struct platform_device`(或其他总线设备) ```c // 内核底层简化逻辑 for_each_child_of_node(root, child) { if (of_device_is_available(child)) { // 检查status属性 platform_device_register(child); // 创建设备 } } ``` - **资源分配**: - 自动解析`reg`属性 → 转换为`struct resource` - 解析`interrupts` → 映射为IRQ编号 --- ### 三、关键组件交互 | 组件 | 功能 | |---------------------|----------------------------------------------------------------------| | **OF(Open Firmware)核心** | 提供`of_*`系列API(如`of_get_property()`)解析节点 | | **平台总线(platform bus)** | 管理`platform_device`与`platform_driver`的匹配 | | **特定总线(I2C/SPI等)** | 总线控制器驱动解析子节点,生成对应总线设备(如`i2c_client`) | --- ### 四、特殊场景处理 1. **别名(aliases)解析** ```dts aliases { ethernet0 = &eth0; // 允许通过别名快速访问设备 }; ``` - 生成全局别名表,支持通过`of_alias_get_id()`获取设备ID 2. **覆盖机制(Overlay)** - 动态加载设备树片段(常用于热插拔设备配置) 3. **延迟初始化** - 某些设备依赖父设备先初始化(如GPIO控制器需在总线设备之后创建) --- ### 五、调试验证方法 1. **查看原始结构** ```bash dtc -I fs /proc/device-tree # 反编译内存中的设备树 ``` 2. **跟踪设备创建** ```bash ls /sys/devices/platform/ # 查看已生成的平台设备 dmesg | grep of_ # 观察OF解析日志 ``` --- ### 六、典型解析流程图解 ``` Bootloader加载dtb → 内核解压dtb → 构建device_node树 → 总线驱动扫描子节点 → 生成platform_device/i2c_client等 → 触发驱动probe ``` **关键结论**: 设备树节点**不会全部转换为设备**,只有满足以下条件的节点才会生成设备: 1. 包含有效`compatible`属性 2. 未被`status = "disabled"`标记 3. 父总线支持设备创建 4. 有对应驱动存在
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值