Extended Device Tree Blob (DTB) library and DT Selection library for Qualcomm platforms, built on top of libfdt.
This project provides enhanced DTB manipulation capabilities and device tree selection functionality for Qualcomm platforms, supporting device tree creation, parsing, modification, property operations, node management, overlay merging, and intelligent DTB/DTBO selection. It runs on Qualcomm® Snapdragon™ processor platforms.
DTFramework/
├── libs/ # Library implementations
│ ├── DTBExtnLib/ # Extended DTB library
│ │ ├── create-dtb-apis.h # DTB creation API header
│ │ ├── DTBExtnLib_env.h # Environment configuration header
│ │ ├── DTBInternals.h # Internal definitions header
│ │ ├── DTBExtnLib_blob.c # Blob management functions
│ │ ├── DTBExtnLib_create-dtb.c # DTB creation functions
│ │ ├── DTBExtnLib_driver.c # Driver-related functions
│ │ ├── DTBExtnLib_node.c # Node operation functions
│ │ ├── DTBExtnLib_overlay.c # Overlay merge functions
│ │ └── DTBExtnLib_prop.c # Property operation functions
│ ├── DTSelectLib/ # DT Selection library
│ │ ├── dt_select_internal.h # Internal definitions
│ │ ├── dt_select.c # DT selection algorithm
│ │ ├── get_dt.c # Wrapper APIs for DT selection
│ │ └── Environment/ # Environment-specific implementations
│ │ ├── dt_select_env.h # Environment configuration
│ │ ├── dt_select_env.c # Environment wrapper functions
│ │ └── README.txt # Library documentation
│ └── libfdt/ # libfdt library (Git submodule)
│ └── [pylibfdt source] # From https://github.com/devicetree-org/pylibfdt.git
├── inc/ # Public API headers
│ ├── DTBExtnLib.h # DTB extension library API
│ ├── dt_select.h # DT selection library API
│ └── get_dt.h # DT selection wrapper API
├── settings/ # Device tree source files
│ ├── *.dts # Device tree source files
│ ├── *.dtsi # Device tree source include files
│ └── *.yaml # YAML configuration files
├── tools/ # Utility tools
│ └── parse_dtb_log_script.py # DTB log parsing script
├── .gitmodules # Git submodule configuration
├── CODE-OF-CONDUCT.md # Code of Conduct
├── CONTRIBUTING.md # Contribution guidelines
├── LICENSE.txt # BSD-3-Clause License
├── README.md # This file
└── SECURITY.md # Security policy
main: Primary development branch. Contributors should develop submissions based on this branch and submit pull requests to this branch.
Enhanced DTB manipulation library providing comprehensive device tree operations.
fdt_check_for_valid_blob()- Validate DTB blob integrityfdt_set_blob_handle()- Set blob handlefdt_get_blob_handle()- Get blob handlefdt_get_blob_size()- Get blob sizefdt_init_root_handle_for_driver()- Initialize root handle for driverfdt_init_root_handle_for_driver_by_id()- Initialize root handle for driver by ID
fdt_add_tree()- Create a new empty device treefdt_add_node()- Create a new nodefdt_add_prop_list_u8()- Add u8 type property listfdt_add_prop_list_u16()- Add u16 type property listfdt_add_prop_list_u32()- Add u32 type property listfdt_add_prop_list_u64()- Add u64 type property listfdt_add_prop_list_string()- Add string type property list
fdt_get_next_node_handle_for_compatible()- Get next node handle by compatible propertyfdt_get_name_index()- Get name indexfdt_get_reg()- Get reg property
fdt_get_node_handle()- Get node handlefdt_get_phandle_node()- Get node by phandlefdt_get_parent_node()- Get parent nodefdt_node_cmp()- Compare nodesfdt_node_copy()- Copy nodefdt_get_prop_values_size_of_node()- Get node property values sizefdt_get_prop_values_of_node()- Get node property valuesfdt_get_count_of_subnodes()- Get subnode countfdt_get_subnode_names()- Get subnode namesCreatDtbHashTable()- Create DTB hash table for fast lookup
fdt_merge_overlay()- Merge primary DTB and overlay DTB
fdt_get_prop_size()- Get property sizefdt_get_uint8_prop()/fdt_get_uint8_prop_list()- Get u8 propertiesfdt_get_uint16_prop()/fdt_get_uint16_prop_list()- Get u16 propertiesfdt_get_uint32_prop()/fdt_get_uint32_prop_list()- Get u32 propertiesfdt_get_uint64_prop()/fdt_get_uint64_prop_list()- Get u64 propertiesfdt_get_boolean_prop()/fdt_get_bool_prop()- Get boolean propertiesfdt_get_string_prop_list()- Get string property list
Intelligent device tree selection library that automatically selects the best matching DTB and DTBOs based on platform information.
dt_select_open()- Parse DTB/DTBO image and select best matching blobsdt_select_read_blob()- Read selected DTB/DTBO blobdt_select_close()- Close DT selection handle
get_dt()- High-level API to get final DTB with overlays appliedget_dt_free()- Free DTB memory allocated by get_dt()
The DT selection algorithm selects the best matching DTB and DTBOs based on:
- Chip Information: Chip family, ID, major/minor version
- Platform Information: Platform type, subtype, major/minor version
- OEM Variant: OEM-specific variant identifier
- Compatible Strings: Device tree compatible property matching
- Custom Properties: User-defined property matching
- Base DTB Selection: Selects base DTB with matching chip family and version 1.0
- SOC DTBO Selection: Selects SOC overlay based on chip ID and version ranking
- Platform DTBO Selection: Selects platform overlay based on platform type, subtype, chip ID, and version ranking
This library supports the following target platforms and architectures:
- TARGET_UEFI - UEFI environment
- TARGET_XBL - XBL (eXtensible Boot Loader) environment
- PORT_ARMv8 - ARMv8 architecture
- PORT_Q6 - Qualcomm Hexagon DSP
- Qualcomm platform SDK (select appropriate version based on target platform)
- Supported build environments:
- UEFI development environment (for UEFI targets)
- XBL development environment (for XBL targets)
- Hexagon SDK (for Q6 targets)
- Device Tree Compiler (dtc) - for DTB file processing
This project uses Git submodules to manage the libfdt dependency. Clone the repository with submodules:
git clone --recurse-submodules https://github.com/qualcomm/DTFramework.git
cd DTFrameworkIf you've already cloned the repository without submodules, initialize them:
git submodule update --init --recursiveThe libs/libfdt/ directory is a Git submodule that references the pylibfdt project:
- Repository: https://github.com/devicetree-org/pylibfdt.git
- Purpose: Provides the underlying libfdt library for device tree manipulation
IMPORTANT: Only include header files (.h) in your code, never include source files (.c).
#include "DTBExtnLib.h" // For DTB manipulation APIs
#include "create-dtb-apis.h" // For DTB creation APIsAdd libs/DTBExtnLib/ directory to your compiler's include path and compile all .c files in libs/DTBExtnLib/ as part of your build.
#include "dt_select.h" // For DT selection APIs
#include "get_dt.h" // For high-level wrapper APIsAdd inc/ and libs/DTSelectLib/ directories to your compiler's include path and compile all .c files in libs/DTSelectLib/ (including Environment/ subdirectory) as part of your build.
#include "create-dtb-apis.h"
fdt_node_handle node;
int offset;
// Create a new device tree with 4096 bytes
fdt_add_tree(&node, 4096);
// Add a new node
fdt_add_node(&node, "/soc/device@0", &offset);
// Add properties
uint32_t reg_values[] = {0x1000, 0x100};
fdt_add_prop_list_u32(&node, "reg", reg_values, 2);
char *compatible = "vendor,device";
fdt_add_prop_list_string(&node, "compatible", compatible, strlen(compatible) + 1);#include "DTBExtnLib.h"
fdt_node_handle node;
uint32_t value;
int ret;
// Get node handle
ret = fdt_get_node_handle(&node, "/soc/device@0");
// Read u32 property
ret = fdt_get_uint32_prop(&node, "reg", &value);
// Read string property
char compatible[64];
ret = fdt_get_string_prop_list(&node, "compatible", compatible, sizeof(compatible));#include "DTBExtnLib.h"
void *primary_blob; // Primary DTB
void *overlay_blob; // Overlay DTB
void *merge_blob; // Merged DTB
size_t pb_size, ob_size, mb_size;
// Merge overlay into primary DTB
int ret = fdt_merge_overlay(primary_blob, pb_size,
overlay_blob, ob_size,
merge_blob, mb_size);#include "dt_select.h"
uintptr_t handle;
uintptr_t dtbs_image_addr = /* address of appended DTB/DTBO image */;
size_t dtbs_image_size = /* size of image */;
size_t base_dtb_size, soc_dtbo_size, plat_dtbo_size;
// Setup chip and platform information
chip_plat_info_property chip_plat_info = {
.chip_family = 0x1234,
.chip_id = 0x5678,
.chip_maj_version = 1,
.chip_min_version = 0,
.platform_type = 0x01,
.platform_subtype = 0x02,
.platform_maj_version = 1,
.platform_min_version = 0,
.oem_var = 0,
.dtb_compatible_string_starts_with = "qcom,",
.soc_dtbo_compatible_string_starts_with = "qcom,soc-",
.plat_dtbo_compatible_string_starts_with = "qcom,board-"
};
// Open and select DTB/DTBOs
int ret = dt_select_open(&handle, dtbs_image_addr, dtbs_image_size,
&chip_plat_info, NULL, 0,
&base_dtb_size, &soc_dtbo_size, &plat_dtbo_size);
// Read selected base DTB
uintptr_t base_dtb_ptr = 0;
ret = dt_select_read_blob(handle, BASE_DTB, &base_dtb_ptr, base_dtb_size);
// Close handle
dt_select_close(handle);#include "get_dt.h"
uintptr_t dtbs_image_addr = /* address of appended DTB/DTBO image */;
size_t dtbs_image_size = /* size of image */;
uintptr_t final_dtb_addr;
size_t final_dtb_size;
// Setup chip and platform information
chip_plat_info_property chip_plat_info = {
.chip_family = 0x1234,
.chip_id = 0x5678,
.chip_maj_version = 1,
.chip_min_version = 0,
.platform_type = 0x01,
.platform_subtype = 0x02,
.platform_maj_version = 1,
.platform_min_version = 0,
.oem_var = 0,
.dtb_compatible_string_starts_with = "qcom,",
.soc_dtbo_compatible_string_starts_with = "qcom,soc-",
.plat_dtbo_compatible_string_starts_with = "qcom,board-"
};
// Get final DTB with all overlays applied
int ret = get_dt(dtbs_image_addr, dtbs_image_size,
&chip_plat_info, NULL, 0,
&final_dtb_addr, &final_dtb_size, POST);
// Use the final DTB...
// Free memory when done
get_dt_free(final_dtb_addr, final_dtb_size);- High-Performance Node Lookup: Uses hash tables for fast node lookup
- Type-Safe Property Operations: Provides typed property read/write APIs
- Overlay Support: Supports DTB overlay merge operations
- Multi-Platform Support: Supports UEFI, XBL, ARMv8, and Hexagon DSP platforms
- Debug Support: Configurable logging and debug functionality
- Memory Management: Optimized memory allocation and caching mechanisms
- Intelligent Selection: Automatically selects best matching DTB and DTBOs
- Ranking Algorithm: Uses sophisticated ranking based on chip/platform versions
- Flexible Matching: Supports chip family, ID, platform type/subtype matching
- OEM Variant Support: Handles OEM-specific device tree variants
- Compatible String Matching: Supports compatible property prefix matching
- Custom Property Matching: Allows user-defined property matching criteria
- Automatic Overlay Application: Applies SOC and platform overlays automatically
Define appropriate macros based on target platform during compilation:
# UEFI platform
-DTARGET_UEFI
# XBL platform
-DTARGET_XBL
# ARMv8 architecture
-DPORT_ARMv8
# Hexagon DSP
-DPORT_Q6
# Enable debug output
-DINSTRUMENTATION
# Enable hash table for fast node lookup (recommended for large device trees)
-DENABLE_HASH_FOR_DTB
# Enable double hash to reduce hash collisions (optional, requires ENABLE_HASH_FOR_DTB)
# -DENABLE_DOUBLE_HASH_FOR_DTB
# Enable DTB profiling for performance analysis (optional)
# -DENABLE_DTB_PROFILING# Enable DT selection logging
-DDT_SELECT_LOGGING_ENABLE
# Build for x86 (for testing/simulation)
-DBUILD_X86When ENABLE_HASH_FOR_DTB is defined, the library automatically creates a hash table to significantly improve node lookup performance:
- Performance: Dramatically reduces node search time, especially beneficial for large device trees
- Algorithm: Uses DJB2 hash algorithm for fast hash computation
- Memory: Requires additional memory (~40 bytes per node) to store hash table entries
- Automatic Creation: Hash table is automatically built when calling
fdt_set_blob_handle() - Phandle Cache: Also creates a phandle-to-node-offset cache for faster phandle lookups
Optional enhancements:
ENABLE_DOUBLE_HASH_FOR_DTB: Adds FNV-64 as a second hash function to reduce collision probability (requiresENABLE_HASH_FOR_DTB)ENABLE_DTB_PROFILING: Enables performance profiling to analyze hash table efficiency and node access patterns
Example:
#include "DTBExtnLib.h"
void *dtb_blob;
size_t blob_size;
int blob_id = 0;
// Set blob handle - hash table is automatically created if ENABLE_HASH_FOR_DTB is defined
int ret = fdt_set_blob_handle(dtb_blob, blob_size, blob_id);
if (ret == FDT_ERR_QC_NOERROR) {
// Blob handle set successfully
// Hash table has been created automatically
// Subsequent node lookups will be much faster
}Note: Hash table creation is automatic and happens once per DTB when setting the blob handle. For merged DTBs, the hash table will be automatically disabled to avoid conflicts.
We welcome contributions to this project! Please follow these steps:
- Read our Code of Conduct and License
- Fork and clone the repository
- Create a new branch based on
main - Make your changes and ensure they follow the coding standards
- Commit your changes using the DCO with
-sor--signoffoption - Push to your fork and submit a pull request
For detailed contribution guidelines, please see CONTRIBUTING.md.
- Follow existing code style
- All public APIs must have complete documentation comments
- Use provided error checking macros (PTR_CHECK, BLOBID_CHECK, etc.)
- Ensure code compiles without warnings before submitting
All pull requests from external contributors are automatically scanned using Semgrep to detect insecure coding patterns and potential security flaws. Contributors are expected to resolve any flagged issues before the PR can be merged.
The library uses standard FDT error codes and extends them with the following Qualcomm-specific error codes:
FDT_ERR_QC_NULLPTR- Null pointer errorFDT_ERR_QC_BLOBID- Invalid blob IDFDT_ERR_QC_FDTLIB_ERROR- FDT library error
SUCCESS(0) - Operation successfulFAIL(-1) - General failureMALLOC_FAIL(-2) - Memory allocation failedINVALID_PARAMETER(-3) - Invalid parameterGET_DT_ERR_NONE(0) - No errorGET_DT_ERR_INVALID_PARAMETER(1) - Invalid parameterGET_DT_ERR_HANDLE_RETURN_ERROR(2) - Handle return errorGET_DT_ERR_INVALID_BASE_DTB_SIZE(3) - Invalid base DTB sizeGET_DT_ERR_MALLOC_FAIL(4) - Memory allocation failedGET_DT_ERR_SIZE_OVERFLOW(5) - Size overflowGET_DT_ERR_INVALID_BASE_DTB_PTR(6) - Invalid base DTB pointer
The settings/ directory is designed to store device tree source files and configuration files:
- DTS Files (*.dts): Device tree source files that describe hardware configurations
- DTSI Files (*.dtsi): Device tree source include files that can be shared across multiple DTS files
- YAML Files (*.yaml): YAML configuration files for device tree generation or validation
These files can be compiled into DTB (Device Tree Blob) files using the Device Tree Compiler (dtc) and then processed by DTFramework libraries.
Python script for parsing and analyzing DTB Enable hash table and enable ENABLE_DTB_PROFILING logs.
For questions or suggestions, please contact us through:
For reporting security vulnerabilities, please see SECURITY.md. You can also contact our Product Security team.
DTFramework is licensed under the BSD-3-Clause Clear License. See LICENSE.txt for the full license text.
This project is built on top of libfdt from the pylibfdt project. We thank all contributors who have helped make this project better.
- Device Tree Compiler (dtc): https://github.com/dgibson/dtc - Official device tree compiler and libfdt
Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.