diff mbox series

[U-Boot,v3,08/14] fit: fdt overlays doc

Message ID 1504555943-12893-9-git-send-email-pantelis.antoniou@konsulko.com
State Accepted
Commit 6b54e50b5a5889efe179cb06aa6aa25583ef25d5
Delegated to: Simon Glass
Headers show
Series uboot overlays, FIT image & unittest | expand

Commit Message

Pantelis Antoniou Sept. 4, 2017, 8:12 p.m. UTC
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@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

Comments

Lukasz Majewski Sept. 6, 2017, 7:06 p.m. UTC | #1
On 09/04/2017 10:12 PM, Pantelis Antoniou wrote:
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@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.antoniou@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?
Pantelis Antoniou Sept. 7, 2017, 6:52 a.m. UTC | #2
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@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.antoniou@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
Simon Glass Sept. 9, 2017, 4:53 a.m. UTC | #3
On 4 September 2017 at 14:12, Pantelis Antoniou
<pantelis.antoniou@konsulko.com> wrote:
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@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
>

Acked-by: Simon Glass <sjg@chromium.org>
Simon Glass Sept. 15, 2017, 7:19 p.m. UTC | #4
On 4 September 2017 at 14:12, Pantelis Antoniou
<pantelis.antoniou@konsulko.com> wrote:
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@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
>

Acked-by: Simon Glass <sjg@chromium.org>

Applied to u-boot-fdt thanks!
diff mbox series

Patch

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.antoniou@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