一个machine能正常工作,很多硬件设备在写驱动时已经固定,比如CPU,总线和桥,I2C号等外设信息,屏幕配置等(当然也有不固定的,比如支持热插拔的USB和光模块等设备)。这些固定不轻易修改的、不支持热插拔的设备信息,linux内核以前如何处理的?现在又是啥情况?
01
主角介绍
Linus Torvalds林纳斯·本纳第克特·托瓦兹(Linus Benedict Torvalds),1969年,芬兰赫尔辛基人,Linux内核的发明人及该计划的合作者。现受聘于开放源代码开发实验室(OSDL:Open Source Development Labs, Inc),全力开发Linux内核。
每次正式 的linux kernel release之后都会有两周的merge window,在这个窗口期间,kernel各个部分的维护者都会提交各自的patch,将自己测试稳定的代码请求并入kernel main line。每到这个时候,Linus就会比较繁忙,他需要从各个内核维护者的分支上取得最新代码并merge到自己的kernel source tree中。
Linus Torvalds在2011年3月17日的ARM Linux邮件列表宣称“this whole ARM thing is a f*cking pain in the ass”,引发ARM Linux社区的地震,随后ARM社区进行了一系列的重大修正。在过去的ARM Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码,相当多数的代码只是在描述板级细节,而这些板级细节对于内核来讲不过是垃圾。
我们从上面这段故事中得到几个要素:
① linux创始人本尊Linus Torvalds是个不羁的暴脾气;
② ARM社区改动频繁,原始架构设计漏洞显现;
③ Dts结构的在较新的内核版本里才支持,主要针对ARM架构,据说最开始powerPC先用,现在mips等架构也在延用。
02
故事结局
经过一些讨论,对ARM平台的相关code做出如下相关规范调整:
① ARM的核心代码仍然保存在arch/arm
② ARM SoC core architecture code保存在arch/arm
③ ARM SOC的周边外设模块的驱动保存在drivers
④ ARM SOC的特定代码在arch/arm/mach-xxx
⑤ ARM SOC board specific的代码被移除,由DeviceTree机制来负责传递硬件拓扑和硬件资源信息。
本质上,Device Tree改变了原来用hardcode方式将HW 配置信息嵌入到内核代码的方法,改用bootloader传递一个DB的形式。
如果我们认为kernel是一个black box,那么其输入参数应该包括:
a.识别platform的信息 b.runtime的配置参数 c.设备的拓扑结构以及特性
对于嵌入式系统,在系统启动阶段,bootloader会加载内核并将控制权转交给内核,此外,还需要把上述的三个参数信息传递给kernel,以便kernel可以有较大的灵活性。在linux kernel中,Device Tree的设计目标就是如此。
03
DTS是什么
DTS即Device Tree Source 设备树源码:
① Device Tree 可以描述的信息包括CPU的数量和类别,内存基地址和大小,总线和桥,外设连接,中断控制器和中断使用情况,Clock控制器和Clock使用情况。
② 设备树信息被保持在一个ASCII文本文件中,适合人类阅读习惯。类似于XML文件,在ARM linux中,一个.dts文件对应一个arm的machine放置在内核的arch/arm/boot/dts/ 目录中
③ 设备树是一种数据结构,用于描述设备信息的语言,具体而言,是用于操作系统中描述硬件,使得不需要对设备进行硬编码
④ Devices Tree是由一系列被命名的节点(node)和属性(property)组成, 而节点本身可包含子节点。所谓属性,其实就是成对出现的name和value
⑤ 设备树源文件dts被编译成dtb二进制,在bootloader运行时传递给操作系统,操作系统对其进行解析展开,从而产生一个硬件设备的拓扑图,有了这个拓扑图,在编成过程可以直接通过系统提供的接口获取到设备树的节点和属性信息
⑥ 经过Device Tree Compiler(dtc)将dts文件转换成二进制文件binary device tree blob(dtb),.dtb文件可由Linux内核解析
由此我们知道通过dts设备树就能知道一个machine的硬件特点,dts文件将被编译并作为参数传递给bootloader。
以eaidk设备为例,ubuntu系统内核编译命令是
make rockchip_linux_defconfig
make rk3399-eaidk-linux.img -j4
dts文件为kernel\arch\arm64\boot\dts\rockchip\rk3399-eaidk-linux.dts
通过编译命令直接指定了eaidk用的dts文件。
嵌入式看代码的困境经常是不熟悉流程和架构,排查故障找不到调用哪个函数,熟悉内核结构和目录也是一种积累。
至于dts文件怎么写,初学者暂时不用了解,首先需要知道的是很多硬件配置信息可以从dts文件里查到。
04
相关名词缩写
① DT :Device Tree
② FDT : Flattened Device Tree
③ OF :Open Firmware, dts起源于OF
④ DTS :device tree source
⑤ DTSI:device tree source include,通常dts文件都以头文件包含的格式#inclue ” .dtsi”
⑥ DTB :device tree blob dtb编译结果文件
DTC :device tree compiler
05
写在最后
今天一起走近linux内核dts的前世今生,请回答几个问题,为什么引入dts,dts内容包括哪些,dts相关的术语含义是什么?
攻城狮什么时候用到dts,开发一个arm架构machine的时候肯定要重头写dts,改硬件配置,比如屏幕,gpio,或者i2c外围设备等等,先从改dts开始,dts是内核重要组件。