pgsphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/devicetree/of_unittestmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/zh_TW/devicetree/of_unittestmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/it_IT/devicetree/of_unittestmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/ja_JP/devicetree/of_unittestmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/ko_KR/devicetree/of_unittestmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget*/translations/sp_SP/devicetree/of_unittestmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageChinese (Simplified)uh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhW/var/lib/git/docbuild/linux/Documentation/translations/zh_CN/devicetree/of_unittest.rsthKubhnote)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]h paragraph)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hh5Documentation/translations/zh_CN/disclaimer-zh_CN.rsthKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhKubh field_body)}(h)Documentation/devicetree/of_unittest.rst h]h)}(h(Documentation/devicetree/of_unittest.rsth]h(Documentation/devicetree/of_unittest.rst}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h翻译h]h翻译}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhKubh)}(h-司延腾 Yanteng Si h]h)}(h,司延腾 Yanteng Si h](h司延腾 Yanteng Si <}(hj hhhNhNubh reference)}(hsiyanteng@loongson.cnh]hsiyanteng@loongson.cn}(hj*hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:siyanteng@loongson.cnuh1j(hj ubh>}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhj ubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h校译h]h校译}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1hhjPhhhKubh)}(hhh]h}(h]h ]h"]h$]h&]uh1hhjPubeh}(h]h ]h"]h$]h&]uh1hhhhK hhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhsection)}(hhh](htitle)}(h%Open Firmware Devicetree 单元测试h]h%Open Firmware Devicetree 单元测试}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1j{hjxhhhhhKubh)}(h4作者: Gaurav Minocha h](h作者: Gaurav Minocha <}(hjhhhNhNubj))}(hgaurav.minocha.os@gmail.comh]hgaurav.minocha.os@gmail.com}(hjhhhNhNubah}(h]h ]h"]h$]h&]refuri"mailto:gaurav.minocha.os@gmail.comuh1j(hjubh>}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjxhhubjw)}(hhh](j|)}(h 1. 概述h]h 1. 概述}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j{hjhhhhhKubh)}(h本文档解释了执行 OF 单元测试所需的测试数据是如何动态地附加到实时树上的,与机器的架构无关。h]h本文档解释了执行 OF 单元测试所需的测试数据是如何动态地附加到实时树上的,与机器的架构无关。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h9建议在继续读下去之前,先阅读以下文件。h]h9建议在继续读下去之前,先阅读以下文件。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubhenumerated_list)}(hhh](h list_item)}(h(Documentation/devicetree/usage-model.rsth]h)}(hjh]h(Documentation/devicetree/usage-model.rst}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(h,http://www.devicetree.org/Device_Tree_Usage h]h)}(h+http://www.devicetree.org/Device_Tree_Usageh]j))}(hjh]h+http://www.devicetree.org/Device_Tree_Usage}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]enumtypearabicprefix(suffix)uh1jhjhhhhhKubh)}(hOF Selftest被设计用来测试提供给设备驱动开发者的接口(include/linux/of.h),以从未扁平 化的设备树数据结构中获取设备信息等。这个接口被大多数设备驱动在各种使用情况下使用。h]hOF Selftest被设计用来测试提供给设备驱动开发者的接口(include/linux/of.h),以从未扁平 化的设备树数据结构中获取设备信息等。这个接口被大多数设备驱动在各种使用情况下使用。}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]id1ah ]h"] 1. 概述ah$]h&]uh1jvhjxhhhhhKubjw)}(hhh](j|)}(h2. 测试数据h]h2. 测试数据}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1j{hj<hhhhhK!ubh)}(h设备树源文件(drivers/of/unittest-data/testcases.dts)包含执行drivers/of/unittest.c 中自动化单元测试所需的测试数据。目前,以下设备树源包含文件(.dtsi)被包含在testcases.dt中::h]h设备树源文件(drivers/of/unittest-data/testcases.dts)包含执行drivers/of/unittest.c 中自动化单元测试所需的测试数据。目前,以下设备树源包含文件(.dtsi)被包含在testcases.dt中:}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK#hj<hhubh literal_block)}(hdrivers/of/unittest-data/tests-interrupts.dtsi drivers/of/unittest-data/tests-platform.dtsi drivers/of/unittest-data/tests-phandle.dtsi drivers/of/unittest-data/tests-match.dtsih]hdrivers/of/unittest-data/tests-interrupts.dtsi drivers/of/unittest-data/tests-platform.dtsi drivers/of/unittest-data/tests-phandle.dtsi drivers/of/unittest-data/tests-match.dtsi}hj]sbah}(h]h ]h"]h$]h&]hhuh1j[hhhK&hj<hhubh)}(hZ当内核在启用CONFIG_OF_UNITTEST的情况下被构建时,那么下面的make规则::h]hY当内核在启用CONFIG_OF_UNITTEST的情况下被构建时,那么下面的make规则:}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK+hj<hhubj\)}(hD$(obj)/%.dtb: $(src)/%.dts FORCE $(call if_changed_dep, dtc)h]hD$(obj)/%.dtb: $(src)/%.dts FORCE $(call if_changed_dep, dtc)}hjysbah}(h]h ]h"]h$]h&]hhuh1j[hhhK-hj<hhubh)}(hp用于将DT源文件(testcases.dts)编译成二进制blob(testcases.dtb),也被称为扁平化的DT。h]hp用于将DT源文件(testcases.dts)编译成二进制blob(testcases.dtb),也被称为扁平化的DT。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK0hj<hhubh)}(hc之后,使用以下规则将上述二进制blob包装成一个汇编文件(testcases.dtb.S)::h]hb之后,使用以下规则将上述二进制blob包装成一个汇编文件(testcases.dtb.S):}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK2hj<hhubj\)}(h:$(obj)/%.dtb.S: $(obj)/%.dtb $(call cmd, dt_S_dtb)h]h:$(obj)/%.dtb.S: $(obj)/%.dtb $(call cmd, dt_S_dtb)}hjsbah}(h]h ]h"]h$]h&]hhuh1j[hhhK4hj<hhubh)}(hc汇编文件被编译成一个对象文件(testcases.dtb.o),并被链接到内核镜像中。h]hc汇编文件被编译成一个对象文件(testcases.dtb.o),并被链接到内核镜像中。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK7hj<hhubjw)}(hhh](j|)}(h2.1. 添加测试数据h]h2.1. 添加测试数据}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j{hjhhhhhK;ubh)}(h"未扁平化的设备树结构体:h]h"未扁平化的设备树结构体:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK=hjhhubh)}(h\未扁平化的设备树由连接的设备节点组成,其树状结构形式如下所述::h]h[未扁平化的设备树由连接的设备节点组成,其树状结构形式如下所述:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK?hjhhubj\)}(h// following struct members are used to construct the tree struct device_node { ... struct device_node *parent; struct device_node *child; struct device_node *sibling; ... };h]h// following struct members are used to construct the tree struct device_node { ... struct device_node *parent; struct device_node *child; struct device_node *sibling; ... };}hjsbah}(h]h ]h"]h$]h&]hhuh1j[hhhKAhjhhubh)}(hXz图1描述了一个机器的未扁平化设备树的通用结构,只考虑了子节点和同级指针。存在另一个指针, ``*parent`` ,用于反向遍历该树。因此,在一个特定的层次上,子节点和所有的兄弟姐妹节点将 有一个指向共同节点的父指针(例如,child1、sibling2、sibling3、sibling4的父指针指向 根节点)::h](h图1描述了一个机器的未扁平化设备树的通用结构,只考虑了子节点和同级指针。存在另一个指针, }(hjhhhNhNubhliteral)}(h ``*parent``h]h*parent}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh ,用于反向遍历该树。因此,在一个特定的层次上,子节点和所有的兄弟姐妹节点将 有一个指向共同节点的父指针(例如,child1、sibling2、sibling3、sibling4的父指针指向 根节点):}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKJhjhhubj\)}(hXroot ('/') | child1 -> sibling2 -> sibling3 -> sibling4 -> null | | | | | | | null | | | | | child31 -> sibling32 -> null | | | | | | null null | | | child21 -> sibling22 -> sibling23 -> null | | | | | null null null | child11 -> sibling12 -> sibling13 -> sibling14 -> null | | | | | | | null | | | null null child131 -> null | nullh]hXroot ('/') | child1 -> sibling2 -> sibling3 -> sibling4 -> null | | | | | | | null | | | | | child31 -> sibling32 -> null | | | | | | null null | | | child21 -> sibling22 -> sibling23 -> null | | | | | null null null | child11 -> sibling12 -> sibling13 -> sibling14 -> null | | | | | | | null | | | null null child131 -> null | null}hjsbah}(h]h ]h"]h$]h&]hhuh1j[hhhKOhjhhubh)}(h1Figure 1: 未扁平化的设备树的通用结构h]h1Figure 1: 未扁平化的设备树的通用结构}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKehjhhubh)}(h在执行OF单元测试之前,需要将测试数据附加到机器的设备树上(如果存在)。因此,当调用 selftest_data_add()时,首先会读取通过以下内核符号链接到内核镜像中的扁平化设备树 数据::h]h在执行OF单元测试之前,需要将测试数据附加到机器的设备树上(如果存在)。因此,当调用 selftest_data_add()时,首先会读取通过以下内核符号链接到内核镜像中的扁平化设备树 数据:}(hj8hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhjhhubj\)}(h__dtb_testcases_begin - address marking the start of test data blob __dtb_testcases_end - address marking the end of test data blobh]h__dtb_testcases_begin - address marking the start of test data blob __dtb_testcases_end - address marking the end of test data blob}hjFsbah}(h]h ]h"]h$]h&]hhuh1j[hhhKlhjhhubh)}(h其次,它调用of_fdt_unflatten_tree()来解除扁平化的blob。最后,如果机器的设备树 (即实时树)是存在的,那么它将未扁平化的测试数据树附加到实时树上,否则它将自己作为 实时设备树附加。h]h其次,它调用of_fdt_unflatten_tree()来解除扁平化的blob。最后,如果机器的设备树 (即实时树)是存在的,那么它将未扁平化的测试数据树附加到实时树上,否则它将自己作为 实时设备树附加。}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKohjhhubh)}(hattach_node_and_children()使用of_attach_node()将节点附加到实时树上,如下所 述。为了解释这一点,图2中描述的测试数据树被附加到图1中描述的实时树上::h]hattach_node_and_children()使用of_attach_node()将节点附加到实时树上,如下所 述。为了解释这一点,图2中描述的测试数据树被附加到图1中描述的实时树上:}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKshjhhubj\)}(hroot ('/') | testcase-data | test-child0 -> test-sibling1 -> test-sibling2 -> test-sibling3 -> null | | | | test-child01 null null nullh]hroot ('/') | testcase-data | test-child0 -> test-sibling1 -> test-sibling2 -> test-sibling3 -> null | | | | test-child01 null null null}hjpsbah}(h]h ]h"]h$]h&]hhuh1j[hhhKvhjhhubh)}(h:Figure 2: 将测试数据树附在实时树上的例子。h]h:Figure 2: 将测试数据树附在实时树上的例子。}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h根据上面的方案,实时树已经存在,所以不需要附加根('/')节点。所有其他节点都是通过在 每个节点上调用of_attach_node()来附加的。h]h根据上面的方案,实时树已经存在,所以不需要附加根(‘/’)节点。所有其他节点都是通过在 每个节点上调用of_attach_node()来附加的。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXZ在函数of_attach_node()中,新的节点被附在实时树中给定的父节点的子节点上。但是,如 果父节点已经有了一个孩子,那么新节点就会取代当前的孩子,并将其变成其兄弟姐妹。因此, 当测试案例的数据节点被连接到上面的实时树(图1)时,最终的结构如图3所示::h]hXY在函数of_attach_node()中,新的节点被附在实时树中给定的父节点的子节点上。但是,如 果父节点已经有了一个孩子,那么新节点就会取代当前的孩子,并将其变成其兄弟姐妹。因此, 当测试案例的数据节点被连接到上面的实时树(图1)时,最终的结构如图3所示:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj\)}(hXroot ('/') | testcase-data -> child1 -> sibling2 -> sibling3 -> sibling4 -> null | | | | | (...) | | | null | | child31 -> sibling32 -> null | | | | | | null null | | | child21 -> sibling22 -> sibling23 -> null | | | | | null null null | child11 -> sibling12 -> sibling13 -> sibling14 -> null | | | | null null | null | child131 -> null | null ----------------------------------------------------------------------- root ('/') | testcase-data -> child1 -> sibling2 -> sibling3 -> sibling4 -> null | | | | | | (...) (...) (...) null | test-sibling3 -> test-sibling2 -> test-sibling1 -> test-child0 -> null | | | | null null null test-child01h]hXroot ('/') | testcase-data -> child1 -> sibling2 -> sibling3 -> sibling4 -> null | | | | | (...) | | | null | | child31 -> sibling32 -> null | | | | | | null null | | | child21 -> sibling22 -> sibling23 -> null | | | | | null null null | child11 -> sibling12 -> sibling13 -> sibling14 -> null | | | | null null | null | child131 -> null | null ----------------------------------------------------------------------- root ('/') | testcase-data -> child1 -> sibling2 -> sibling3 -> sibling4 -> null | | | | | | (...) (...) (...) null | test-sibling3 -> test-sibling2 -> test-sibling1 -> test-child0 -> null | | | | null null null test-child01}hjsbah}(h]h ]h"]h$]h&]hhuh1j[hhhKhjhhubh)}(h@Figure 3: 附加测试案例数据后的实时设备树结构。h]h@Figure 3: 附加测试案例数据后的实时设备树结构。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX6聪明的读者会注意到,与先前的结构相比,test-child0节点成为最后一个兄弟姐妹(图2)。 在连接了第一个test-child0节点之后,又连接了test-sibling1节点,该节点推动子节点 (即test-child0)成为兄弟姐妹,并使自己成为子节点,如上所述。h]hX6聪明的读者会注意到,与先前的结构相比,test-child0节点成为最后一个兄弟姐妹(图2)。 在连接了第一个test-child0节点之后,又连接了test-sibling1节点,该节点推动子节点 (即test-child0)成为兄弟姐妹,并使自己成为子节点,如上所述。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h如果发现一个重复的节点(即如果一个具有相同full_name属性的节点已经存在于实时树中), 那么该节点不会被附加,而是通过调用函数update_node_properties()将其属性更新到活 树的节点中。h]h如果发现一个重复的节点(即如果一个具有相同full_name属性的节点已经存在于实时树中), 那么该节点不会被附加,而是通过调用函数update_node_properties()将其属性更新到活 树的节点中。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]id3ah ]h"]2.1. 添加测试数据ah$]h&]uh1jvhj<hhhhhK;ubjw)}(hhh](j|)}(h2.2. 删除测试数据h]h2.2. 删除测试数据}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j{hjhhhhhKubh)}(hX=一旦测试用例执行完,selftest_data_remove被调用,以移除最初连接的设备节点(首先是 叶子节点被分离,然后向上移动父节点被移除,最后是整个树)。selftest_data_remove() 调用detach_node_and_children(),使用of_detach_node()将节点从实时设备树上分离。h]hX=一旦测试用例执行完,selftest_data_remove被调用,以移除最初连接的设备节点(首先是 叶子节点被分离,然后向上移动父节点被移除,最后是整个树)。selftest_data_remove() 调用detach_node_and_children(),使用of_detach_node()将节点从实时设备树上分离。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h为了分离一个节点,of_detach_node()要么将给定节点的父节点的子节点指针更新为其同级节 点,要么根据情况将前一个同级节点附在给定节点的同级节点上。就这样吧。 :)h]h为了分离一个节点,of_detach_node()要么将给定节点的父节点的子节点指针更新为其同级节 点,要么根据情况将前一个同级节点附在给定节点的同级节点上。就这样吧。 :)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]id4ah ]h"]2.2. 删除测试数据ah$]h&]uh1jvhj<hhhhhKubeh}(h]id2ah ]h"]2. 测试数据ah$]h&]uh1jvhjxhhhhhK!ubeh}(h]open-firmware-devicetreeah ]h"]%open firmware devicetree 单元测试ah$]h&]uh1jvhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(j{N generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjPerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(j*j'j9j6j"jjjjju nametypes}(j*j9j"jjuh}(j'jxj6jjj<jjjju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}j^KsRparse_messages]transform_messages] transformerN include_log];Documentation/translations/zh_CN/devicetree/of_unittest.rst(NNNNta decorationNhhub.