Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | .. SPDX-License-Identifier: GPL-2.0+ U-Boot FDT Overlay FIT usage ============================ Introduction ------------ In many cases it is desirable to have a single FIT image support a multitude of similar boards and their expansion options. The same kernel on DT enabled platforms can support this easily enough by providing a DT blob upon boot that matches the desired configuration. This document focuses on specifically using overlays as part of a FIT image. General information regarding overlays including its syntax and building it can be found in :doc:`/usage/fdt_overlays` Configuration without overlays ------------------------------ Take a hypothetical board named 'foo' where there are different supported revisions, reva and revb. Assume that both board revisions can add a bar add-on board, while only the revb board can use a baz add-on board. Without using overlays the configuration would be as follows for every case:: /dts-v1/; / { images { kernel { data = /incbin/("./zImage"); type = "kernel"; arch = "arm"; os = "linux"; load = <0x82000000>; entry = <0x82000000>; }; fdt-1 { data = /incbin/("./foo-reva.dtb"); type = "flat_dt"; arch = "arm"; }; fdt-2 { data = /incbin/("./foo-revb.dtb"); type = "flat_dt"; arch = "arm"; }; fdt-3 { data = /incbin/("./foo-reva-bar.dtb"); type = "flat_dt"; arch = "arm"; }; fdt-4 { data = /incbin/("./foo-revb-bar.dtb"); type = "flat_dt"; arch = "arm"; }; fdt-5 { data = /incbin/("./foo-revb-baz.dtb"); type = "flat_dt"; arch = "arm"; }; fdt-6 { data = /incbin/("./foo-revb-bar-baz.dtb"); type = "flat_dt"; arch = "arm"; }; }; configurations { default = "foo-reva.dtb"; foo-reva.dtb { kernel = "kernel"; fdt = "fdt-1"; }; foo-revb.dtb { kernel = "kernel"; fdt = "fdt-2"; }; foo-reva-bar.dtb { kernel = "kernel"; fdt = "fdt-3"; }; foo-revb-bar.dtb { kernel = "kernel"; fdt = "fdt-4"; }; foo-revb-baz.dtb { kernel = "kernel"; fdt = "fdt-5"; }; foo-revb-bar-baz.dtb { kernel = "kernel"; fdt = "fdt-6"; }; }; }; Note the blob needs to be compiled for each case and the combinatorial explosion of configurations. A typical device tree blob is in the low hundreds of kbytes so a multitude of configuration grows the image quite a bit. Booting this image is done by using:: # bootm <addr>#<config> Where config is one of:: foo-reva.dtb, foo-revb.dtb, foo-reva-bar.dtb, foo-revb-bar.dtb, foo-revb-baz.dtb, foo-revb-bar-baz.dtb This selects the DTB to use when booting. .. _fit_configuration_using_overlays: Configuration using overlays ---------------------------- Device tree overlays can be applied to a base DT and result in the same blob being passed to the booting kernel. This saves on space and avoids the combinatorial explosion problem:: /dts-v1/; / { images { kernel { data = /incbin/("./zImage"); type = "kernel"; arch = "arm"; os = "linux"; load = <0x82000000>; entry = <0x82000000>; }; fdt-1 { data = /incbin/("./foo.dtb"); type = "flat_dt"; arch = "arm"; load = <0x87f00000>; }; fdt-2 { data = /incbin/("./reva.dtbo"); type = "flat_dt"; arch = "arm"; load = <0x87fc0000>; }; fdt-3 { data = /incbin/("./revb.dtbo"); type = "flat_dt"; arch = "arm"; load = <0x87fc0000>; }; fdt-4 { data = /incbin/("./bar.dtbo"); type = "flat_dt"; arch = "arm"; load = <0x87fc0000>; }; fdt-5 { data = /incbin/("./baz.dtbo"); type = "flat_dt"; arch = "arm"; load = <0x87fc0000>; }; }; configurations { default = "foo-reva.dtb"; foo-reva.dtb { kernel = "kernel"; fdt = "fdt-1", "fdt-2"; }; foo-revb.dtb { kernel = "kernel"; fdt = "fdt-1", "fdt-3"; }; foo-reva-bar.dtb { kernel = "kernel"; fdt = "fdt-1", "fdt-2", "fdt-4"; }; foo-revb-bar.dtb { kernel = "kernel"; fdt = "fdt-1", "fdt-3", "fdt-4"; }; foo-revb-baz.dtb { kernel = "kernel"; fdt = "fdt-1", "fdt-3", "fdt-5"; }; foo-revb-bar-baz.dtb { kernel = "kernel"; fdt = "fdt-1", "fdt-3", "fdt-4", "fdt-5"; }; bar { fdt = "fdt-4"; }; baz { fdt = "fdt-5"; }; }; }; Booting this image is exactly the same as the non-overlay example. u-boot will retrieve the base blob and apply the overlays in sequence as they are declared in the configuration. Note the minimum amount of different DT blobs, as well as the requirement for the DT blobs to have a load address; the overlay application requires the blobs to be writeable. Configuration using overlays and feature selection -------------------------------------------------- Although the configuration in the previous section works, it is a bit inflexible since it requires all possible configuration options to be laid out beforehand in the FIT image. For the add-on boards the extra config selection method might make sense. Note the two bar & baz configuration nodes. To boot a reva board with the bar add-on board enabled simply use:: => bootm <addr>#foo-reva.dtb#bar While booting a revb with bar and baz is as follows:: => bootm <addr>#foo-revb.dtb#bar#baz The limitation for a feature selection configuration node is that a single fdt option is currently supported. .. sectionauthor:: Pantelis Antoniou <pantelis.antoniou@konsulko.com>, 12/6/2017 |