设备树覆盖手柄
device tree overlay phandle
我正在研究带有双 Cortex-A9 处理器的 Altera Cyclone V SOC FPGA。嵌入式系统(linux-socfpga 4.16)是用Buildroot-2018.05创建的。
我在处理器组件的启动时使用 "top" 设备树,并使用设备树覆盖来配置组件的 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)
};
};
};
我的问题是 link 从顶部 DT 到覆盖层中的 memory-region
mem_dma_reserved
。
我假设在使用 -@ 选项将 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,因为叠加层不知道 <&mem_dma_reserved> 节点。修复部分应该能够在加载时取回 phandle,但它不工作,我得到这个错误:
[ 27.434730] OF: resolver: of_resolve_phandles: no symbols in root of device tree.
[ 27.440401] OF: resolver: overlay phandle fixup failed: -22
[ 27.445993] create_overlay: Failed to resolve tree
我在顶部 DT 上进行了从 dtb 到 dts 的相同再生。我看到保留内存的phandle其实是0x6。我在设备树覆盖层中写了 <0x6> 而不是 <&mem_dma_reserved> 并且使用此配置,一切都加载了!
如何让叠加层自动找到 <&mem_dma_reserved> 而无需手动操作?
编辑
正如 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/
my_dma_0
other_stuff
cat /sys/firmware/devicetree/base/soc/base_fpga_region/my_dma_0/memory-region
//nothing//
似乎没有附加内存区域。
我错过了什么?
制作top dtb时,是否在dtc命令中附加了选项--symbol(或-@)?
给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";
};
我正在研究带有双 Cortex-A9 处理器的 Altera Cyclone V SOC FPGA。嵌入式系统(linux-socfpga 4.16)是用Buildroot-2018.05创建的。
我在处理器组件的启动时使用 "top" 设备树,并使用设备树覆盖来配置组件的 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)
};
};
};
我的问题是 link 从顶部 DT 到覆盖层中的 memory-region
mem_dma_reserved
。
我假设在使用 -@ 选项将 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,因为叠加层不知道 <&mem_dma_reserved> 节点。修复部分应该能够在加载时取回 phandle,但它不工作,我得到这个错误:
[ 27.434730] OF: resolver: of_resolve_phandles: no symbols in root of device tree.
[ 27.440401] OF: resolver: overlay phandle fixup failed: -22
[ 27.445993] create_overlay: Failed to resolve tree
我在顶部 DT 上进行了从 dtb 到 dts 的相同再生。我看到保留内存的phandle其实是0x6。我在设备树覆盖层中写了 <0x6> 而不是 <&mem_dma_reserved> 并且使用此配置,一切都加载了!
如何让叠加层自动找到 <&mem_dma_reserved> 而无需手动操作?
编辑
正如 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/
my_dma_0
other_stuffcat /sys/firmware/devicetree/base/soc/base_fpga_region/my_dma_0/memory-region
//nothing//
似乎没有附加内存区域。
我错过了什么?
制作top dtb时,是否在dtc命令中附加了选项--symbol(或-@)?
给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";
};