devicetree kernel internals and practical troubleshooting
play

devicetree: kernel internals and practical troubleshooting There - PowerPoint PPT Presentation

devicetree: kernel internals and practical troubleshooting There have been many presentations on what a devicetree looks like and how to create a devicetree. This talk instead examines how the Linux kernel uses a devicetree. Topics include


  1. devicetree: kernel internals and practical troubleshooting There have been many presentations on what a devicetree looks like and how to create a devicetree. This talk instead examines how the Linux kernel uses a devicetree. Topics include the kernel devicetree framework, device creation, resource allocation, driver binding, and connecting objects. Troubleshooting will consider initialization, allocation, and binding ordering; kernel configuration; and driver problems. Frank Rowand, Sony Mobile Communications August 22, 2014 140821_1927

  2. CAUTION The material covered in this presentation is kernel version specific Most information describes 3.16 or earlier In cases where arch specific code is involved, there will be a bias to looking at arch/arm/

  3. Chapter 1 Device tree

  4. what is device tree? “A device tree is a tree data structure with nodes that describe the devices in a system. Each node has property/value pairs that describe the characteristics of the device being represented. Each node has exactly one parent except for the root node, which has no parent.” (ePAPR v1.1)

  5. what is device tree? “A device tree is a tree data structure with nodes that describe the devices in a system. Each node has property/value pairs that describe the characteristics of the device being represented. Each node has exactly one parent except for the root node, which has no parent.” (ePAPR v1.1) A device tree describes hardware that can not be located by probing.

  6. DT data life cycle (source) .dts

  7. .dts - device tree source file / { /* incomplete .dts example */ model = "Qualcomm APQ8074 Dragonboard"; compatible = "qcom,apq8074-dragonboard"; interrupt-parent = <&intc>; soc: soc { ranges; compatible = "simple-bus"; intc: interrupt-controller@f9000000 { compatible = "qcom,msm-qgic2"; interrupt-controller; reg = <0xf9000000 0x1000>, <0xf9002000 0x1000>; console: serial@f991e000 { compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; reg = <0xf991e000 0x1000>; interrupts = <0 108 0x0>; };

  8. .dts - device tree source file Thomas Pettazzoni's ELC 2014 talk “Device Tree For Dummies” is an excellent introduction to - device tree source - boot loader mechanisms - much more! http://elinux.org/images/f/f9/ Petazzoni-device-tree-dummies_0.pdf

  9. .dts - device tree source file / { /* incomplete .dts example */ <--- root node model = "Qualcomm APQ8074 Dragonboard"; <--- property compatible = "qcom,apq8074-dragonboard"; <--- property interrupt-parent = <&intc>; <--- property, phandle soc: soc { <--- node ranges; <--- property compatible = "simple-bus"; <--- property intc: interrupt-controller@f9000000 { <--- node, phandle compatible = "qcom,msm-qgic2"; <--- property interrupt-controller; <--- property reg = <0xf9000000 0x1000>, <--- property <0xf9002000 0x1000>; serial@f991e000 { <--- node compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; reg = <0xf991e000 0x1000>; <--- property interrupts = <0 108 0x0>; <--- property }; }; };

  10. Key vocabulary nodes - the tree structure - contain properties and other nodes properties - data values providing information about a node node '/': property 'compatible' - will be used to match a machine_desc entry other nodes: property 'compatible' - will be used to match a driver

  11. DT data life cycle (source) (compiler) (binary blob) .dts dtc .dtb

  12. DT data life cycle (source) (compiler) (binary blob) .dts dtc .dtb

  13. Binary Blob format A “flat” format Access via serial scan and offsets

  14. Binary Blob format info struct fdt_header offsets to blocks section sizes (free space) memory reservation block {address, size} tuples (free space) nested nodes structure block - name embedded properties nested in nodes - values embedded - names are offsets in 'strings' (free space) property names strings block - null terminated strings - concatenated (free space)

  15. DT data life cycle (source) (compiler) (binary blob) .dts dtc .dtb boot dtb boot vmlinux loader: image: dtb' dtb FDT memory: (flattened device tree)

  16. DT data life cycle (source) (compiler) (binary blob) .dts dtc .dtb boot dtb boot vmlinux loader: image: dtb' dtb FDT memory: (flattened device linux tree) kernel

  17. Flattened Device Tree format A “flat” format. Access via serial scan and offsets using fdt_*() functions.

  18. DT data life cycle (source) (compiler) (binary blob) .dts dtc .dtb boot dtb boot vmlinux loader: image: dtb' dtb FDT memory: (flattened device linux tree) kernel expanded DT

  19. Expanded format A “tree” data structure Access and modified via tree operations using of_*() functions Access all nodes via a linked list Created during boot Nodes and properties can be added or deleted after boot

  20. Expanded format tree of struct device_node struct device_node { const char *name; const char *type; phandle phandle; const char *full_name; struct property *properties; struct property *deadprops; struct device_node *parent; struct device_node *child; struct device_node *sibling; struct device_node *next; struct device_node *allnext; struct kobject kobj; unsigned long _flags; void *data; #if defined(CONFIG_SPARC) ... #endif };

  21. Expanded format tree of struct device_node struct device_node { struct property *properties; struct device_node *parent; struct device_node *child; struct device_node *sibling; struct device_node *allnext; };

  22. Expanded format tree of struct device_node Tree pointers child pointer sibling pointer

  23. Expanded format tree of struct device_node of_allnodes child sibling

  24. Expanded format tree of struct device_node Tree pointers child pointer sibling pointer Used to find node by tree search of_find_node_by_path()

  25. Expanded format tree of struct device_node Global linked list pointer allnext pointer

  26. Expanded format tree of struct device_node child sibling allnext

  27. allnext linked list Follows a depth first traversal of the tree After boot: YES After dynamic node addition: NO To be safe, think of allnext as a randomly ordered linked list of all nodes.

  28. allnext linked list - internal usage Common pattern: of_find_by_XXX(struct device node *from, …) { np = from ? from->allnext : of_allnodes; for (; np; np = np->allnext) … If 'from' is NULL then search from of_allnodes, else search from a specific starting point

  29. allnext linked list - internal usage Find nodes by attribute struct device_node { const char *name; const char *type; phandle phandle; const char *full_name;

  30. allnext linked list - internal usage Find nodes by attribute of_find_node_by_name (*from, …) of_find_node_by_type (*from, …) of_find_node_by_phandle (handle) handle is unique, so *from not needed of_find_node_with_property (*from, …) traverse allnext and properties

  31. allnext linked list Properties 'name' and 'device_type' are special. memory { device_type = "memory"; reg = <0 0>; }; In addition to existing on the node's properties list, these properties are hoisted into: device_node.name device_node.type

  32. Expanded format tree of struct device_node parent pointer

  33. Expanded format tree of struct device_node parent child sibling allnext

  34. Expanded format tree of struct device_node properties pointer struct property { char *name; int length; void *value; struct property *next; unsigned long _flags; unsigned int unique_id; struct bin_attribute attr; };

  35. Expanded format tree of struct device_node child sibling properties next

  36. Chapter 2 Matching boot customization options to the device tree Kernel boot

  37. Linux kernel - machine_desc Boot customizations for different device trees

  38. machine_desc struct machine_desc { unsigned int nr; /* architecture */ const char *name; /* architecture */ unsigned long atag_offset; char *dt_compat; /* 'compatible' strings */ unsigned int nr_irqs; phys_addr_t dma_zone_size; ... enum reboot_mode reboot_mode; unsigned l2c_aux_val; /* L2 cache */ unsigned l2c_aux_mask; /* L2 cache */ ... struct smp_operations *smp; bool (*XXX_init)(); bool (*YYY_init)(); ...

  39. machine_desc - populating #define DT_MACHINE_START(_name, _namestr) \ struct machine_desc __mach_desc_##_name \ __section__(".arch.info.init" = { \ .nr = ~0, \ .name = _namestr, #define MACHINE_END }; * Essential features extracted, actual code is on next slide

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend