第十四课--MicroWRT 内核树介绍
本节教程主要介绍Linux 内核树的概念,在3.x的linux 系统中,为了是kernel 程序保持整洁,将许多和开发板相关的代码去掉了,然后引入了 内核树的概念。下面就让我们了解一下内核树,这里只是一个简单介绍,详细的资料在网上会找到很多。
Device Tree Source诞生在过去的linux内核里,如:ARM Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码, 相当多数的代码只是在描述板级细节,而这些板级细节对于内核来讲,不过是垃圾, 如板上的platform设备、resource、i2c_board_info、spi_board_info 以及各种硬件的platform_data。 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、总线、设备组成的树,Bootloader会将这棵树传递给内核,然后内核可以识别这棵树, 并根据它展开出Linux 内核中的platform_device、i2c_client、spi_device等设备,而这些设备用到的内存、IRQ等资源, 也被传递给了内核, 内核会将这些资源绑定给展开的相应的设备。 Device Tree组成和结构.dts文件是一种ASCII 文本格式的Device Tree描述,此文本格式非常人性化,适合人类的阅读习惯。 基本上,在mips Linux,一个.dts文件对应一个mips的machine,一般放置在/target/linux/ramips/dts目录。 由于一个SoC可能对应多 个machine(一个SoC可以对应多个产品和电路板),势必这些.dts文件需包含许多共同的部分,Linux内核为了简化, 把SoC公用的部分或者 多个machine共同的部分一般提炼为.dtsi,类似于C语言的头文件。其他的machine对应的.dts就include这个.dtsi。 譬如, 对于MT762n而言,mt7620n.dtsi就被WRTNODE.dts,WRTNODE.dts所引用,WRTNODE.dts 有如下一行: /include/ "mt7620n.dtsi" 当然,和C语言的头文件类似,.dtsi也可以include其他的.dtsi,譬如几乎所有的ARM SoC的.dtsi都引用了skeleton.dtsi。 .dts(或者其include的.dtsi)基本元素即为前文所述的结点和属性。 例如:m25p80的spi flash m25p80@0 { #address-cells = <1>; #size-cells = <1>; #compatible = "mx25l6405d"; compatible = "w25q128"; reg = <0 0>; linux,modalias = "m25p80", "w25q128"; spi-max-frequency = <10000000>; partition@0 { label = "u-boot"; reg = <0x0 0x30000>; read-only; }; partition@30000 { label = "u-boot-env"; reg = <0x30000 0x10000>; read-only; }; factory: partition@40000 { label = "factory"; reg = <0x40000 0x10000>; read-only; }; partition@50000 { label = "firmware"; reg = <0x50000 0xfb0000>; }; }; m25p80@0 为结点, partition@0, factory: partition@40000 是他的子结点。 compatible 属性的组织形式为<manufacturer>,<model>,别名其实就是去掉compatible 属性中逗号前的manufacturer前缀。 关于这一点,可查看drivers/spi/spi.c的源代码,函数spi_match_device()暴露了更多的细节, 如果别名出现在设备spi_driver的id_table里面,或者别名与spi_driver的name字段相同,SPI设备和驱动都可以匹配上。 |