作为uboot到kernel中DTS DTSI DTB等关系

本文介绍了设备树(DeviceTree)的基本概念及其在内核中的重要作用,包括如何简化硬件探测、描述硬件资源的方式,以及设备树的组成部分DTS、DTSI和DTB之间的关系。此外,还详细解释了设备树的编译过程和在BootLoader中的传递方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、设备树(Device Tree)基本概念及作用

在内核源码中,存在大量对板级细节信息描述的代码。这些代码充斥在/arch/arm/plat->xxx和/arch/arm/mach-xxx目录,对内核而言,这些platform设备、resource、I2C_board_info、spi_board_info以及各种硬件的platform_data绝大多数纯属垃圾冗余代码。为了解决这一问题,ARM内核版本3.x之后引入了原先在Power PC等其他体系架构已经使用的Flattened Device Tree.
“A data structure by which bootloaders pass hardware layout to linux in a device-independent manner,simplifying hardware probing.”开源文档中对设备树的描述是,一种描述硬件资源的数据结构,它通过BootLoader将硬件资源传给内核,使得内核和硬件资源描述相对独立。
Device Tree可以描述的信息包括CPU的数量和类别、内存基地址和大小、总线和桥、外设连接、中断控制器和中断使用情况,GPIO控制器和GPIO使用情况、Clock控制器和Clock使用情况。
另外,设备树对于可热插拔的设备不进行具体描述,它只描述用于控制该热插拔设备的控制器。
设备树的主要优势:对于同一SOC的不同主板,只需要更换设备树文件.dtb即可实现不同主板的无差异支持,而无需更换内核文件。
注:要使得3.x之后的内核支持使用设备树,除了内核编译时需要打开相对应的选项外,BootLoader也需要支持将设备树的数据结构传给内核。

2、设备树的组成和使用

设备树包括DTC(device tree compiler),DTS(device tree source和DTB(device tree blob)。其对应关系如图1-1所示
DTS、DTSI由DTC转化成DTB。

2.1 DTS和DTSI(源文件)

.dts文件是一种ASCII文本对Device Tree的描述,放置在内核的/arch/arm/boot/dts目录。一般而言,一个.dts文件对应一个ARM的machine。
由于一个SOC可能有多个不同电路板,而每个电路板拥有一个.dts。这些dts势必会存在许多共同部分,为了减少代码的冗余,设备树讲这些共同部分提炼保存在.dtsi文件中,供不同的dts共同使用。.dtsi的使用方法,类似于C语言的头文件,在dts文件中需要进行include .dtsi文件。当然,dtsi本身也支持include另一个dtsi文件。

2.2 DTC(编译工具)

DTC为编译工具,它可以将.dts文件编译成.dtb文件。DTC的源码位于内核的scripts/dtc目录下,内核选中CONFIG_OF,编译内核的时候,主机可执行程序DTC就会被编译出来。即scripts/dtc/Makefile中

  1. hostprogs-y:=dtc
  2. always:=$(hostprogs-y)
    在内核的arch/arm/boot/dts/Makefile中,若选中某种SOC,则与其对应相关的所有dtb文件都将被编译出来。在Linux下,make dtbs可单独编译dtb.以下截取了TEGRA平台的一部分。
  3. ifeq($(CONFIG_OF),y)
  4. dtb-$(CONFIG_ARCH_TEGRA)+=tegra20-harmony.dtb\
  5. tegra30-beaver.dtb\
  6. tegra114-dalmore.dtb\
  7. tegra124-ardbeg.dtb
2.3 DTB(二进制文件)

DTC编译.dts生成的二进制文件(.dtb),bootloader在引到内核时,会预先读取.dtb到内存,进而由内核解析。

2.4 BootLoader(bootloader支持)

Bootloader需要将设备树在内存中的地址传给内核。在ARM中通过bootm或bootz命令来进行传递。
bootm [kernel_addr] [initrd_address][dtb_address],其中kernel_addr为内核镜像的地址,init.rd为initrd的地址,dtb_address为dtb所在的地址。若initrd_address为空,则用“-”来代替。
DTS的基本语法范例,如图3-1 所示。

它包括一系列节点,以及描述节点的属性。

“/”为root节点。在一个.dts文件中,有且仅有一个root节点;在root节点下有“node1”,“node2”子节点,称root为“node1”和“node2”的parent节点,除了root节点外,每个节点有且仅有一个parent;其中子节点node1下还存在子节点“child-nodel1”和“child-node2”。

注:如果看过内核/arch/arm/boot/dts目录的读者看到这可能有一个疑问。在每个.dsti和.dts中都会存在一个“/”根节点,那么如果在一个设备树文件中include一个.dtsi文件,那么岂不是存在多个“/”根节点了么。其实不然,编译器DTC在对.dts进行编译生成dtb时,会对node进行合并操作,最终生成的dtb只有一个root node。Dtc会进行合并操作这一点从属性上也可以得到验证。这个稍后做讲解。
在节点的{}里面是描述该节点的属性(property),即设备的特性,它的值是多样化的:

  1. 它可以是string,
  2. 它也可以是32 bit unsigned integres
  3. 他也可以是binary data
  4. 他也可能是空
    BootLoader引导内核时,ARM寄存器R2会将.tdb的首地址传给内核,内核根据该地址,接卸.dtb中根节点的compatible属性,将该属性与内核中预先定义machine_desc机构体的dt_compat成员做匹配,得到最匹配的一个machine_desc。

DTB加载解析过程

先从uboot里的do_bootm出发,根据之前描述,DTB在内存中的地址通过bootm命令进行传递。在bootm中,它会根据所传进来的DTB所在内存做一系列操作,为内核解析DTB提供保证。

注:lmb为uboot下的一种内存管理机制,全称为logical memory blocks。用于管理镜像的内存。lmv所记录的内存信息最终会传递给kernel。
世界地图矢量数据可以通过多种网站进行下载。以下是一些提供免费下载世界地图矢量数据的网站: 1. Open Street Map (https://www.openstreetmap.org/): 这个网站可以根据输入的经纬度或手动选定范围来导出目标区域的矢量图。导出的数据格式为osm格式,但只支持矩形范围的地图下载。 2. Geofabrik (http://download.geofabrik.de/): Geofabrik提供按洲际和国家快速下载全国范围的地图数据数据格式支持shape文件格式,包含多个独立图层,如道路、建筑、水域、交通、土地利用分类、自然景观等。数据每天更新一次。 3. bbbike (https://download.bbbike.org/osm/): bbbike提供全球主要的200多个城市的地图数据下载,也可以按照bbox进行下载。该网站还提供全球数据数据格式种类齐全,包括geojson、shp等。 4. GADM (https://gadm.org/index.html): GADM提供按国家或全球下载地图数据的服务。该网站提供多种格式的数据下载。 5. L7 AntV (https://l7.antv.antgroup.com/custom/tools/worldmap): L7 AntV是一个提供标准世界地图矢量数据免费下载的网站。支持多种数据格式下载,包括GeoJSON、KML、JSON、TopJSON、CSV和高清SVG格式等。可以下载中国省、市、县的矢量边界和世界各个国家的矢量边界数据。 以上这些网站都提供了世界地图矢量数据免费下载服务,你可以根据自己的需求选择合适的网站进行下载
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值