From 63bf7331b5fbc120a1068bcff8bc6b1ee117a4f5 Mon Sep 17 00:00:00 2001 From: iOSDevLog Date: Fri, 1 Jul 2022 22:42:09 +0800 Subject: [PATCH] add article: Device Tree --- articles/20220701-linux-dts-1.md | 243 +++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100755 articles/20220701-linux-dts-1.md diff --git a/articles/20220701-linux-dts-1.md b/articles/20220701-linux-dts-1.md new file mode 100755 index 0000000..4bcf396 --- /dev/null +++ b/articles/20220701-linux-dts-1.md @@ -0,0 +1,243 @@ +> Author: iosdevlog
+> Date: 2022/07/01
+> Project: [RISC-V Linux 内核剖析](https://gitee.com/tinylab/riscv-linux) + +# Device Tree 初探 + +## Device Tree 简介 + +Linus Torvalds 在 2011 年 3 月 17 日的 ARM Linux 邮件列表宣称 "this whole ARM thing is a fucking pain in the ass"。 + +引发 ARM Linux 社区的地震,随后 ARM 社区进行了一系列的重大修正。 + +在过去的 ARM Linux 中,`arch/arm/plat-xxx` 和 `arch/arm/mach-xxx` 中充斥着大量的垃圾代码,相当多数的代码只是在描述板级细节,而这些板级细节对于内核来讲,不过是垃圾,如板上的 platform 设备、resource、i2c_board_info、spi_board_info 以及各种硬件的 platform_data。 + +社区必须改变这种局面,于是 PowerPC 等其他体系架构下已经使用的 Flattened Device Tree(FDT)进入 ARM 社区的视野。 + +Device Tree 是一种描述硬件的数据结构,它起源于 OpenFirmware(OF)。 + +在 Linux 2.6 中,ARM 架构的板极硬件细节过多地被硬编码在 `arch/arm/plat-xxx` 和 `arch/arm/mach-xxx`,采用 Device Tree 后,许多硬件的细节可以直接透过它传递给 Linux,而不再需要在 kernel 中进行大量的冗余编码。 + +Device Tree 由一系列被命名的结点(node)和属性(property)组成,而结点本身可包含子结点。 + +所谓属性,其实就是成对出现的 name 和 value。 + +在 Device Tree 中,可描述的信息包括(原先这些信息大多被 hard code 到 kernel 中): + +* CPU 的数量和类别 +* 内存基地址和大小 +* 总线和桥 +* 外设连接 +* 中断控制器和中断使用情况 +* GPIO 控制器和 GPIO 使用情况 + +它基本上就是画一棵电路板上 CPU、总线、设备组成的树,Bootloader 会将这棵树传递给内核,然后内核可以识别这棵树,并根据它展开出 Linux 内核中的 platform_device、i2c_client、spi_device 等设备。 + +这些设备用到的内存、IRQ 等资源,也被传递给了 kernel,kernel 会将这些资源绑定给展开的相应的设备。 + +## 术语 + +* AMP + * Asymmetric Multiprocessing. + * 非对称多处理器。 + * Computer available CPUs are partitioned into groups, each running a distinct operating system image. + * 计算机中的 CUPs 中被划成组,每个组运行不同的系统镜像。 + * The CPUs may or may not be identical. + * CPUs 不一定是相同的。 +* boot CPU + * The first CPU which a boot program directs to a client program’s entry point. + * 运行引导程序跳转到 client program 的进入点的 CPU。 +* Book III-E + * Embedded Environment. + * 嵌入式环境。 + * Section of the Power ISA defining supervisor instructions and related facilities used in embedded Power processor implementations. + * 电源 ISA 部分定义了嵌入式电源处理器实现中使用的监控器指令和相关设施。 +* boot program + * Used to generically refer to a software component that initializes the system state and executes another software component referred to as a client program. + * 用于泛指初始化系统状态并执行另一个称为客户端程序的软件组件。 + * Examples of a boot program include: firmware, bootloaders, and hypervisors. + * 引导程序的示例包括:固件、引导加载程序和虚拟机管理程序。 +* client program + * Program that typically contains application or operating system software. + * 通常包含应用程序或操作系统软件的程序。 + * Examples of a client program include: bootloaders, hypervisors, operating systems, and special purpose programs. + * 客户端程序的示例包括:引导加载程序、虚拟机管理程序、操作系统和特殊用途程序。 +* cell + * A unit of information consisting of 32 bits. + * 由 32 位组成的信息单位。 +* DMA + * Direct memory access + * 直接内存访问。 +* DTB + * Devicetree blob. + * 设备树 blob。 + * Compact binary representation of the devicetree. + * 设备树的紧凑二进制表示形式。 +* DTC + * Devicetree compiler. + * 设备树编译器。 + * An open source tool used to create DTB files from DTS files. + * 用于从 DTS 文件创建 DTB 文件的开源工具。 +* DTS + * Devicetree syntax. + * 设备树语法。 + * A textual representation of a devicetree consumed by the DTC. + * 被 DTC 使用的设备树的文本表示形式。 + * See Appendix A Devicetree Source Format (version 1). + * 请参阅附录 A 设备树源格式(版本 1)。 +* effective address + * Memory address as computed by processor storage access or branch instruction. + * 由处理器存储访问或分支指令计算的内存地址。 +* physical address + * Address used by the processor to access external device, typically a memory controller. + * 处理器用于访问外部设备(通常是存储器控制器)的地址。 +* Power ISA + * Power Instruction Set Architecture. + * Power 指令集架构。 +* interrupt specifier + * A property value that describes an interrupt. + * 描述中断的属性值。 + * Typically information that specifies an interrupt number and sensitivity and triggering mechanism is included. + * 通常包括指定中断号、灵敏度和触发机制的信息。 +* secondary CPU + * CPUs other than the boot CPU that belong to the client program are considered secondary CPUs. + * 属于客户端程序的引导 CPU 以外的 CPU 被视为辅助 CPU。 +* SMP + * Symmetric multiprocessing. + * 对称多处理。 + * A computer architecture where two or more identical CPUs can share memory and IO and operate under a single operating system. + * 一种计算机体系结构,其中两个或多个相同的 CPU 可以共享内存和 IO,并在单个操作系统下运行。 +* SoC + * System on a chip. + * 片上系统。 + * A single computer chip integrating one or more CPU core as well as number of other peripherals. + * 集成一个或多个 CPU 内核以及许多其他外设的单个计算机芯片。 +* unit address + * The part of a node name specifying the node’s address in the address space of the parent node. + * 节点名称的一部分,用于指定父节点的地址空间中的节点地址。 +* quiescent CPU + * A quiescent CPU is in a state where it cannot interfere with the normal operation of other CPUs. + * 静态 CPU 处于无法干扰其他 CPU 正常运行的状态。 + * nor can its state be affected by the normal operation of other running CPUs. + * 其状态也不会受到其他正在运行的 CPU 正常运行的影响。 + * except by an explicit method for enabling or re-enabling the quiescent CPU. + * 除非通过显式方法启用或重新启用静态 CPU。 + +## The DeviceTree Specification 设备树规范 + +A devicetree is a data structure for describing hardware. + +设备树是用于描述硬件的数据结构。 + +在设备树的官方网站这样写着: + +> Welcome to devicetree.org +> 欢迎来到 devicetree.org +> +> If you are looking for the devicetree specification you’ve come to the right place! +> 如果您正在寻找设备树规范,那么您来对地方了! + +Devicetree.org 是许多公司和个人为促进 Devicetree 标准的未来发展而做出的社区努力。 + +无需将设备的每个细节硬编码到操作系统中,硬件的许多方面都可以在引导时传递给操作系统的数据结构中进行描述。 + +该设备树由 OpenFirmware,OpenPOWER 抽象层(OPAL),Power Architecture Platform Requirements(PAPR)和独立的扁平设备树(FDT)形式使用。 + +设备树规范提供了设备树数据格式和最佳做法的完整技术说明。 + +在这里可以下载到最新的设备树规范 v0.4-rc1. + +打开最新的规范,发现版本是: + +Devicetree Specification +Release v0.3-40-g7e1cc17 + +查看一下目录,规范分了以下六章。 + +* 第一章:介绍设备树规范的结构 +* 第二章:介绍设备树概念和描述它的逻辑结构和标准属性 +* 第三章:阐述 DTSpec-compliant 设备树要求的设备结点基本集合的定义 +* 第四章:具体的设备 (类型) 的设备 bindings +* 第五章:设备树的 DTB 编码 +* 第六章:DTS 语法 + +在计算中,设备树(也称为写入设备树)是描述特定计算机的硬件组件的数据结构,以便操作系统的内核可以使用和管理这些组件。 + +包括 CPU 或 CPU,内存,总线和集成外设。 + +设备树是通过开放固件项目从基于 SPARC 的计算机派生的。 + +当前的 Devicetree 规范针对的是较小的系统,但仍与某些服务器级系统(例如,Power Architecture 平台参考中描述的系统)一起使用。 + +具有 x86 体系结构的个人计算机通常不使用设备树,而是依靠各种自动配置协议(例如 ACPI)来发现硬件。 + +使用设备树的系统通常会将静态设备树(可能存储在 ROM 中)传递给操作系统,但也可以在启动的早期阶段生成设备树。 + +例如,Das U-Boot 和 kexec 可以在启动新操作系统时传递设备树。 + +在具有不支持设备树的引导加载程序的系统上,静态设备树可以与操作系统一起安装。 + +Linux 内核支持这种方法。 + +Devicetree 规范目前由一个名为 devicetree.org 的社区管理,该社区与 Linaro 和 Arm 等相关联。 + +它在设备树源文件(.dts)中指定,并通过设备树编译器(DTC)编译为设备树 Blob 或设备树二进制(.dtb)文件。 + +设备树源文件可以包括其他文件,称为设备树源包含的文件。 + +## Device Tree 编译 + +Device Tree 文件的格式为 `dts`,包含的头文件格式为 `dtsi`,`dts` 文件是一种人可以看懂的编码格式。 + +但是 uboot 和 linux 不能直接识别,他们只能识别二进制文件,所以需要把 dts 文件编译成 dtb 文件。 + +dtb 文件是一种可以被 kernel 和 uboot 识别的二进制文件。 + +把 dts 编译成 dtb 文件的工具是 dtc。 + +Linux 源码目录下 `scripts/dtc` 目录包含 dtc 工具的源码。 + +除了使用在 Linux 的 `scripts/dtc` 目录下提供 dtc 工具外,也可以自己安装 dtc 工具。 + +在 Ubuntu 下执行: + +``` +sudo apt install device-tree-compiler +``` + +安装 dtc 工具。 + +其中还提供了一个 fdtdump 的工具,可以反编译 dtb 文件。 + +dtc 工具的使用方法是: + +``` +$ make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig +$ make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- dtbs + DTC arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dtb + DTC arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dtb + DTC arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dtb +$ dtc –I dts –O dtb –o xxx.dtb xxx.dts +$ dtc –I dtb –O dts –o xxx.dts xxx.dtb +$ fdtdump xxx.dtb > xxx.dts +``` + +即可生成 dts 文件对应的 dtb 文件了。 + +## 总结 + +本文介绍了 Linux 使用设备树的原因, + +设备树规范及一些术语。 + +还介绍了如何编译设备树。 + +接下来几篇文章,会参考 devicetree-specification-v0.4-rc1.pdf 依次介绍第二章到第六章的内容。 + +了解了设备树的语法之后,我们再详细剖析设备树的源码。 + +## 参考 + +1. [Devicetree Specification](https://www.devicetree.org/specifications/) +2. [Devicetree-Wikipedia](https://en.wikipedia.org/wiki/Devicetree) +3. [Linux 和 Devicetree](https://www.kernel.org/doc/html/latest/translations/zh_CN/devicetree/usage-model.html) -- Gitee