Linux内核Device Tree怎么创建

技术Linux内核Device Tree怎么创建这篇文章主要讲解了“Linux内核Device Tree怎么创建”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux内

这篇文章主要讲解了“Linux内核设备树怎么创建",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux内核设备树怎么创建"吧!

在Linux操作系统操作系统内核启动时,内核通过of_platform_populate()函数,将调度员培训模拟系统中的设备节点创建成平台设备。为后续和各类驱动的平台驱动程序匹配做准备。

of_platform_populate()函数在文件驱动程序/of/platform.c中实现。下面基于洛克皮4A单板的内核代码介绍其调用流程和实现过程。

一、函数调用流程

在Linux操作系统操作系统内核中,可以使用dump_stack()函数查看函数的调用流程。

/* * * of _ platform _ populate()-从devicetreedata填充platform _ devices.#省略部分注释*/intof _ platform _ populate(struct device _ node * root,conststructof _ device _ id * matches,conststructof _ dev _ auxdata * lookup,struct device * parent){ struct device _ node * child;int RC=0;dump _ stack();###打印函数调用的堆栈信息//1.如果根为空值,则通过of_find_node_by_path()查找根=根?of _ node _ get(root): of _ find _ node _ by _ path('/');if(!根)返回-EINVAL;//2.遍历调度员培训模拟系统中的节点for _ every _ child _ of _ node(根,子){//3。为每个节点和子节点创建platformdevicerc=of _ platform _ bus _ create(子,匹配,查找,父,真);}.} EXport _ SYMBOL _ GPL(of _ platform _ populate);dump_stack()堆栈信息如下:

[0.311191]CPU :0 PID :1 comm : swapper/0未绑定4。4 .154-00036-gcef 30e 88 a9 F5-脏# 36[0.311198]硬

ware name: ROCK PI 4A 2 (DT)[    0.311206] Call trace:[    0.311220] [<ffffff80080888d8>] dump_backtrace+0x0/0x220[    0.311232] [<ffffff8008088b1c>] show_stack+0x24/0x30[    0.311244] [<ffffff800856ebec>] dump_stack+0x98/0xc0[    0.311258] [<ffffff80089a1000>] of_platform_populate+0x30/0xb8[    0.311268] [<ffffff8009113b68>] arm64_device_init+0x30/0x4c[    0.311278] [<ffffff80080831cc>] do_one_initcall+0x18c/0x194[    0.311290] [<ffffff8009110e10>] kernel_init_freeable+0x228/0x22c[    0.311301] [<ffffff8008c75080>] kernel_init+0x18/0x100[    0.311311] [<ffffff8008082ef0>] ret_from_fork+0x10/0x20

从堆栈信息中,可以看出:在arm64_device_init()函数中实现了of_platform_populate()函数的调用。后续介绍kernel_init()函数,暂时先留个念想。

注:

arm64_device_init()函数在arch/arm64/kernel/setup.c文件中实现。此时,串口驱动尚未加载,串口日志保存在缓冲区中。由于RK3399是多核,在Linux内核启动时,堆栈信息或其它日志有可能会丢失。在系统启动时,可以增加nosmp配置,关闭其他CPU的加载,保证尽可能多的日志输出。在配置文件/boot/extlinux/extlinux.conf最后增加:

label kernel-debug    kernel /debug/Image    fdt /debug/rk3399-rock-pi-4a.dtb    append earlyprintk console=ttyFIQ0,1500000n8 init=/sbin/init root=PARTUUID=b921b045-1d rw rootwait rootfstype=ext4 nosmp
二、函数实现过程

of_platform_populate()函数主要通过of_platform_bus_create()函数创建platform device。为了理解其实现过程,通过printk增加了部分调试日志,代码如下:

/** * of_platform_bus_create() - Create a device for a node and its children. * @bus: device node of the bus to instantiate * @matches: match table for bus nodes * @lookup: auxdata table for matching id and platform_data with device nodes * @parent: parent for new device, or NULL for top level. * @strict: require compatible property * * Creates a platform_device for the provided device_node, and optionally * recursively create devices for all the child nodes. */static int of_platform_bus_create(struct device_node *bus,                  const struct of_device_id *matches,                  const struct of_dev_auxdata *lookup,                  struct device *parent, bool strict){    ...    printk(KERN_ERR"--- name %s \n",bus->name);        //1.判断是否有compatible属性,没有则返回    /* Make sure it has a compatible property */    if (strict && (!of_get_property(bus, "compatible", NULL))) {        printk(KERN_ERR"--- %s() - skipping %s, no compatible prop\n",             __func__, bus->full_name);        return 0;    }    ...    //2.创建platform device    dev = of_platform_device_create_pdata(bus, bus_id, platform_data, parent);    if (!dev || !of_match_node(matches, bus)) {        printk(KERN_ERR"--- no match node\n");        return 0;    }    //3.遍历子节点。如果存在,则创建platform device    for_each_child_of_node(bus, child) {        printk(KERN_ERR"---   create child: %s\n", child->full_name);        rc = of_platform_bus_create(child, matches, lookup, &dev->dev, strict);        if (rc) {            of_node_put(child);            break;        }    }    of_node_set_flag(bus, OF_POPULATED_BUS);    return rc;}

更新内核映像后,截取了部分内核启动日志,如下:

[    0.326151] --- name syscon[    0.326311] ---   create child: /syscon@ff770000/io-domains[    0.326318] --- name io-domains[    0.326458] --- no match node[    0.326466] ---   create child: /syscon@ff770000/usb2-phy@e450[    0.326472] --- name usb2-phy[    0.326627] --- no match node[    0.326635] ---   create child: /syscon@ff770000/usb2-phy@e460[    0.326641] --- name usb2-phy[    0.326791] --- no match node[    0.326798] ---   create child: /syscon@ff770000/phy@f780[    0.326804] --- name phy[    0.326958] --- no match node[    0.326965] ---   create child: /syscon@ff770000/mipi-dphy-rx0[    0.326972] --- name mipi-dphy-rx0[    0.327113] --- no match node[    0.327120] ---   create child: /syscon@ff770000/pvtm[    0.327126] --- name pvtm[    0.327291] --- no match node...                                              ## 省略部分log[    0.330604] --- name display-subsystem        ## drm[    0.330742] --- no match node...

上述日志中的节点名称bus->name和子节点名称child->full_name可在arch/arm64/boot/dts/rockchip/rk3399.dtsi文件中查到:

    grf: syscon@ff770000 {                        ## syscon对应节点名        compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd";        reg = <0x0 0xff770000 0x0 0x10000>;        #address-cells = <1>;        #size-cells = <1>;        io_domains: io-domains {            compatible = "rockchip,rk3399-io-voltage-domain";            status = "disabled";        };        u2phy0: usb2-phy@e450 {                     ## usb2-phy@e450对应子节点名            compatible = "rockchip,rk3399-usb2phy";            reg = <0xe450 0x10>;            clocks = <&cru SCLK_USB2PHY0_REF>;            clock-names = "phyclk";            #clock-cells = <0>;            clock-output-names = "clk_usbphy0_480m";            status = "disabled";            ...        }    }    ...    display_subsystem: display-subsystem {          ## display-subsystem 对应节点名        compatible = "rockchip,display-subsystem";        ports = <&vopl_out>, <&vopb_out>;        clocks = <&cru PLL_VPLL>, <&cru PLL_CPLL>;        clock-names = "hdmi-tmds-pll", "default-vop-pll";        devfreq = <&dmc>;        status = "disabled";    };

在系统启动后,可以在/sys/firmware/devicetree/base路径下查看dts文件节点,在/sys/devices/platform路径下查看platform device

root@linaro-alip:/sys/firmware/devicetree/base# ls syscon@ff770000/#address-cells  compatible  mipi-dphy-rx0  phandle   pvtm  usb2-phy@e450#size-cells     io-domains  name           phy@f780  reg   usb2-phy@e460root@linaro-alip:/sys/firmware/devicetree/base# ls display-subsystem/clock-names  compatible  logo-memory-region  phandle  routeclocks       devfreq     name                ports    statusroot@linaro-alip:/sys/firmware/devicetree/base#
root@linaro-alip:/sys/devices/platform# ls ff770000.syscon/driver_override                ff770000.syscon:usb2-phy@e460/ff770000.syscon:io-domains/    modaliasff770000.syscon:mipi-dphy-rx0/ of_node/ff770000.syscon:phy@f780/      power/ff770000.syscon:pvtm/          subsystem/ff770000.syscon:usb2-phy@e450/ ueventroot@linaro-alip:/sys/devices/platform# ls display-subsystem/driver           drm       modalias  power      ueventdriver_override  graphics  of_node   subsyste

感谢各位的阅读,以上就是“Linux内核Device Tree怎么创建”的内容了,经过本文的学习后,相信大家对Linux内核Device Tree怎么创建这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/113126.html

(0)

相关推荐

  • 丽江到香格里拉要多久,丽江古城去香格里拉怎么坐车

    技术丽江到香格里拉要多久,丽江古城去香格里拉怎么坐车丽江古城到香格里拉大概有200公里左右丽江到香格里拉要多久,最方便的到达和游玩方式是乘坐旅游专线车,旅游专线车有只发香格里拉的,有中停游玩上虎跳峡,有中停游玩中虎跳峡的

    生活 2021年10月24日
  • mshflexgrid数据表格怎样绑定数据库

    技术mshflexgrid数据表格怎样绑定数据库这篇文章将为大家详细讲解有关mshflexgrid数据表格怎样绑定数据库,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。ms

    攻略 2021年12月1日
  • 愀怎么读,afternoon怎么读音发音

    技术愀怎么读,afternoon怎么读音发音afternoon 的读音愀怎么读:[ˌɑːftəˈnuːn] 具体解析: afternoon
    英文发音:[ˌɑːftəˈnuːn]
    中文释义:n.下午(中午12点至下午6

    生活 2021年10月21日
  • 短时间复习通过2021上半年软考软件设计师,附资料)

    技术短时间复习通过2021上半年软考软件设计师,附资料) 短时间复习通过2021上半年软考软件设计师(附资料)距离2021上半年软件设计师考试已经过了好几个月了,这么久才来发这篇文章,惭愧惭愧
    考试的目

    礼包 2021年12月5日
  • 如何买到便宜机票,怎么样才能买到最便宜的机票

    技术如何买到便宜机票,怎么样才能买到最便宜的机票你可以在自己附近的售票点买票如何买到便宜机票,票大付款是很安全的~ 如果订的是电子客票,你可以让给你出票的地方帮你先占座~然后让他们给你个记录编码。你去信天游这个网站查询编

    生活 2021年10月26日
  • 如何使用Hadoop进行分布式并行编程

    技术如何使用Hadoop进行分布式并行编程小编给大家分享一下如何使用Hadoop进行分布式并行编程,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧

    攻略 2021年12月4日