linux驱动学习day1-设备树

一、什么是设备树?

1.uboot 启动内核哟用到zImage、imx6ull-alientek-emmc.dtgb、bootz80800000
2.设备树(DTS(Device Tree Source):设备和树。这个 DTS 文件采用树形结构描述板级设备,也就是开发板上的设备信息,比如CPU 数量、 内存基地址、IIC 接口上接了哪些设备、SPI 接口上接了哪些设备等等.
3.在单片机驱动里面的 比如W25QXX、SPI速度等都是在.c文件里面写死。板级信息都写.c里面。导致linux内核臃肿,因此将板子信息做成独立的格式,文件扩展名为.dts。一个平台或者机器对应一个dts。
在这里插入图片描述

二、DTS、DTB 和 DTC 的关系

.dts 相当于.c,就是 DTS 源码文件。
DTC 工具相当于 gcc 编译器,将.dts 编译成.dtb。
.dtb 相当于 bin 文件,或可执行文件。
通过 make dtbs 编译所有的 dts 文件。如果要编译指定的 dtbs
make imx6ull-alientek-emmc.dtb

三、DTS基本语法

1.设备树也有头文件,扩展名为.dtsi,可以将一款SOC他的其他所有设备/平台
2.DTS也是’ / '开始。
3.从/根节点开始描述设备信息
4.在/根节点外有一些&cpu0这样的语句是“追加”
5.节点名字,完整的要求
node_name@unit_ address.
unit-address一般都是外设寄存器起始地址。有时候是I2C的设备地址,或者其他含义,具体节点具体分析。设备树里面常常遇到如下所示节点名字
intc:interrupt-controller@00a01000
:前面是标签label,后面才是名字。intc完整的名字是
interrupt-controller@00a01000。追加的时候&intc intc是label

四、设备树在系统中的体现

系统启动以后可以在跟文件里面看到设备树的节点信息。在/proc/device-tree/目录下存放着设备树信息。
内核启动的时候会解析设备树,然后在/proc/device-tree/目录下呈现出来。
在这里插入图片描述
这样将生成的dtb文件拷贝的tftp目录下,重启开发板,就会在/proc/device-tree里面看到自己创建的节点名称了。

六、特殊节点

1.打开 imx6ull.dtsi 文件,aliases 节点内容如下所示:

aliases {
	can0 = &flexcan1;
	can1 = &flexcan2;
	ethernet0 = &fec1;
	ethernet1 = &fec2;
	gpio0 = &gpio1;
	gpio1 = &gpio2;
	...
	spi0 = &ecspi1;
	spi1 = &ecspi2;
	spi2 = &ecspi3;
	spi3 = &ecspi4;
	usbphy0 = &usbphy1;
	usbphy1 = &usbphy2;
};

单词 aliases 的意思是“别名”,因此 aliases 节点的主要功能就是定义别名,定义别名的目的就是为了方便访问节点。不过我们一般会在节点命名的时候会加上 label,然后通过&label来访问节点,这样也很方便,而且设备树里面大量的使用&label 的形式来访问节点。起别名的节点可以在dev目录下面看到别名。
在这里插入图片描述
2.chosen
chosen 并不是一个真实的设备,chosen 节点主要是为了 uboot 向 Linux 内核传递数据,重点是 bootargs 参数。一般.dts 文件中 chosen 节点通常为空或者内容很少,imx6ull-alientekemmc.dts 中 chosen 节点内容如下所示:

chosen {
 	stdout-path = &uart1;
 };

从示例代码 中可以看出,chosen 节点仅仅设置了属性“stdout-path”,表示标准输
出使用 uart1。但是当我们进入到/proc/device-tree/chosen 目录里面,会发现多了 bootargs 这个
属性,如图 所示:
在这里插入图片描述
从图 可以看出,bootargs 这个文件的内容为“console=ttymxc0,115200……”,这个
不就是我们在 uboot 中设置的 bootargs 环境变量的值吗?现在有两个疑点:
①、我们并没有在设备树中设置 chosen 节点的 bootargs 属性,那么图 中 bootargs
这个属性是怎么产生的?
②、为何 bootargs 文件的内容和 uboot 中 bootargs 环境变量的值一样?它们之间有什么关
系?
因为:
uboot接触过dtb,最终通过bootz 80800000-83000000 来启动内核。83000000 为dtb在RAM中的位置。经过分析判断uboot拥有bootargs环境变量和dtb。因此最有可能“作案”,因此要去查看uboot源码。在uboot源码中全局搜索"chosen",
在这里插入图片描述
足以证明这样。
函数调用流程如下。
在这里插入图片描述
图中框起来的部分就是函数 do_bootm_linux 函数的执行流程,也就是说do_bootm_linux 函数会通过一系列复杂的调用,最终通过 fdt_chosen 函数在 chosen 节点中加入了 bootargs 属性。而我们通过 bootz 命令启动 Linux 内核的时候会运行 do_bootm_linux 函数,
至此,真相大白,一切事情的源头都源于如下命令:
bootz 80800000 – 83000000
当我们输入上述命令并执行以后,do_bootz 函数就会执行,然后一切就按照上图所示的流程开始运行。

六、特殊的属性

1.compatible属性

值是字符串,用来描述兼容性。这是非常重要的一个属性,compatible属性的值是一个字符串列表,compatible属性用于将设备和驱动绑定起来。字符串列表用于选择设备所要使用的驱动程序,compatible属性的格式如下所示:

"manufacturer,model"

其中 manufacturer 表示厂商,model 一般是模块对应的驱动名字。比如 imx6ull-alientekemmc.dts 中 sound 节点是 I.MX6U-ALPHA 开发板的音频设备节点,I.MX6U-ALPHA 开发板上
的音频芯片采用的欧胜(WOLFSON)出品的 WM8960,sound 节点的 compatible 属性值如下:

compatible = "fsl,imx6ul-evk-wm8960","fsl,imx-audio-wm8960";

属性值有两个,分别为“fsl,imx6ul-evk-wm8960”和“fsl,imx-audio-wm8960”,其中“fsl”表示厂商是飞思卡尔,“imx6ul-evk-wm8960”和“imx-audio-wm8960”表示驱动模块名字。

一般驱动程序文件都会有一个 OF 匹配表,此 OF 匹配表保存着一些 compatible 值,如果设备节点的 compatible 属性值和 OF 匹配表中的任何一个值相等,那么就表示设备可以使用这个驱动。比如在文件 imx-wm8960.c 中有如下内容:

static const struct of_device_id imx_wm8960_dt_ids[] = {
{ .compatible = "fsl,imx-audio-wm8960", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_wm8960_dt_ids);

static struct platform_driver imx_wm8960_driver = {
.driver = {
.name = "imx-wm8960",
.pm = &snd_soc_pm_ops,
.of_match_table = imx_wm8960_dt_ids,
},
.probe = imx_wm8960_probe,
.remove = imx_wm8960_remove,
};

其中数组 imx_wm8960_dt_ids就是imx-wm8960.c这个驱动文件的匹配表,此匹配表只有一个匹配值 “fsl,imx-audio-wm8960”, 如果在设备树中有哪个节点的compatible属性值与此相等,那么这个节点就会使用此驱动文件。

2.model属性

model属性值也是一个字符串,一般model属性描述设备模块信息,比如名字什么的
比如:

model = "wm8960-audi  o";

3.status

status 属性看名字就知道是和设备状态有关的,status 属性值也是字符串,字符串是设备的状态信息,如图
在这里插入图片描述

4.#address-cells 和#size-cells 属性

这两个属性的值都是无符号 32 位整形,#address-cells 和#size-cells 这两个属性可以用在任何拥有子节点的设备中,用于描述子节点的地址信息。#address-cells 属性值决定了子节点 reg 属性中地址信息所占用的字长(32 位),#size-cells 属性值决定了子节点 reg 属性中长度信息所占的字长(32 位)。#address-cells 和#size-cells 表明了子节点应该如何编写 reg 属性值,一般 reg 属性都是和地址有关的内容,和地址相关的信息有两种:起始地址和地址长度,reg 属性的格式一为:

reg = <address1 length1 address2 length2 address3 length3……>

每个“address length”组合表示一个地址范围,其中 address 是起始地址,length 是地址长度,#address-cells 表明 address 这个数据所占用的字长,#size-cells 表明 length 这个数据所占用的字长

  • 30
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值