The Linux device tree describes the hardware and peripherals that the kernel image will interact with as it runs. Using a device tree allows the same kernel image to run on multiple hardware platforms, and it simplifies porting Linux to new platforms because many customizations can be done in the device tree without modifying the kernel source code. Device trees are organized in a hierarchy based on how different hardware peripherals communicate with each other. Most nodes are associated with a Linux device driver, and the presence of a node tells Linux that the driver should be loaded and gives parameters for one instance of the device driver.
Device tree nodes may correspond to various sub-systems of a CPU, or to peripherals that are connected to the CPU by various types of busses. For example, a CPU might have a sub-system to control an I2C bus. In order to use this sub-system, Linux must load the proper device driver and point it to the correct registers in the CPU. The device tree would have a node for the I2C controller that tells what driver to load and the register range. Any peripherals connected to this I2C bus would usually be sub-nodes of the I2C bus node in the device tree. Those nodes can specify which Linux driver controls the peripheral, the I2C address of the peripheral, and any other relevant parameters.
Device trees are usually written as text files that are compiled into binaries using the device tree compiler (dtc) tool. The device tree binary (.dtb file) is loaded into memory by the bootloader, and its location is used by the boot command along with the location of the Linux kernel. Using this method, the same Linux kernel can support multiple hardware configurations. The bootloader detects the configuration, and boots the kernel with the corresponding device tree.