【问题标题】:device tree overlay phandle设备树覆盖图
【发布时间】:2018-11-29 15:06:01
【问题描述】:

我正在开发来自 Altera 的 Cyclone V SOC FPGA,它带有双 Cortex-A9 处理器。嵌入式系统(linux-socfpga 4.16)是使用 Buildroot-2018.05 创建的。

我在启动时为处理器组件使用“顶部”设备树,并使用设备树覆盖来配置组件的 FPGA 部分并加载相关的驱动程序。叠加层将附加到顶部 DT 的 base_fpga_region


顶部设备树

/dts-v1/;

/ {
    model = "MY_PROJECT";   /* appended from boardinfo */
    compatible = "altr,socfpga-cyclone5", "altr,socfpga";   /* appended from boardinfo */
    #address-cells = <1>;
    #size-cells = <1>;

    cpus {
        [...]
    }; //end cpus

    memory {
        device_type = "memory";
        reg = <0xffff0000 0x00010000>,
            <0x00000000 0x80000000>;
    }; //end memory

    reserved-memory {
        #address-cells = <1>;
        #size-cells = <1>;
        ranges;

        mem_dma_reserved {
            compatible = "shared-dma-pool";
            no-map;
            reg = <0x78000000 0x8000000>;
        };
    };

    soc: soc {
        device_type = "soc";
        ranges;
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "altr,avalon", "simple-bus";
        bus-frequency = <0>;

        fpgabridge1: fpgabridge@1 {
            compatible = "altr,socfpga-lwhps2fpga-bridge";
            resets = <&hps_rstmgr 97>;  /* appended from boardinfo */
            clocks = <&l4_main_clk>;    /* appended from boardinfo */           
            #address-cells = <1>;
            #size-cells = <1>;
            ranges;
            bridge-enable = <1>;

            label = "lwhps2fpga";
            reset-names = "lwhps2fpga";
            reg = <0xff200000 0x200000>;
            reg-names = "axi_h2f_lw";
        }; //end fpgabridge@1 (fpgabridge1)

        base_fpga_region: base_fpga_region  {
            compatible = "fpga-region";
            #address-cells = <0x2>;
            #size-cells = <0x1>;
            fpga-mgr = <&hps_fpgamgr>;
            fpga-bridges = <&fpgabridge1>;          
            ranges = <0x0 0x0 0xff200000 0x200000>;
        }; //end base_fpga_region (base_fpga_region)

etc......

设备树覆盖

/dts-v1/ /plugin/; 

/{ 
    fragment@0 { 
        target-path = "/soc/base_fpga_region"; 
        #address-cells = <2>; 
        #size-cells = <1>; 
        __overlay__ { 
            #address-cells = <2>; 
            #size-cells = <1>; 

            firmware-name = "my_project.rbf";

            my_dma_0: dma@0x000000000 {
                compatible = "my_company,my_dma-0.1";
                reg = <0x00000000 0x0000000 0x00000014>;
                memory-region = <&mem_dma_reserved>;
            }; //end dma@0x000000000 (my_dma_0)      
        }; 
    }; 
};

我的问题是将顶部 DT 中的 mem_dma_reserved 链接到叠加层中的 memory-region

我假设在使用 -@ 选项将 dts 转换为 dtbo 时,覆盖应使用 __fixups__ 选项获得 mem_dma_reserved 的 phandle。我已经创建了 dtbo 文件并在 dts 中再次对其进行了转换,以查看在编译过程中做了什么:

dtc -@ -I dts -O dtb -o overlay.dtbo overlay.dts
dtc -I dtb -O dts -o overlay_recovery.dts overlay.dtbo

设备树覆盖重新生成

/dts-v1/;    
/ {

    fragment@0 {
        target-path = "/soc/base_fpga_region";
        #address-cells = <0x2>;
        #size-cells = <0x1>;

        __overlay__ {
            #address-cells = <0x2>;
            #size-cells = <0x1>;
            firmware-name = "my_project.rbf";

            dma@0x000000000 {
                compatible = "my_company,my_dma-0.1";
                reg = <0x0 0x0 0x14>;
                memory-region = <0xffffffff>;  // phandle converted to 0xffffffff, cannot resolve unless the __fixup__ function does it.
                linux,phandle = <0x2>;
                phandle = <0x2>;
            };
        };
    };

    __symbols__ {
        my_dma_0 = "/fragment@0/__overlay__/dma@0x000000000";
    };

    __fixups__ {
        mem_dma_reserved = "/fragment@0/__overlay__/dma@0x000000000:memory-region:0";
    };
};

我们可以看到内存区域的 phandle 为 0xFFFFFFFF,因为覆盖层不知道 节点。 fixup 部分应该能够在加载时取回 phandle,但它不起作用,我收到此错误:

[27.434730] OF:解析器:of_resolve_phandles:设备树根目录中没有符号。
[27.440401] OF:解析器:覆盖 phandle 修复失败:-22
[27.445993] create_overlay:解析树失败

我在顶部 DT 上进行了从 dtb 到 dts 的相同再生。我已经看到保留内存的phandle实际上是0x6。我在设备树覆盖中写了 而不是 并且使用此配置,所有内容都会加载!

如何让叠加层自动找到 而无需手动操作?

编辑

正如 ikwzm 所指出的,我在顶部设备树中添加了以下几行:

reserved-memory {
    #address-cells = <1>;
    #size-cells = <1>;
    ranges;

    mem_dma_reserved: mem_dma_reserved { // add a label
        compatible = "shared-dma-pool";
        no-map;
        reg = <0x78000000 0x8000000>;
    };
};    

[...]    

// add the whole symbol block
__symbols__ { 
    mem_dma_reserved = "/reserved-memory/mem_dma_reserved ";
};

错误现在消失了,但是:

我希望在操作期间加载 my_dma 的驱动程序。

我检查了设备树覆盖是否很好地考虑了:

ls /sys/firmware/devicetree/base/soc/base_fpga_region/
我的_dma_0
其他的东西

cat /sys/firmware/devicetree/base/soc/base_fpga_region/my_dma_0/memory-region
//什么都没有//

内存区域似乎没有附加。

我错过了什么?

【问题讨论】:

    标签: linux-kernel device-tree


    【解决方案1】:

    在制作顶部 dtb 时,您是否将选项 --symbol(或 -@)附加到 dtc 命令?

    如下向mem_dma_reserved添加标签(符号)。

    reserved-memory {
        #address-cells = <1>;
        #size-cells = <1>;
        ranges;
    
        mem_dma_reserved: mem_dma_reserved {
            compatible = "shared-dma-pool";
            no-map;
            reg = <0x78000000 0x8000000>;
        };
    };
    

    使用--symbol选项dtc命令创建dtb时,__symbols__{...};添加如下,mem_dma_reserved = "/reserved-memory/ mem_dma_reserved";应该在里面找到。

    __symbols__ {
        :
        :
        :
        mem_dma_reserved = "/reserved-memory/mem_dma_reserved";
        usb_phy0 = "/phy0";
    };
    

    【讨论】:

    • 我试过这个解决方案,但内核在启动时卡在“正在启动内核...”我认为启用此选项时我的设备树有问题
    • 好的,这是阻止内核启动的修复行。我在 dts 文件中手动添加了 symbols 并在没有选项 -@ 的情况下编译
    • 我更改了我的dtc 版本,现在设备树覆盖与您的解决方案一起安装得很好。唯一的问题是我的驱动程序现在没有探测。只调用了init函数...好吧,如果我不能自己解决,那就需要另一个问题了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2015-07-04
    相关资源
    最近更新 更多