Linux

device tree 정리

Roien 2018. 3. 18.
반응형
DTS (Device Tree Source) file

arch/arm/boot/dts

.dts  : board-level definitions
.dtsi : SoC-level definitions 

device tree compiler

scripts/dts

device tree blob
produced by the compiler
passed by the bootloader and parseed at boot time

arch/arm/boot/dts/Makefile
lists which DTSs should be generated at build time



. bootloader의 일

bootload loads  (kernel image)
uImage
or
zImage


ATAGS 초기화
memory size, location 등의 정보를 지님
Linux command line 정보를 지님

kernel에게 
보드 정보 pass (via r1)


U-boot command
bootm <kernel img addr>



. device tree 이전


   ----------------------------
    | ATAGS   |    uImage   |
   ----------------------------
     r1 = <machine type>
     r2 = <pointer to ATAGS>



. device tree 이후

커널은 더이상 hardware description 정보를 지니지 않음
device tree blob이란 binary에 저장되어 있음

bootload는 다음의 2개를 load

1) uImage or zImage
2) DTB (located in arch/arm/boot/dts/) <- one per board


bootloader가 
DTB address를 r2로 전달

(memrory information으로 DTB가 조절될 수 있음)

U-boot command

bootm <kernel img addr> - <dtb addr>



    ----------------------------------
      | DTB |     | uImage          |
    ----------------------------------

r1 = don't care
r2 = pointer to DTB


. legacy device tree

CONFIG_ARM_APPENDED_DTB option

cat arch/arm/boot/zImage arch/arm/boot/dts/myboard.dtb > my-zImage
mkimage ... -d my-zImage my-uImage



CONFIG_ARM_ATAG_DTB_COMPAT 
커널이 ATAGS 정보를 읽고 DT를 update



. Device Tree Syntax

       +--- node name
       | +- unit address
       | |
/ {    v v
    node@0 {
        a-string-property = "A string";   <-- property name = value
        a-string-list-prop = "1" "2" "3";
        a-byte-data-prop = [0x01 0x02 0x03 0x04];

        child-node@0 {
            first-child-prop;
            second-child-prop = <1>;
            a-ref-to-something = <&node1>;    <- reference to another node
        };

        child-node@1 {
        };
    };

     +--- label
     |
     v
    node1: node@1 {
        an-empty-prop;
        a-cell-prop = <1 2 3 4>           <-- four cells (32 bits values)

        child-node@0 {
        };
    };


ex.
    auart0: serial@8006a000 {

           +--- id used by the OS
           |
           v
        compatible = "fsl,imx28-auart", "fsl,imx23-auart";
        reg = <0x8006a000 0x2000>;                          <- addr & length
        interrupts = <112>;                                 <- IRQ number

        dmas = <&dma_apbx 8>, <&dma_apbx 9>;                <- DMA engine and ch, with names
        dma-names = "rx", "tx";

        clocks = <&clks 45>                                 <- clk ref.

        status = "disabled";                                <- dev is not enabled

    };


static struct of_device_id mxs_ausrt_dt_ids[] = {
    {
        .compatible = "fsl,imx28-uart",
        .data = "mxs_auart_devtype[IMX28_AUART]
    }, 
    {
        .compatible = "fsl,imx23-uart",
        .data = "mxs_auart_devtype[IMX23_AUART]
    },
    {
        /* sentinel */
    }
};

MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids);
[...]

static struct platform_driver mxs_auart_driver = {
    .probe = mxs_auart_probe,
    .remove = mxs_auart_remove,
    .driver = {
        .name = "mxs-auart",
        .of_match_table = mxs_auart_dt_ids,
    },
};

static int mxs_auart_probe(struct platform_device *pdev)
{
    const struct of_device_id *of_id = 
        of_match_device(mxs_auart_dt_ids, &pdev->dev);

    if (!of_id) {
        ....
        return....
    }

    /* use of_id->data here */

    s->clk = clk_get(&pdev->dev, NULL);

    // getting the I/O register resource
    r = platform_get_resource(pdev, IORESOURCE_MEM, 0);

    s->irq = platform_get_irq(pdev, 0);    // get IRQ nr

    s->rx_dma_chan = dma_request_slave_channel(s->dev, "rx");
    s->tx_dma_chan = dma_request_slave_channel(s->dev, "tx");


    // custom property

    struct device_node *np = pdev->dev.of_node;
    if (of_get_property(np, "fsl,uart-has-rtscts", NULL))
    ...
}



. device tree inclusion

여러 file로 구성 가능
.dtsi가 .dts file들을 includsion

보통
.dtsi가 SoC-level의 information을 contain

.dts file은 board-level information을 contain



. device tree binding

ref.
Documentation/devicetree/bindings

properties, values에 대한 명시

새로운 binding 추가 시, 
devicetree@vger.kernel.org에 post 하여 maintainer에 알려야 함



* Freescale MXS Application UART (AUART)

   Required properties:
    - compatible : Should be "fsl,<soc>-auart". The supported SoCs include
      imx23 and imx28.
    - reg : Address and length of the register set for the device
    - interrupts : Should contain the auart interrupt numbers
    - dmas: DMA specifier, consisting of a phandle to DMA controller node
      and AUART DMA channel ID.
      Refer to dma.txt and fsl-mxs-dma.txt for details.
    - dma-names: "rx" for RX channel, "tx" for TX channel.

    Example:
    auart0: serial@8006a000 {
        compatible = "fsl,imx28-auart", "fsl,imx23-auart";
        reg = <0x8006a000 0x2000>;
        interrupts = <112>;
        dmas = <&dma_apbx 8>, <&dma_apbx 9>;
        dma-names = "rx", "tx";
    };

    Note: Each auart port should have an alias correctly numbered in "aliases"
    node.



. device tree organization: top-level nodes

root 밑에는 보통, 
cpus ndoe
memory node
chosen node
aliases node
...
one or more nodes defining the buses in he SoC
one or more nodes defining on-board devices

    / {
        aliases { ... };
        cpus { ... };

        apb@80000000 {
            apbh@80000000 {
                /* Some devices */
            };
        apbx@80040000 {
            /* Some devices */
        };
    };

    ahb@80080000 {
        /* Some devices */
    };
};



반응형

댓글