ARM Linux 3.x的设备树(Device Tree)

发布者:幸福旅程最新更新时间:2024-11-11 来源: cnblogs关键字:ARM  Linux  设备树  Device  Tree 手机看文章 扫描二维码
随时随地手机看文章

1.    ARM Device 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中充斥着大量的垃圾代码,相当多数的代码只是在描述板级细节,而这些板级细节对于内核来讲,不过是垃圾,如板上的platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的platform_data。读者有兴趣可以统计下常见的s3c2410、s3c6410等板级目录,代码量在数万行。

社区必须改变这种局面,于是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使用情况

Clock控制器和Clock使用情况

它基本上就是画一棵电路板上CPU、总线、设备组成的树,Bootloader会将这棵树传递给内核,然后内核可以识别这棵树,并根据它展开出Linux内核中的platform_device、i2c_client、spi_device等设备,而这些设备用到的内存、IRQ等资源,也被传递给了内核,内核会将这些资源绑定给展开的相应的设备。

2.    Device Tree组成和结构整个Device Tree牵涉面比较广,即增加了新的用于描述设备硬件信息的文本格式,又增加了编译这一文本的工具,同时Bootloader也需要支持将编译后的Device Tree传递给Linux内核。

DTS (device tree source).dts文件是一种ASCII 文本格式的Device Tree描述,此文本格式非常人性化,适合人类的阅读习惯。基本上,在ARM Linux在,一个.dts文件对应一个ARM的machine,一般放置在内核的arch/arm/boot/dts/目录。由于一个SoC可能对应多个machine(一个SoC可以对应多个产品和电路板),势必这些.dts文件需包含许多共同的部分,Linux内核为了简化,把SoC公用的部分或者多个machine共同的部分一般提炼为.dtsi,类似于C语言的头文件。其他的machine对应的.dts就include这个.dtsi。譬如,对于VEXPRESS而言,vexpress-v2m.dtsi就被vexpress-v2p-ca9.dts所引用, vexpress-v2p-ca9.dts有如下一行:

/include/ 'vexpress-v2m.dtsi'

当然,和C语言的头文件类似,.dtsi也可以include其他的.dtsi,譬如几乎所有的ARM SoC的.dtsi都引用了skeleton.dtsi。

.dts(或者其include的.dtsi)基本元素即为前文所述的结点和属性:

/ {  

    node1 {  

        a-string-property = 'A string';  

        a-string-list-property = 'first string', 'second string';  

        a-byte-data-property = [0x01 0x23 0x34 0x56];  

        child-node1 {  

            first-child-property;  

            second-child-property = <1>;  

            a-string-property = 'Hello, world';  

        };  

        child-node2 {  

        };  

    };  

    node2 {  

        an-empty-property;  

        a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */  

        child-node1 {  

        };  

    };  

};  

上述.dts文件并没有什么真实的用途,但它基本表征了一个Device Tree源文件的结构:

1个root结点'/';

root结点下面含一系列子结点,本例中为'node1' 和 'node2';

结点'node1'下又含有一系列子结点,本例中为'child-node1' 和 'child-node2';

各结点都有一系列属性。这些属性可能为空,如' an-empty-property';可能为字符串,如'a-string-property';可能为字符串数组,如'a-string-list-property';可能为Cells(由u32整数组成),如'second-child-property',可能为二进制数,如'a-byte-data-property'。

下面以一个最简单的machine为例来看如何写一个.dts文件。假设此machine的配置如下:

1个双核ARM Cortex-A9 32位处理器;

ARM的local bus上的内存映射区域分布了2个串口(分别位于0x101F1000 和 0x101F2000)、GPIO控制器(位于0x101F3000)、SPI控制器(位于0x10170000)、中断控制器(位于0x10140000)和一个external bus桥;

External bus桥上又连接了SMC SMC91111 Ethernet(位于0x10100000)、I2C控制器(位于0x10160000)、64MB NOR Flash(位于0x30000000);

External bus桥上连接的I2C控制器所对应的I2C总线上又连接了Maxim DS1338实时钟(I2C地址为0x58)。

其对应的.dts文件为:

/ {  

    compatible = 'acme,coyotes-revenge';  

    #address-cells = <1>;  

    #size-cells = <1>;  

    interrupt-parent = <&intc>;  

  

    cpus {  

        #address-cells = <1>;  

        #size-cells = <0>;  

        cpu@0 {  

            compatible = 'arm,cortex-a9';  

            reg = <0>;  

        };  

        cpu@1 {  

            compatible = 'arm,cortex-a9';  

            reg = <1>;  

        };  

    };  

  

    serial@101f0000 {  

        compatible = 'arm,pl011';  

        reg = <0x101f0000 0x1000 >;  

        interrupts = < 1 0 >;  

    };  

  

    serial@101f2000 {  

        compatible = 'arm,pl011';  

        reg = <0x101f2000 0x1000 >;  

        interrupts = < 2 0 >;  

    };  

  

    gpio@101f3000 {  

        compatible = 'arm,pl061';  

        reg = <0x101f3000 0x1000  

               0x101f4000 0x0010>;  

        interrupts = < 3 0 >;  

    };  

  

    intc: interrupt-controller@10140000 {  

        compatible = 'arm,pl190';  

        reg = <0x10140000 0x1000 >;  

        interrupt-controller;  

        #interrupt-cells = <2>;  

    };  

  

    spi@10115000 {  

        compatible = 'arm,pl022';  

        reg = <0x10115000 0x1000 >;  

        interrupts = < 4 0 >;  

    };  

  

    external-bus {  

        #address-cells = <2>  

        #size-cells = <1>;  

        ranges = <0 0  0x10100000   0x10000     // Chipselect 1, Ethernet  

                  1 0  0x10160000   0x10000     // Chipselect 2, i2c controller  

                  2 0  0x30000000   0x1000000>; // Chipselect 3, NOR Flash  

  

        ethernet@0,0 {  

            compatible = 'smc,smc91c111';  

            reg = <0 0 0x1000>;  

            interrupts = < 5 2 >;  

        };  

  

        i2c@1,0 {  

            compatible = 'acme,a1234-i2c-bus';  

            #address-cells = <1>;  

            #size-cells = <0>;  

            reg = <1 0 0x1000>;  

            interrupts = < 6 2 >;  

            rtc@58 {  

                compatible = 'maxim,ds1338';  

                reg = <58>;  

                interrupts = < 7 3 >;  

            };  

        };  

  

        flash@2,0 {  

            compatible = 'samsung,k8f1315ebm', 'cfi-flash';  

            reg = <2 0 0x4000000>;  

        };  

    };  

};  

上述.dts文件中,root结点'/'的compatible 属性compatible = 'acme,coyotes-revenge';定义了系统的名称,它的组织形式为:,。Linux内核透过root结点'/'的compatible 属性即可判断它启动的是什么machine。

在.dts文件的每个设备,都有一个compatible 属性,compatible属性用户驱动和设备的绑定。compatible 属性是一个字符串的列表,列表中的第一个字符串表征了结点代表的确切设备,形式为',',其后的字符串表征可兼容的其他设备。可以说前面的是特指,后面的则涵盖更广的范围。如在arch/arm/boot/dts/vexpress-v2m.dtsi中的Flash结点:

flash@0,00000000 {  

     compatible = 'arm,vexpress-flash', 'cfi-flash';  

     reg = <0 0x00000000 0x04000000>,  

     <1 0x00000000 0x04000000>;  

     bank-width = <4>;  

 };  

compatible属性的第2个字符串'cfi-flash'明显比第1个字符串'arm,vexpress-flash'涵盖的范围更广。

再比如,Freescale MPC8349 SoC含一个串口设备,它实现了国家半导体(National Semiconductor)的ns16550 寄存器接口。则MPC8349串口设备的compatible属性为compatible = 'fsl,mpc8349-uart', 'ns16550'。其中,fsl,mpc8349-uart指代了确切的设备, ns16550代表该设备与National Semiconductor 的16550 UART保持了寄存器兼容。

接下来root结点'/'的cpus子结点下面又包含2个cpu子结点,描述了此machine上的2个CPU,并且二者的compatible 属性为'arm,cortex-a9'。

注意cpus和cpus的2个cpu子结点的命名,它们遵循的组织形式为:[@],<>中的内容是必选项,[]中的则为可选项。name是一个ASCII字符串,用于描述结点对应的设备类型,如3com Ethernet适配器对应的结点name宜为ethernet,而不是3com509。如果一个结点描述的设备有地址,则应该给出@unit-address。多个相同类型设备结点的name可以一样,只要unit-address不同即可,如本例中含有cpu@0、cpu@1以及serial@101f0000与serial@101f2000这样的同名结点。设备的unit-address地址也经常在其对应结点的reg属性中给出。ePAPR标准给出了结点命名的规范。

可寻址的设备使用如下信息来在Device Tree中编码地址信息:

    reg

    #address-cells

    #size-cells

其中reg的组织形式为reg = ,其中的每一组address length表明了设备使用的一个地址范围。address为1个或多个32位的整型(即cell),而length则为cell的列表或者为空(若#size-cells = 0)。address 和 length 字段是可变长的,父结点的#address-cells和#size-cells分别决定了子结点的reg属性的address和length字段的长度。在本例中,root结点的#address-cells = <1>;和#size-cells = <1>;决定了serial、gpio、spi等结点的address和length字段的长度分别为1。cpus 结点的#address-cells = <1>;和#size-cells = <0>;决定了2个cpu子结点的address为1,而length为空,于是形成了2个cpu的reg = <0>;和reg = <1>;。external-bus结点的#address-cells = <2>和#size-cells = <1>;决定了其下的ethernet、i2c、flash的reg字段形如reg = <0 0 0x1000>;、reg = <1 0 0x1000>;和reg = <2 0 0x4000000>;。其中,address字段长度为0,开始的第一个cell(0、1、2)是对应的片选,第2个cell(0,0,0)是相对该片选的基地址,第3个cell(0x1000、0x1000、0x4000000)为length。特别要留意的是i2c结点中定义的 #address-cells = <1>;和#size-cells = <0>;又作用到了I2C总线上连接的RTC,它的address字段为0x58,是设备的I2C地址。

[1] [2] [3] [4]
关键字:ARM  Linux  设备树  Device  Tree 引用地址:ARM Linux 3.x的设备树(Device Tree)

上一篇:Linux Kernel之flush_cache_all在ARM平台下是如何实现的
下一篇:最后一页

推荐阅读最新更新时间:2024-11-11 13:53

特斯拉车主设计一款戒指钥匙 可以打开Model 3汽车
据外媒报道,一对夫妻设计了一款戒指,其中嵌入了 特斯拉Model 3 密钥卡的RFID(无线射频识别)芯片,能够打开汽车车门。虽然大家觉得制造可穿戴“戒指钥匙”可能会很复杂,但是车主表示,其实相当简单。 (图片来源:teslarati.com) 进入 特斯拉 Model 3的主要钥匙其实是车主的智能手机,如果车主在使用移动设备时遇到了麻烦,例如无法使用或者电池耗尽时,密钥卡就是一个使用方便的备用方案。不过,车主的最新发明进一步让打开汽车更加简便。 (图片来源:推特) 特斯拉Model 3车主将密钥卡的一部分在丙酮中溶解,将RFID芯片的铜质天线分离出来。然后,将该铜质天线缠绕到一个环形模具上,并与树脂混合。此次
[汽车电子]
特斯拉车主设计一款戒指钥匙 可以打开Model <font color='red'>3</font>汽车
ARM裸机开发笔记2ARM的存储与工作模式
1.两种工作状态:ARM状态 32位指令 Thumb 16位指令 可以通过一些机制进行两种状态的转换 2.ARM的寻址空间对多可以达到4G,是以字为单位进行对齐(字对齐)。 一款ARM芯片先要知道其存储方式:是大端还是小端(大小端的编译等存在差别) ARM体系结构分为两种方法存储数据,成为大端方式和小端方式 大端方式:字数据的高字节存储在低地址中,而数据的字节数据的低字节则存放在高地址中。 小端方式:与大端方式相反,在小端存储格式中,低地址中存放的是字节数据的低字节,高地址存放的是字数据的高字节 如下图所示: 3.指令长度与数据类型 ARM----- 32位 Thumb-------- 16位
[单片机]
Spansion新款MCU家族助力打造新型汽车设计
汽车销售人员通常会向潜在买家询问一系列问题,以便帮助他们锁定符合其要求的车型。您中意哪个品牌?想要哪种车型?喜欢什么颜色呢?随着产品的更新换代和功能的推陈出新,消费者在选购汽车的过程中提出的问题也随着时间的推移而不断演进。这款车配有电动车窗吗?音响系统是哪种?是否配有iPhone插座? 随着混合动力汽车和电动汽车等新型能源汽车的问世,另一个层面的问询也会随之增多。 上世纪九十年代,新能源汽车技术回潮,并且一直延续到二十一世纪。鉴于消费者不断寻求减少燃油支出的出行方案,而且制造商也必须遵守二氧化碳减排法规,全球混合动力汽车和电动汽车的市场规模会得到快速增长。预计到2020年,全球年均销量将达到380万辆。 此外,德勤在其最新全球汽车
[单片机]
ARM汇编中的:比较指令CMN / CMP / TEQ / TST
1. 简介 CMP / CMN : 算术指令 TEQ / TST : 逻辑指令 它们总是会影响CPSR条件标志位. APSR(CPSR)与condition的关系图: 2. CMN -- 比较取负的值 CMN{条件}{P} op1 , op2 status = op1 - (-op2) 相加操作 CMN R0, #1 @把R0与-1进行比较 3. CMP CMP{条件}{P} op1 , op2 status = op1 - (op2) 相减操作 会影响标志位.
[单片机]
<font color='red'>ARM</font>汇编中的:比较指令CMN / CMP / TEQ / TST
大陆集团、HERE和Leia联手打造裸眼3D汽车导航
大陆 集团、HERE和Leia正在合作,将三维导航技术引入到汽车驾驶舱的显示解决方案中。通过这种方式,三家公司将共同为安全、直观的车内用户体验助力,并带来惊艳的效果。HERE通过3D技术描绘出的建筑物和地形通过Leia的光场技术来进行显示。这种联合解决方案可以实现3D地图的可视化,而无需佩戴自适应眼镜或眼动传感器。光场技术甚至可以使3D效果从不同角度可见。因此,驾驶员和乘客都可以看到3D图形。 3D显示技术不仅为汽车驾驶舱带来了新的惊艳效果,而且通过合适的内容,可以为驾驶员和车辆创造更直观的互动,从而提高驾驶安全性 ,大陆集团人机界面事业部战略和产品组合负责人Ulrich Lueders说到。 3D显示对于导航尤为重要,
[汽车电子]
大陆集团、HERE和Leia联手打造裸眼<font color='red'>3</font>D汽车导航
视频监控:3G差强人意 4G令人赞不绝口
    如今,城市管理的发展趋势正在向平安城市转变,而平安城市的建设中,视频监控的部署是必不可少的环节,与此同时,3G问题也是迫切要解决的。      3G网络高资费制约无线应用     由于受到地理环境和工作内容的限制,部分区域有线网络部署困难、成本较高,需要有线与无线网络结合使用,才能保证在应用需求的覆盖范围实现视频监控,同时配合GPS、北斗定位系统实现人员与车辆的定位;     3G无线网络的收费方式极大的制约了无线传输方式的发展,随着4G网络建设的不断推开,网络的租用费用将不断降低,平安城市中无线网络部署成为重要的一部分,可采用以4G为主结合3G网络的方式,4G系统能够以100Mbps的速度下载,上传的速度理
[安防电子]
搞事情!东风标致5008,18万中型SUV首月超3
    时光飞逝,2017年已经过了一半,车企们也都各显神通,作为当下最火的SUV车型,上半年也是持续保持热度,其中大众途昂,雪佛兰探界者等等都相继与大家见面。      当然除此之外,还有一款中型SUV,也就是我们今天的主角—东风标致5008,这款车于6月份上市,指导价为18.77-27.97万,而且数据显示其在上市第一个月就卖出去3216辆!   那么这款车实力如何呢?我们一起来看看。      前脸采用了标致家族全新的设计语言,点阵式进气格栅搭配狮眼大灯,霸气十足,也有很高的辨识度。      侧面采用高腰线、高轮拱设计,透露着很强的运动气息,尾部采用较为平直的线条,非常硬朗。      定位于中型SUV,长宽高分别为4
[汽车电子]
华北工控新推基于Freescale ARM架构All In One Mini主板
概述 华北工控顺应市场趋势,推出一款基于Freescale ARM架构All In One Mini主板EMB-2500。该板体积小巧、性能强劲、功耗低,主要针对小空间、小体积应用方案而设计。采用的是Freescale Cortex™-A9架构的高扩展性多核系列应用处理器。该处理器不仅具有超强的图形处理能力、1080P高清播放以及强劲的应用计算能力,同时拥有极低的系统功耗。该板扩展接口丰富: 支持1个双通道24bit LVDS接口、1个mini HDMI接口和1个VGA接口、1个千兆网卡、1个SATA2、2个RS-232、4个USB2.0、1个Mini_USB(OTG)接口等。 EMB-2500兼具了稳定可靠的工
[嵌入式]
华北工控新推基于Freescale <font color='red'>ARM</font>架构All In One Mini主板
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved