最近要学习设备树,在网上找了很多资料,找出几篇写的比较好的博客分享一下:

  https://blog.csdn.net/smcdef/article/details/77387975

  https://blog.csdn.net/dzw19911024/article/details/82115101

  https://blog.csdn.net/huanting_123/article/details/90142745

  https://blog.csdn.net/woshidahuaidan2011/article/details/52948732

  本篇文章总结一些比较特殊的情况,虽然有些在上边这些博客里有提到,但是还是通过一些实例进行具体的分析比较具有说服力。

  为了验证自己写的设备树,首先要编译自己写的设备树,使用dtc工具编译设备,dtc工具的使用方法是:dtc -I dts -O dtb -o xxx.dtb xxx.dts,即可生成dts文件对应的dtb文件了,-I 指输入文件格式,-O指输出文件格式,-o指输出文件名。

  于是我写了一个最简单的dts文件,只包含一个根节点:

1 / {
2 
3 };

  好了,实际上这是一个坑,因为这个文件怎么编都编译不过去。就这个问题困扰了我大半天,早上弄到下午才解决,中间走了很多弯路,然后在一个偶然的机会看到了一个别的设备树文件是可以编译过去的,对比一下发现能编译过去的设备树文件最开始写了一行:/dts-v1/; 将这行加进去就能编译通过了,dts文件改为:

1 /dts-v1/;
2 / {
3 
4 };

  这才是最简单的设备树。找这个问题真的是废了很大的神,因为编译的时候报错信息只有:

  Error: test.dts:1.1-2 syntax error
  FATAL ERROR: Unable to parse input tree

  我只知道文件第一行语法错误,鬼知道是什么错误。查看编译器代码发现“/dts-v1/;”这句还必须写,而且必须写成这个样子,写成“/dts-v2/;”都不行。而且根节点也必须写,根节点还不能有名字。编译之后生成的二进制文件及分析如下图 :

 

 

 

 

  其实前40个字节就是struct fdt_header结构体,该结构体在内核代码scripts/dtc/libfdt/fdt.h中定义了。注意在dt_struct区域中第一个[00 00 00 01]表示的是一个节点的起始,接下来应该是节点的名字,由于根节点是没有名字的,因此后面跟了个[00]表示\0,即根节点名的结束符(虽然没有名字但是有结束符),后面的[00 00 00]是为了按4字节对齐。

  接下来再分析一个比较典型的设备树案例,代码如下:

 1 /dts-v1/;
 2 / {
 3     node@0 {
 4         a-string-property = "A string";
 5         a-string-list-property = "first string", "second string";
 6         a-byte-data-property = [01 02 03 04];
 7         
 8         chile-node@0 {
 9             first-child-property;
10             second-child-property = <1>;
11             a-reference-to-something = <&node1>;
12         };
13     };
14     
15     node:node@1 {
16         an-cmpty-property;
17         a-cell-property = <1 2 3 4>;
18         child-node@0 {
19         
20         };
21     };
22 };

分析图下图:

 

   最后声明一下,本文只是对一些实际案例进行分析,关于设备数的原理解析等请看文章开始推荐的4篇博客。