对于任何的知识来说,了解了理论的知识,知道了设备树怎么解析用以代替传统的范式之后,我们需要知道怎么使用设备树。对于使用我们分两部分,一部分是它有哪些接口,能做些什么,至于怎么编写dts文件本章不讨论。主要包括两部分:

  1. 对于设备树,编译和设备启动后,怎么来查看设备树的信息,怎么用来debug
  2. 设备树的操作函数提供了哪些接口,基本的方法有哪些

1. 文件系统下的设备树

一部分是出现问题后,怎么用来debug,对于内核来说一切皆是文件的思想,设备树与文件系统的关系,在Linux系统起来后,会将解析完成的设备树导出到用户空间。
kernel启动在of_init()函数中在sys/firmware/devicetree/base目录下面为设备树展开成sysfs的目录和二进制属性文件,所有的node节点就是一个目录,所有的property属性就是一个二进制属性文件。

static int __init of_init(void)
{
	struct device_node *np;

	/* Create the kset, and register existing nodes */
	mutex_lock(&of_mutex);
	of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj);
	if (!of_kset) {
		mutex_unlock(&of_mutex);
		return -ENOMEM;
	}
	for_each_of_allnodes(np)
		__of_attach_node_sysfs(np);
	mutex_unlock(&of_mutex);

	/* Symlink in /proc as required by userspace ABI */
	if (of_allnodes)
		proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");

	return 0;
}
core_initcall(of_init);

该函数比较简单,其主要完成下面三件事情:

  1. 创建/sys/firmware/devicetree/目录
  2. 遍历所有的设备树节点,并且在./sys/firmware/devicetree/目录下创建对应的sysfs,以目录结构程现的dtb文件, 根节点对应base目录, 每一个节点对应一个目录, 每一个属性对应一个文件
  3. 在/proc/device-tree文件软连接到/sys/firmware/devicetree/base

2. 设备树的操作函数

学习完了设备树的文件系统查看方法,那么对于在源码中去拿到设备树的节点或者属性信息,内核提供了那些操作函数呢?内核中开放出来的接口函数的声明大多在include/linux/下面,关于设备树的都是以of形式开头的命名
在这里插入图片描述
对应各个文件主要完成什么功能如下:

文件名功能描述
of.h提供设备树的一般处理函数,大部分的功能函数都在该文件中
of_address.h地址相关的函数, 比如 of_get_address(获得reg属性中的addr, size值)
of_device.h设备相关的函数, 比如 of_match_device、of_device_register
of_dma.h设备树中DMA相关属性的函数
of_fdt.hdtb文件的相关操作函数,我们一般不使用
of_gpio.hGPIO相关的函数
of_graph.hGPU相关驱动中用到的函数, 从设备树中获得GPU信息
of_iommu.hIOMMU相关函数
of_irq.h中断相关的函数
of_mdio.hmdio相关的函数
of_mtd.hmtd相关的函数
of_net.hnet相关的函数
of_pci.hpci相关的函数
of_platform.h把device_node转换为platform_device时用到的函数
of_reserved_mem.hreserved_mem的相关函数
  • 通过compatible属性查找指定节点
struct device_node *of_find_compatible_node(struct device_node *from,
							const char *type, const char *compat);

使用方法可以如下
np = of_find_compatible_node(NULL, NULL, “fsl,imx23-digctl”);
digctrl = of_iomap(np, 0);

digctl: digctl@8001c000 {
	compatible = "fsl,imx28-digctl", "fsl,imx23-digctl";
	reg = <0x8001c000 0x2000>;
	interrupts = <89>;
	status = "disabled";
};
  • 通过节点名查找指定节点
static const struct of_device_id exynos_dt_mcpm_match[] = {
	{ .compatible = "samsung,exynos5420" },
	{ .compatible = "samsung,exynos5800" },
	{},
};

	node = of_find_matching_node(NULL, exynos_dt_mcpm_match);
	if (!node)
		return -ENODEV;
	of_node_put(node);
  • 通过路径查找指定节点
struct device_node *of_find_node_by_path(const char *path);

/* 参数:	const char *path - 带全路径的节点名,也可以是节点的别名 */

data->current_node = of_find_node_by_path("/");

  • 通过节点名查找指定节点
	sscg_np = of_find_node_by_name(NULL, "sscg");
	if (sscg_np == NULL) {
		pr_err("cannot get SSCG register node\n");
		return system_clk;
	}

	sscg_map = of_iomap(sscg_np, 0);
	if (sscg_map == NULL) {
		pr_err("cannot map SSCG register\n");
		goto out;
	}

由于接口操作函数集比较多,详细的需要看对应的函数定义。

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐