From: Pantelis Antoniou Date: Thu, 07 Sep 2017 09:52:10 +0300 Subject: [U-Boot] [PATCH v3 08/14] fit: fdt overlays doc In-Reply-To: <49fedf05-4896-3105-f143-d24db31f6182@denx.de> References: <1504555943-12893-1-git-send-email-pantelis.antoniou@konsulko.com> <1504555943-12893-9-git-send-email-pantelis.antoniou@konsulko.com> <49fedf05-4896-3105-f143-d24db31f6182@denx.de> Message-ID: <1504767130.23573.14.camel@hp800z> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit To: u-boot@lists.denx.de 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 > > --- > > 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 > > 9. bootm []: > > -10. bootm []# > > +10. bootm []#[# > 11. bootm []: []: > > 12. bootm []: []: []: > > 13. bootm []: []: > > @@ -129,6 +129,12 @@ following syntax: > > - new uImage configuration specification > > # > > > > +- new uImage configuration specification with extra configuration components > > +#[#[#..]] > > + > > +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 at 1 > > - boot configuration "cfg at 1" from a new uImage located at 200000: > > bootm 200000#cfg at 1 > > > > +- boot configuration "cfg at 1" with extra "cfg at 2" from a new uImage located > > + at 200000: > > +bootm 200000#cfg at 1#cfg at 2 > > + > > - boot "kernel at 1" from a new uImage at 200000 with initrd "ramdisk at 2" found in > > some other new uImage stored at address 800000: > > bootm 200000:kernel at 1 800000:ramdisk at 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 at 1 { > > + data = /incbin/("./zImage"); > > + type = "kernel"; > > + arch = "arm"; > > + os = "linux"; > > + load = <0x82000000>; > > + entry = <0x82000000>; > > + }; > > + fdt at 1 { > > + data = /incbin/("./foo-reva.dtb"); > > + type = "flat_dt"; > > + arch = "arm"; > > + }; > > + fdt at 2 { > > + data = /incbin/("./foo-revb.dtb"); > > + type = "flat_dt"; > > + arch = "arm"; > > + }; > > + fdt at 3 { > > + data = /incbin/("./foo-reva-bar.dtb"); > > + type = "flat_dt"; > > + arch = "arm"; > > + }; > > + fdt at 4 { > > + data = /incbin/("./foo-revb-bar.dtb"); > > + type = "flat_dt"; > > + arch = "arm"; > > + }; > > + fdt at 5 { > > + data = /incbin/("./foo-revb-baz.dtb"); > > + type = "flat_dt"; > > + arch = "arm"; > > + }; > > + fdt at 6 { > > + data = /incbin/("./foo-revb-bar-baz.dtb"); > > + type = "flat_dt"; > > + arch = "arm"; > > + }; > > + }; > > + > > + configurations { > > + default = "foo-reva.dtb; > > + foo-reva.dtb { > > + kernel = "kernel at 1"; > > + fdt = "fdt at 1"; > > + }; > > + foo-revb.dtb { > > + kernel = "kernel at 1"; > > + fdt = "fdt at 2"; > > + }; > > + foo-reva-bar.dtb { > > + kernel = "kernel at 1"; > > + fdt = "fdt at 3"; > > + }; > > + foo-revb-bar.dtb { > > + kernel = "kernel at 1"; > > + fdt = "fdt at 4"; > > + }; > > + foo-revb-baz.dtb { > > + kernel = "kernel at 1"; > > + fdt = "fdt at 5"; > > + }; > > + foo-revb-bar-baz.dtb { > > + kernel = "kernel at 1"; > > + fdt = "fdt at 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 # > > + > > +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 at 1 { > > + data = /incbin/("./zImage"); > > + type = "kernel"; > > + arch = "arm"; > > + os = "linux"; > > + load = <0x82000000>; > > + entry = <0x82000000>; > > + }; > > + fdt at 1 { > > + data = /incbin/("./foo.dtb"); > > + type = "flat_dt"; > > + arch = "arm"; > > + load = <0x87f00000>; > > + }; > > + fdt at 2 { > > + data = /incbin/("./reva.dtbo"); > > + type = "flat_dt"; > > + arch = "arm"; > > + load = <0x87fc0000>; > > + }; > > + fdt at 3 { > > + data = /incbin/("./revb.dtbo"); > > + type = "flat_dt"; > > + arch = "arm"; > > + load = <0x87fc0000>; > > + }; > > + fdt at 4 { > > + data = /incbin/("./bar.dtbo"); > > + type = "flat_dt"; > > + arch = "arm"; > > + load = <0x87fc0000>; > > + }; > > + fdt at 5 { > > + data = /incbin/("./baz.dtbo"); > > + type = "flat_dt"; > > + arch = "arm"; > > + load = <0x87fc0000>; > > + }; > > + }; > > + > > + configurations { > > + default = "foo-reva.dtb; > > + foo-reva.dtb { > > + kernel = "kernel at 1"; > > + fdt = "fdt at 1", "fdt at 2"; > > + }; > > + foo-revb.dtb { > > + kernel = "kernel at 1"; > > + fdt = "fdt at 1", "fdt at 3"; > > + }; > > + foo-reva-bar.dtb { > > + kernel = "kernel at 1"; > > + fdt = "fdt at 1", "fdt at 2", "fdt at 4"; > > + }; > > + foo-revb-bar.dtb { > > + kernel = "kernel at 1"; > > + fdt = "fdt at 1", "fdt at 3", "fdt at 4"; > > + }; > > + foo-revb-baz.dtb { > > + kernel = "kernel at 1"; > > + fdt = "fdt at 1", "fdt at 3", "fdt at 5"; > > + }; > > + foo-revb-bar-baz.dtb { > > + kernel = "kernel at 1"; > > + fdt = "fdt at 1", "fdt at 3", "fdt at 4", "fdt at 5"; > > + }; > > + bar { > > + fdt = "fdt at 4"; > > + }; > > + baz { > > + fdt = "fdt at 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 #foo-reva.dtb#bar > > + > > +While booting a revb with bar and baz is as follows: > > + > > + # bootm #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.antoniou at 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 at 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 at 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