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