DTS结构及其编译方法

一:主要问题

1,需要了解dtsi与dts的关系

2,dts的结构模型

3,dts是如何被编译的,以及编译后会生成一个什么文件.

二:参考文字

1,DTS(device tree source)

.dts文件是一种ASCII文本格式的DeviceTree描述。基本上,在ARMLinux内,一个.dts文件对应一个ARM的machine,一般放置在内核的arch/arm/boot/dts/目录。由于一个SoC可能对应多个machine(一个SoC可以对应多个产品和电路板),势必这些.dts文件需包含许多共同的部分。Linux内核为了简化,把SoC公用的部分或者多个machine共同的部分一般提炼为.dtsi,类似于C语言的头文件。其他的machine对应的.dts就include这个.dtsi。

2,dts的结构模型

为了了解DeviceTree的结构,我们首先给出一个DeviceTree的示例:

/o device-tree
      |- name ="device-tree"
      |- model ="MyBoardName"
      |-compatible = "MyBoardFamilyName"
     |- #address-cells = <2>
      |-#size-cells = <2>
      |-linux,phandle = <0>
      |
     o cpus
      | | - name = "cpus"
     | | - linux,phandle = <1>
      | |- #address-cells = <1>
      | | -#size-cells = <0>
      | |
     | o PowerPC,970@0
      | |- name ="PowerPC,970"
      | |-device_type = "cpu"
      | |-reg = <0>
      | |-clock-frequency = <0x5f5e1000>
     | |- 64-bit
      | |- linux,phandle =<2>
      |
     o memory@0
      | |- name ="memory"
      | |- device_type= "memory"
      | |- reg =<0x00000000 0x00000000 0x00000000 0x20000000>
     | |- linux,phandle = <3>
     |
      o chosen
       |- name = "chosen"
       |- bootargs = "root=/dev/sda2"
       |- linux,phandle = <4>

从上图中可以看出,devicetree的基本单元是node。这些node被组织成树状结构,除了rootnode,每个node都只有一个parent。一个devicetree文件中只能有一个rootnode。每个node中包含了若干的property/value来描述该node的一些特性。每个node用节点名字(nodename)标识,节点名字的格式是node-name@unit-address。如果该node没有reg属性(后面会描述这个property),那么该节点名字中必须不能包括@和unit-address。unit-address的具体格式是和设备挂在那个bus上相关。例如对于cpu,其unit-address就是从0开始编址,以此加一。而具体的设备,例如以太网控制器,其unit-address就是寄存器地址。rootnode的nodename是确定的,必须是“/”。

3,dts是如何被编译的,以及编译后会生成一个什么文件。

  1. DTC(device tree compiler)

dtc是将.dts编译为.dtb的工具。DTC的源代码位于内核的scripts/dtc目录,在Linux内核使能了DeviceTree的情况下,编译内核时,主机工具dtc会被编译出来,对应scripts/dtc/Makefile中的“hostprogs-y:= dtc”这一hostprogs编译target。

在Linux内核的arch/arm/boot/dts/Makefile中,描述了当某种SoC被选中后,哪些.dtb文件会被编译出来。举例如下:

如与VEXPRESS对应的.dtb包括:

   dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \    vexpress-v2p-ca9.dtb \  vexpress-v2p-ca15-tc1.dtb \ vexpress-v2p-ca15_a7.dtb \  xenvm-4.2.dtb

在Linux下,我们可以单独编译DeviceTree文件。当我们在Linux内核下运行makedtbs时,若我们之前选择了ARCH_VEXPRESS,上述.dtb都会由对应的.dts编译出来。因为arch/arm/Makefile中含有一个dtbs编译target项目。

  1. DeviceTree Blob (.dtb)

.dtb是.dts被DTC编译后的二进制格式的DeviceTree描述,可由Linux内核解析。通常在我们为电路板制作NAND、SD启动image时,会为.dtb文件单独留下一个很小的区域以存放之,之后bootloader在引导kernel的过程中,会先读取该.dtb到内存。

  1. 源代码体现

有两种方式使用DT。第一种可包含多个dtb,编入dt.img,放入boot.img。第二种只包含一个dtb,直接追加到kernelimage后面,放入boot.img。
dtc编译在kernel/AndroidKernel.mk中定义。先用定义"DTS_NAMES"变量,它的每个entry(记为"DTS_NAME"变量,下面的$$arch)中可能有arch和rev两部分,和.config中相关配置有关,用下面方法找出。

while (<>) {$$a = $$1 if /CONFIG_ARCH_((?:MSM|QSD|MPQ)[a-zA-Z0-9]+)=y/;
$$r = $$1 if /CONFIG_MSM_SOC_REV_(?!NONE)(\w+)=y/;
$$arch = $$arch.lc("$$a$$r ") if /CONFIG_ARCH_((?:MSM|QSD|MPQ)[a-zA-Z0-9]+)=y/
} print $$arch;

得到上述"DTS_NAMES"变量,用"$(DTS_NAME)*.dts"方式去"kernel/arch/arm/boot/dts/"下匹配。见下面的定义,其中"cat"命令就是生成带DT的kernelimage。

define append-dtb
mkdir -p $(KERNEL_OUT)/arch/arm/boot;\
$(foreach DTS_NAME, $(DTS_NAMES), \
   $(foreach d, $(DTS_FILES), \
      $(DTC) -p 1024 -O dtb -o $(call DTB_FILE,$(d)) $(d); \
      cat $(KERNEL_ZIMG) $(call DTB_FILE,$(d)) > $(call ZIMG_FILE,$(d));))
endef

第二种方式没看到后续如何放入boot.img。对于第一种方式,会用"device/qcom/common/generate_extra_images.mk"中定义的下面规则编出"dt.img",

$(INSTALLED_DTIMAGE_TARGET): $(DTBTOOL) $(INSTALLED_KERNEL_TARGET)
        $(build-dtimage-target)

在"build/core/Makefile"中用下面语句使它被编入boot.img。

ifeq ($(strip $(BOARD_KERNEL_SEPARATED_DT)),true)
  INTERNAL_BOOTIMAGE_ARGS += --dt $(INSTALLED_DTIMAGE_TARGET)
  BOOTIMAGE_EXTRA_DEPS   s:= $(INSTALLED_DTIMAGE_TARGET)
endif

(DT系列一)DTS结构及其编译方法相关推荐

  1. dts 编译过程_DTS结构及其编译方法

    一.主要问题 1,需要了解dtsi与dts的关系 2,dts的结构模型 3,dts是如何被编译的,以及编译后会生成一个什么文件. 二.参考文字 1,DTS(device tree source) .d ...

  2. DTS结构及其编译和反编译方法

    https://wenku.baidu.com/view/89851ee8bb68a98270fefa59.html https://blog.csdn.net/lichengtongxiazai/a ...

  3. go 修改结构体方法_「GCTT 出品」Go 系列教程——26. 结构体取代类

    Go语言中文网,致力于每日分享编码.开源等知识,欢迎关注我,会有意想不到的收获! Go 支持面向对象吗? Go 并不是完全面向对象的编程语言.Go 官网的 FAQ 回答了 Go 是否是面向对象语言,摘 ...

  4. arm linux打印机驱动编译方法,嵌入式linux驱动打印机HP系列

    arm linux打印机驱动编译方法和过程记录(2017.03.15): 改动添加概述: 添加foo2zjs工具(用于发送数据到打印机进行打印): 添加gohstscript工具(用于转换文档格式到打 ...

  5. Atitit 发帖机系列(7) 词法分析的方法attilax大总结)

    Atitit 发帖机系列(7) 词法分析的方法attilax大总结) 1.1. 词法分析貌似俩大方法,一个直接根据状态图转换,一个根据dfa1 1.2. switchcase或者ifelse 最原始方 ...

  6. ES6 系列之 Babel 是如何编译 Class 的(上)

    前言 在了解 Babel 是如何编译 class 前,我们先看看 ES6 的 class 和 ES5 的构造函数是如何对应的.毕竟,ES6 的 class 可以看作一个语法糖,它的绝大部分功能,ES5 ...

  7. 【java】RMI教程:入门与编译方法 远程

    1.概述 转载:RMI教程:入门与编译方法 2.分布式对象和RMI 分布式对象技术主要是在分布式异构环境下简历应用系统框架和对象构件.在应用系统框架的支撑下,开发者可以将软件功能封装为更易于管理和使用 ...

  8. linux 驱动编译静态,Linux驱动静态编译和动态编译方法详解

    内核源码树的目录下都有两个文档Kconfig和Makefile.分布到各目录的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录源文档相关的内核配置菜单.在内核配置m ...

  9. 一步步实现windows版ijkplayer系列文章之一Windows10平台编译ffmpeg 4.0.2,生成ffplay

    一步步实现windows版ijkplayer系列文章之一Windows10平台编译ffmpeg 4.0.2,生成ffplay 最近想研究下ffplay的代码,学习代码是枯燥无味的,也是抽象的,学习一个 ...

最新文章

  1. 【FFmpeg】警告:[mpegts] H.264 bitstream error, startcode missing, size 0
  2. 废弃电器电子产品回收:需要的不仅是补贴 !
  3. 从 SPIR-V 到 ISPC:将 GPU 计算转化为 CPU 计算
  4. 使用正則表達式对URL进行解析
  5. Flink 在小红书推荐系统中的应用
  6. html语言基础tr,HTML tr 标签
  7. mysql 实例启动利用binlog恢复_mysql利用binlog进行数据恢复
  8. java log输出到文件路径_Java - 配置log4j的日志文件路径 (附-获取当前类路径的多种方法)...
  9. 深度学习(六十五)移动端网络MobileNets
  10. 官宣:Linux 内核主要贡献者 Linaro「喜提」新任 CEO!
  11. S32K MCAL03-如何使用EB工具配置FlexCAN的波特率
  12. Windows 10 如何离线安装NetFx3
  13. 腾讯全球首款JS代码坦克 CodeTank
  14. JavaScript学习手册四:JS对象
  15. 桥接模式和NAT模式的区别
  16. 基于BoF算法的图像分类
  17. 2020年高教社杯全国大学生数学建模竞赛题目D题 接触式轮廓仪的自动标注
  18. ubuntu18.04添加网络共享文件夹
  19. A类博士后年薪30万起!北邮人工智能学院郭军教授实验室招聘博士后研究人员...
  20. 一种基于信令数据的业务推销类骚扰电话识别方法

热门文章

  1. IAR下载报错 “Fatal error: Failed to connect to CPU Session aborted!”
  2. 百度前端技术学院—-小薇学院(HTML+CSS课程任务)
  3. 给苹果cms添加视频描述伪原创处理功能
  4. 苹果怎么换字体_换了苹果手机怎么恢复通讯录
  5. 和平精英奇葩吃鸡操作,帮你苟到最后轻松吃鸡
  6. deadbeef_于关u-boot中的.balignl 16,0xdeadbeef的理解(原创,请勿转载)
  7. PPT播放时用到的技巧
  8. 内网ip和外网ip的联系以及连接过程
  9. Java接口可以继承接口么
  10. phpstudy启功apache失败,直接在端口设置更改