Search code examples
linuxkerneldevicedevice-tree

Understanding the Device Tree mechanism


Was reading the Device Tree Usage and reached to the section describing the ranges key attribute for a node.

external-bus {
        #address-cells = <2>
        #size-cells = <1>;
        ranges = <0 0  0x10100000   0x10000     // Chipselect 1, Ethernet
                  1 0  0x10160000   0x10000     // Chipselect 2, i2c controller
                  2 0  0x30000000   0x1000000>; // Chipselect 3, NOR Flash

        ethernet@0,0 {
            compatible = "smc,smc91c111";
            reg = <0 0 0x1000>;
            interrupts = < 5 2 >;
        };

        i2c@1,0 {
            compatible = "acme,a1234-i2c-bus";
            #address-cells = <1>;
            #size-cells = <0>;
            reg = <1 0 0x1000>;
            interrupts = < 6 2 >;
            rtc@58 {
                compatible = "maxim,ds1338";
                reg = <58>;
                interrupts = < 7 3 >;
            };
        };

        flash@2,0 {
            compatible = "samsung,k8f1315ebm", "cfi-flash";
            reg = <2 0 0x4000000>;
        };
    };
  1. What is the difference between ranges and reg ?
  2. What are the dimensions for the ranges, how the parser figure out what is written in it?
  3. One missing part I didn't understand yet? Can't include .h files instead of hard-coding values in a the .dts file?

Solution

  • The "range" property maps one or more addresses (the second number from the left of the range) in the current node, the "external bus" node, to addresses in the parent node (probably the CPU) address space (the third number in the range). The fourth number is the length of the range. Buses can have their own idea of addresses on their external side to which peripherals are attached, so the drivers that manage the peripherals on the bus will need to know these ranges in order to read to or write from the the devices.

    The "reg" property indicates the address at which a device resides in the address range of the node (the "external bus" in this case) in which the device is defined. So in this case, flash@2,0 resides at address 0 in the external bus range, and extends to address 0x04000000. This corresponds to address range 0x30000000 to 0x34000000 in the parent (CPU) address space.

    I am assuming that the length specifier of the third range, 2 0 0x30000000 0x1000000>; // Chipselect 3, NOR Flash should in fact be 0x04000000 rather than 0x1000000.