Hi Lukasz, On Wed, 2017-09-06 at 21:06 +0200, Łukasz Majewski wrote: > On 09/04/2017 10:12 PM, Pantelis Antoniou wrote: > > Signed-off-by: Pantelis Antoniou <pantelis.anton...@konsulko.com> > > --- > > doc/uImage.FIT/command_syntax_extensions.txt | 12 +- > > doc/uImage.FIT/overlay-fdt-boot.txt | 221 > > +++++++++++++++++++++++++++ > > doc/uImage.FIT/source_file_format.txt | 6 +- > > 3 files changed, 236 insertions(+), 3 deletions(-) > > create mode 100644 doc/uImage.FIT/overlay-fdt-boot.txt > > > > diff --git a/doc/uImage.FIT/command_syntax_extensions.txt > > b/doc/uImage.FIT/command_syntax_extensions.txt > > index 6c99b1c..676f992 100644 > > --- a/doc/uImage.FIT/command_syntax_extensions.txt > > +++ b/doc/uImage.FIT/command_syntax_extensions.txt > > @@ -36,7 +36,7 @@ Old uImage: > > New uImage: > > 8. bootm <addr1> > > 9. bootm [<addr1>]:<subimg1> > > -10. bootm [<addr1>]#<conf> > > +10. bootm [<addr1>]#<conf>[#<extra-conf[#...]] > > 11. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2> > > 12. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2> [<addr3>]:<subimg3> > > 13. bootm [<addr1>]:<subimg1> [<addr2>]:<subimg2> <addr3> > > @@ -129,6 +129,12 @@ following syntax: > > - new uImage configuration specification > > <addr>#<configuration unit_name> > > > > +- new uImage configuration specification with extra configuration > > components > > +<addr>#<configuration unit_name>[#<extra configuration unit_name>[#..]] > > + > > +The extra configuration currently is supported only for additional device > > tree > > +overlays to apply on the base device tree supplied by the first > > configuration > > +unit. > > > > Examples: > > > > @@ -138,6 +144,10 @@ bootm 200000:kernel@1 > > - boot configuration "cfg@1" from a new uImage located at 200000: > > bootm 200000#cfg@1 > > > > +- boot configuration "cfg@1" with extra "cfg@2" from a new uImage located > > + at 200000: > > +bootm 200000#cfg@1#cfg@2 > > + > > - boot "kernel@1" from a new uImage at 200000 with initrd "ramdisk@2" > > found in > > some other new uImage stored at address 800000: > > bootm 200000:kernel@1 800000:ramdisk@2 > > diff --git a/doc/uImage.FIT/overlay-fdt-boot.txt > > b/doc/uImage.FIT/overlay-fdt-boot.txt > > new file mode 100644 > > index 0000000..dbdf2a1 > > --- /dev/null > > +++ b/doc/uImage.FIT/overlay-fdt-boot.txt > > @@ -0,0 +1,221 @@ > > +U-Boot FDT Overlay 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. > > + > > +Configuration without overlays > > +------------------------------ > > + > > +Take a hypothetical board named 'foo' where there are different supported > > +revisions, reva and revb. Assume that both board revisions can use 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@1 { > > + 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@1"; > > + fdt = "fdt@1"; > > + }; > > + foo-revb.dtb { > > + kernel = "kernel@1"; > > + fdt = "fdt@2"; > > + }; > > + foo-reva-bar.dtb { > > + kernel = "kernel@1"; > > + fdt = "fdt@3"; > > + }; > > + foo-revb-bar.dtb { > > + kernel = "kernel@1"; > > + fdt = "fdt@4"; > > + }; > > + foo-revb-baz.dtb { > > + kernel = "kernel@1"; > > + fdt = "fdt@5"; > > + }; > > + foo-revb-bar-baz.dtb { > > + kernel = "kernel@1"; > > + 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 hunderds 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. > > + > > +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 avoid the > > combinatorial > > +explosion problem. > > + > > + /dts-v1/; > > + / { > > + images { > > + kernel@1 { > > + 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@1"; > > + fdt = "fdt@1", "fdt@2"; > > + }; > > + foo-revb.dtb { > > + kernel = "kernel@1"; > > + fdt = "fdt@1", "fdt@3"; > > + }; > > + foo-reva-bar.dtb { > > + kernel = "kernel@1"; > > + fdt = "fdt@1", "fdt@2", "fdt@4"; > > + }; > > + foo-revb-bar.dtb { > > + kernel = "kernel@1"; > > + fdt = "fdt@1", "fdt@3", "fdt@4"; > > + }; > > + foo-revb-baz.dtb { > > + kernel = "kernel@1"; > > + fdt = "fdt@1", "fdt@3", "fdt@5"; > > + }; > > + foo-revb-bar-baz.dtb { > > + kernel = "kernel@1"; > > + 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 is a bit > > inflexible > > +since it requires all possible configuration options to be laid out before > > +hand 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. > > + > > +Pantelis Antoniou > > +pantelis.anton...@konsulko.com > > +12/6/2017 > > diff --git a/doc/uImage.FIT/source_file_format.txt > > b/doc/uImage.FIT/source_file_format.txt > > index 136d3d7..ba8013a 100644 > > --- a/doc/uImage.FIT/source_file_format.txt > > +++ b/doc/uImage.FIT/source_file_format.txt > > @@ -235,7 +235,7 @@ o config@1 > > |- description = "configuration description" > > |- kernel = "kernel sub-node unit name" > > |- ramdisk = "ramdisk sub-node unit name" > > - |- fdt = "fdt sub-node unit-name" > > + |- fdt = "fdt sub-node unit-name" [, "fdt overlay sub-node unit-name", > > ...] > > |- fpga = "fpga sub-node unit-name" > > |- loadables = "loadables sub-node unit-name" > > > > @@ -249,7 +249,9 @@ o config@1 > > - ramdisk : Unit name of the corresponding ramdisk image (component > > image > > node of a "ramdisk" type). > > - fdt : Unit name of the corresponding fdt blob (component image node > > of a > > - "fdt type"). > > + "fdt type"). Additional fdt overlay nodes can be supplied which signify > > + that the resulting device tree blob is generated by the first base fdt > > + blob with all subsequent overlays applied. > > - setup : Unit name of the corresponding setup binary (used for booting > > an x86 kernel). This contains the setup.bin file built by the kernel. > > - fpga : Unit name of the corresponding fpga bitstream blob > > > > Reviewed-by: Łukasz Majewski > > > I'm just curious - what was the fit image size reduction on your test setup? >
I haven't measured, but it's easy to calculate. Assume each base blob is B bytes in average with each additional overlay being Oi extra bytes when included in the base and O bytes (in average) when compiled as an overlay (with O > Oi, overhead is almost constant - O = Oi + C). Then for n cases: The size of a non-overlay case is: Si = (B + Oi) * n = B * n + Oi * n The size of an overlay case is So = B + O * n = B + (Oi + C) * n = B + Oi * n + C * n The delta in size is: d = Si - So = B * n + Qi * n - B - Oi * n - C * n = = B * (n - 1) - C * n For contemporary device trees (which are in the 140K sizes) and the average overhead at about 200 bytes. d = 140K * (n - 1) - 200 * n It's pretty much a win even at n = 2. For example for n = 5 (a common case). d = 140K * (5 - 1) - 200 * 5 = 559K It's not earth-shattering smaller, but it's significant. Regards -- Pantelis _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot