How To Modify and Use Custom Device Tree with Factory

Summary

This HOWTO covers a two-step process for both modifying the Factory-provided device tree and then integrating the (now) custom device tree with Factory for use in future builds.

NOTE: This HOWTO assumes that the Desktop Factory has been configured and built prior to attempting to modify the device tree. If these Factory configuration and build steps have not been completed yet, please do so before continuing with this HOWTO.

Custom Device Tree use with Factory can be broken up into the following two distinct tasks, each of which is covered within this HOWTO:

  1. Modify Existing dts Files
    1. Modify existing device tree source (dts) files
    2. Rebuild binary device tree blob (dtb)
    3. Deploy new dtb for testing
  2. Integrate Custom dts with Factory
    1. Copy modified dts to local sources directory
    2. Modify workorder to utilize custom dts file
    3. Clean device tree sources
    4. Rebuild device tree and SDK Installer

Note: To use the modified dts with new Factory installations (or to use an existing custom dts), simply follow the steps 2.1 and 2.2 prior to kicking off the BSP/SDK build.

Device Tree Introduction

The Device Tree is a generic term encompassing the components that make up a new method of describing the hardware layout of an embedded system that isn't compiled into the kernel proper. The device tree mechanism aims at replacing conventional board .c files that hard-code the hardware layout for each particular processor and/or board. This was adopted into the mainline kernel due to the growing number of hardware variants for a given processor (e.g. Freescale's i.MX6 processor) and the resulting need for processor/board support in the kernel proper. Using device trees, a single kernel image can be booted along with the appropriate Device Tree Blob (dtb) to adequately describe the hardware layout.

The Device Tree Blob (*.dtb) file is the file that is actually deployed to the hardware at boot time. It is typically loaded by the bootloader along with the kernel image. The machine-readable dtb is generated via compilation of human-readable Device Tree Source (*.dts) and Device Tree Source Include (*.dtsi) files by the Device Tree Compiler (dtc).

Device Tree Sources and Factory

The dts and dtsi files are located within the kernel source tree at arch/[arch]/boot/dts/. This is where the dtc looks for particular .dtsi files included in the .dts, and also where the device tree compilation takes place.

Desktop Factory comes packaged with dts files for board/kernel combinations which support device trees. These can be found in target/configs/kernel/[board]/ - typically named dts-[kernel-version]. It is from here that the appropriate device tree source is copied into the src/dl/k/kernel/kernel-[version]/ directory and then ultimately to the kernel working directory (during the kernel_devicetree-fetch stage of BSP/SDK build) as kernel_devicetree.dts. This renaming of the *.dts file is intentional to eliminate any conflicts (overwriting of or confusion) with existing *.dts files included in the kernel source tree.

Modify Existing dts Files

Modify Existing Device Tree Source (dts) Files

Device tree modifications should start with the existing kernel_devicetree.dts file in the downloaded source files for the kernel (found in the src/dl/k/kernel/kernel-[version]/ directory). For example:

vim src/dl/k/kernel/kernel-3.10/kernel_devicetree.dts

Factory compiles the kernel_devicetree.dts with the dtc built in the Linux kernel source tree near the end of the kernel-build step of the BSP/SDK generation. This action needs to be initiated next.

Rebuild Binary Device Tree Blob (dtb)

Once modifications have been made to the dts, it needs to be recompiled. There are a number of kernel_devicetree-* make targets available within Factory to manipulate the device tree, though to rebuild the dtb, we can simply call the following from the top-level Factory directory:

make kernel_devicetree-host-install

This will propagate modifications to the kernel_devicetree.dts located in src/dl/ to the kernel working directory and recompile the dtb. The resulting kernel_devicetree.dtb is then copied to the Factory images directory for ease of access (build_[arch]-timesys-linux-[libc]/images/). This process renames the dtb as [board].dtb during the copy to the Factory images directory.

Note: The above command will not rebuild the SDK Installer to include the new dtb file. The make installer command run from the top-level Factory directory is necessary to rebuild the SDK Installer and include the newly compiled dtb.

Deploy New dtb for Testing

Once created, the new *.dtb file needs to be copied to the boot media and loaded by the bootloader along with the kernel image. Please refer to the appropriate Board-specific Getting Started Guide for information regarding this step.

Integrate Custom dts with Factory

Once the device tree has been satisfactorily modified and tested, the modifications can be integrated into the Factory BSP/SDK build process. This is accomplished by storing the custom dts in an accessible location, setting Factory to fetch the custom dts, resetting the device tree portion of the build to a pristine state, and rebuilding the SDK Installer. This example illustrates the steps necessary for storing the custom dts in the src/local/ directory for use in the BSP/SDK build; however, it can indeed be located elsewhere on the local development host, on a network-accessible device, or in a SCM system.

Copy Modified dts to Local Sources Directory

Now that the dts has been modified and resulting dtb tested, integration of the custom dts starts by preserving the modifications in a safe location within Factory (source modifications made in the build_*/linux-[VER] directory will be lost during certain cleaning operations). Factory is designed to utilize a specific user-created source directory (src/local/ for custom files to be used during the BSP/SDK build process. Storing your custom dts in this src/local/ directory not only keeps custom files centrally located in Factory (good practice from a maintenance standpoint), but src/local/ is not effected by cleaning operations run within Factory.

The src/local/ directory structure is intended to closely mimic that of the src/dl/ directory after the Factory fetch stage of a BSP/SDK build. Keeping with this convention, the src/local/ directory, along with the expected kernel-related subdirectory structure can be created with one simple command run from the top-level factory directory (replacing [kernel version] with the kernel version specific to your selections):

mkdir -p src/local/k/kernel/kernel-[kernel version]/

and then copying the dts to this new location is as simple as (again, substituting in your build's specific values in place of variables indicated by [square brackets]):

cp build_[arch]-timesys-linux-[libc]/linux-[kernel version]/arch/[arch]/boot/dts/kernel_devicetree.dts src/local/k/kernel/kernel-[kernel version]/

Note: if using an existing custom dts file (not modifying the Factory-supplied dts), be sure to replace the path to the dts file in this command to reflect the location of your custom dts file.

Modify Workorder to Utilize Custom dts File

The dts file Factory uses during the BSP/SDK build is defined within the workorder. It is here that you specify which dts file to fetch and use in generating the dtb for the build. The menuconfig interface can be used to make the change to your custom dts file as such.

  1. Run make menuconfig from the top-level Factory directory
  2. Navigate to Target Software > Kernel > Create Device Tree Blob > Device Tree filename for your board
  3. Modify value to reflect your custom dts file (in our case, this would be file://$(TSWO_SRC_LOCAL_LOCATION)/k/kernel/kernel-[kernel version]/kernel_devicetree.dts)
  4. Exit menuconfig and save the workorder

Note: the $(TSWO_SRC_LOCAL_LOCATION) entered into the workorder in step 3 above evaluates to src/local/ in the top-level Factory directory.

Now that the Factory knows where to find your custom dts file, all that is left to do is clean the device tree sources and rebuild.

Clean Device Tree Sources

In order rebuild the dtb, while having Factory pull your custom dts from the src/local/ directory, the device tree portion of the kernel build stage needs to be reset within Factory. This can be done with the following, issued from the top-level Factory directory:

make kernel_devicetree-distclean

This action will remove the existing dts file stored in the src/dl/k/kernel/kernel-[kerenl version]/ directory (thereby requiring your modified dts to be fetched during the rebuild) and also remove the compiled *.dtb file from your kernel working directory and the BSP output (build_*/images/) directory.

Rebuild Device Tree and SDK Installer

With the device tree reset and everything set to build the dtb with the custom dts file, all that's left to do is rebuild the dtb and SDK Installer.

  1. make kernel_devicetree-host-install
    • this only regenerates the device tree in the kernel working directory and copies it to the build_*/images/ directory (dts modifications will not be reflected in the dtb included in the SDK Installer)
    • this is automatically completed during the kernel build within Factory (make kernel-build from top-level Factory directory)
  2. make installers
    • this will run the above make kernel_devicetree-host-install and then rebuild the SDK Installer to include the custom dtb