[U-Boot] [PATCH v3 08/14] fit: fdt overlays doc
Pantelis Antoniou
pantelis.antoniou at konsulko.com
Thu Sep 7 06:52:10 UTC 2017
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.antoniou at 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 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 <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 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 <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.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
More information about the U-Boot
mailing list