Linux设备树详解(五)设备树的使用
linux-dash
A beautiful web dashboard for Linux
项目地址:https://gitcode.com/gh_mirrors/li/linux-dash
免费下载资源
·
对于任何的知识来说,了解了理论的知识,知道了设备树怎么解析用以代替传统的范式之后,我们需要知道怎么使用设备树。对于使用我们分两部分,一部分是它有哪些接口,能做些什么,至于怎么编写dts文件本章不讨论。主要包括两部分:
- 对于设备树,编译和设备启动后,怎么来查看设备树的信息,怎么用来debug
- 设备树的操作函数提供了哪些接口,基本的方法有哪些
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);
该函数比较简单,其主要完成下面三件事情:
- 创建/sys/firmware/devicetree/目录
- 遍历所有的设备树节点,并且在./sys/firmware/devicetree/目录下创建对应的sysfs,以目录结构程现的dtb文件, 根节点对应base目录, 每一个节点对应一个目录, 每一个属性对应一个文件
- 在/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.h | dtb文件的相关操作函数,我们一般不使用 |
of_gpio.h | GPIO相关的函数 |
of_graph.h | GPU相关驱动中用到的函数, 从设备树中获得GPU信息 |
of_iommu.h | IOMMU相关函数 |
of_irq.h | 中断相关的函数 |
of_mdio.h | mdio相关的函数 |
of_mtd.h | mtd相关的函数 |
of_net.h | net相关的函数 |
of_pci.h | pci相关的函数 |
of_platform.h | 把device_node转换为platform_device时用到的函数 |
of_reserved_mem.h | reserved_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 年前
更多推荐
已为社区贡献5条内容
所有评论(0)