diff mbox series

[U-Boot,v3] spl: add overall SPL size check

Message ID 20190524200704.29373-1-simon.k.r.goldschmidt@gmail.com
State Accepted
Commit 2577015dc5c48e7892dea8731a27530543606673
Delegated to: Tom Rini
Headers show
Series [U-Boot,v3] spl: add overall SPL size check | expand

Commit Message

Simon Goldschmidt May 24, 2019, 8:07 p.m. UTC
This adds a size check for SPL that can dynamically check generated
SPL binaries (including devicetree) for a size limit that ensures
this image plus global data, heap and stack fit in initial SRAM.

Since some of these sizes are not available to make, a new host tool
'spl_size_limit' is added that dumps the resulting maximum size for
an SPL binary to stdout. This tool is used in toplevel Makefile to
implement the size check on SPL binaries.

Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
---

Changes in v3:
- don't build this new tools for 'make tools-only'

Changes in v2:
- added missing tools/spl_size_limit.c

 Kconfig                |  8 --------
 Makefile               |  3 ++-
 common/spl/Kconfig     | 36 ++++++++++++++++++++++++++++++++++++
 tools/Makefile         |  4 ++++
 tools/spl_size_limit.c | 30 ++++++++++++++++++++++++++++++
 5 files changed, 72 insertions(+), 9 deletions(-)
 create mode 100644 tools/spl_size_limit.c

Comments

Simon Goldschmidt May 24, 2019, 8:10 p.m. UTC | #1
Am 24.05.2019 um 22:07 schrieb Simon Goldschmidt:
> This adds a size check for SPL that can dynamically check generated
> SPL binaries (including devicetree) for a size limit that ensures
> this image plus global data, heap and stack fit in initial SRAM.
> 
> Since some of these sizes are not available to make, a new host tool
> 'spl_size_limit' is added that dumps the resulting maximum size for
> an SPL binary to stdout. This tool is used in toplevel Makefile to
> implement the size check on SPL binaries.
> 
> Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
> ---
> 
> Changes in v3:
> - don't build this new tools for 'make tools-only'

So this is how far I got.

Tom, your idea with making this multi-config aware (U-Boot, SPL and TPL) 
does not seem to work as 'tools' are only built once, not once per 
U-Boot/SPL/TPL. So if we wanted to use this for TPL, too, that would 
either mean create yet another tool or pass an option to this new tool 
to differ between SPL and TPL.

Regard,
Simon

> 
> Changes in v2:
> - added missing tools/spl_size_limit.c
> 
>   Kconfig                |  8 --------
>   Makefile               |  3 ++-
>   common/spl/Kconfig     | 36 ++++++++++++++++++++++++++++++++++++
>   tools/Makefile         |  4 ++++
>   tools/spl_size_limit.c | 30 ++++++++++++++++++++++++++++++
>   5 files changed, 72 insertions(+), 9 deletions(-)
>   create mode 100644 tools/spl_size_limit.c
> 
> diff --git a/Kconfig b/Kconfig
> index 1221d1af69..5f5c5ccfd6 100644
> --- a/Kconfig
> +++ b/Kconfig
> @@ -172,14 +172,6 @@ config TPL_SYS_MALLOC_F_LEN
>   	  particular needs this to operate, so that it can allocate the
>   	  initial serial device and any others that are needed.
>   
> -config SPL_SIZE_LIMIT
> -	int "Maximum size of SPL image"
> -	depends on SPL
> -	default 0
> -	help
> -	  Specifies the maximum length of the U-Boot SPL image.
> -	  If this value is zero, it is ignored.
> -
>   menuconfig EXPERT
>   	bool "Configure standard U-Boot features (expert users)"
>   	default y
> diff --git a/Makefile b/Makefile
> index 7d910b3682..ed7e12120f 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -797,7 +797,7 @@ BOARD_SIZE_CHECK =
>   endif
>   
>   ifneq ($(CONFIG_SPL_SIZE_LIMIT),0)
> -SPL_SIZE_CHECK = @$(call size_check,$@,$(CONFIG_SPL_SIZE_LIMIT))
> +SPL_SIZE_CHECK = @$(call size_check,$@,$$(tools/spl_size_limit))
>   else
>   SPL_SIZE_CHECK =
>   endif
> @@ -1779,6 +1779,7 @@ checkarmreloc: u-boot
>   envtools: scripts_basic $(version_h) $(timestamp_h)
>   	$(Q)$(MAKE) $(build)=tools/env
>   
> +tools-only: export TOOLS_ONLY=y
>   tools-only: scripts_basic $(version_h) $(timestamp_h)
>   	$(Q)$(MAKE) $(build)=tools
>   
> diff --git a/common/spl/Kconfig b/common/spl/Kconfig
> index c7cd34449a..6a98536f20 100644
> --- a/common/spl/Kconfig
> +++ b/common/spl/Kconfig
> @@ -25,6 +25,42 @@ config SPL_FRAMEWORK
>   	  supports MMC, NAND and YMODEM and other methods loading of U-Boot
>   	  and the Linux Kernel.  If unsure, say Y.
>   
> +config SPL_SIZE_LIMIT
> +	hex "Maximum size of SPL image"
> +	depends on SPL
> +	default 0
> +	help
> +	  Specifies the maximum length of the U-Boot SPL image.
> +	  If this value is zero, it is ignored.
> +
> +config SPL_SIZE_LIMIT_SUBTRACT_GD
> +	bool "SPL image size check: provide space for global data"
> +	depends on SPL_SIZE_LIMIT > 0
> +	help
> +	  If enabled, aligned size of global data is reserved in
> +	  SPL_SIZE_LIMIT check to ensure such an image does not overflow SRAM
> +	  if SPL_SIZE_LIMIT describes the size of SRAM available for SPL when
> +	  pre-reloc global data is put into this SRAM, too.
> +
> +config SPL_SIZE_LIMIT_SUBTRACT_MALLOC
> +	bool "SPL image size check: provide space for malloc() pool before relocation"
> +	depends on SPL_SIZE_LIMIT > 0
> +	help
> +	  If enabled, SPL_SYS_MALLOC_F_LEN is reserved in SPL_SIZE_LIMIT check
> +	  to ensure such an image does not overflow SRAM if SPL_SIZE_LIMIT
> +	  describes the size of SRAM available for SPL when pre-reloc malloc
> +	  pool is put into this SRAM, too.
> +
> +config SPL_SIZE_LIMIT_PROVIDE_STACK
> +	hex "SPL image size check: provide stack space before relocation"
> +	depends on SPL_SIZE_LIMIT > 0
> +	default 0
> +	help
> +	  If set, this size is reserved in SPL_SIZE_LIMIT check to ensure such
> +	  an image does not overflow SRAM if SPL_SIZE_LIMIT describes the size
> +	  of SRAM available for SPL when the stack required before reolcation
> +	  uses this SRAM, too.
> +
>   config HANDOFF
>   	bool "Pass hand-off information from SPL to U-Boot proper"
>   	depends on BLOBLIST
> diff --git a/tools/Makefile b/tools/Makefile
> index e2f572cae1..33e90a8025 100644
> --- a/tools/Makefile
> +++ b/tools/Makefile
> @@ -199,6 +199,10 @@ hostprogs-$(CONFIG_RISCV) += prelink-riscv
>   hostprogs-y += fdtgrep
>   fdtgrep-objs += $(LIBFDT_OBJS) fdtgrep.o
>   
> +ifneq ($(TOOLS_ONLY),y)
> +hostprogs-y += spl_size_limit
> +endif
> +
>   hostprogs-$(CONFIG_MIPS) += mips-relocs
>   
>   # We build some files with extra pedantic flags to try to minimize things
> diff --git a/tools/spl_size_limit.c b/tools/spl_size_limit.c
> new file mode 100644
> index 0000000000..98ff491867
> --- /dev/null
> +++ b/tools/spl_size_limit.c
> @@ -0,0 +1,30 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (c) 2019, Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
> + *
> + * This tool helps to return the size available for SPL image during build
> + */
> +
> +#include <generated/autoconf.h>
> +#include <generated/generic-asm-offsets.h>
> +
> +int main(int argc, char *argv[])
> +{
> +	int spl_size_limit = 0;
> +
> +#ifdef CONFIG_SPL_SIZE_LIMIT
> +	spl_size_limit = CONFIG_SPL_SIZE_LIMIT;
> +#ifdef CONFIG_SPL_SIZE_LIMIT_SUBTRACT_GD
> +	spl_size_limit -= GENERATED_GBL_DATA_SIZE;
> +#endif
> +#ifdef CONFIG_SPL_SIZE_LIMIT_SUBTRACT_MALLOC
> +	spl_size_limit -= CONFIG_SPL_SYS_MALLOC_F_LEN;
> +#endif
> +#ifdef CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK
> +	spl_size_limit -= CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK;
> +#endif
> +#endif
> +
> +	printf("%d", spl_size_limit);
> +	return 0;
> +}
>
Tom Rini May 26, 2019, 11:09 a.m. UTC | #2
On Fri, May 24, 2019 at 10:10:48PM +0200, Simon Goldschmidt wrote:
> Am 24.05.2019 um 22:07 schrieb Simon Goldschmidt:
> >This adds a size check for SPL that can dynamically check generated
> >SPL binaries (including devicetree) for a size limit that ensures
> >this image plus global data, heap and stack fit in initial SRAM.
> >
> >Since some of these sizes are not available to make, a new host tool
> >'spl_size_limit' is added that dumps the resulting maximum size for
> >an SPL binary to stdout. This tool is used in toplevel Makefile to
> >implement the size check on SPL binaries.
> >
> >Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
> >---
> >
> >Changes in v3:
> >- don't build this new tools for 'make tools-only'
> 
> So this is how far I got.
> 
> Tom, your idea with making this multi-config aware (U-Boot, SPL and TPL)
> does not seem to work as 'tools' are only built once, not once per
> U-Boot/SPL/TPL. So if we wanted to use this for TPL, too, that would either
> mean create yet another tool or pass an option to this new tool to differ
> between SPL and TPL.

OK.  Hopefully at least we can use a Makefile rule to transform the
source code rather than have a copy/paste version of the code.  Thanks
again!
Jean-Jacques Hiblot May 27, 2019, 1:47 p.m. UTC | #3
Simon,


On 24/05/2019 22:10, Simon Goldschmidt wrote:
> Am 24.05.2019 um 22:07 schrieb Simon Goldschmidt:
>> This adds a size check for SPL that can dynamically check generated
>> SPL binaries (including devicetree) for a size limit that ensures
>> this image plus global data, heap and stack fit in initial SRAM.
>>
>> Since some of these sizes are not available to make, a new host tool
>> 'spl_size_limit' is added that dumps the resulting maximum size for
>> an SPL binary to stdout. This tool is used in toplevel Makefile to
>> implement the size check on SPL binaries.
>>
>> Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
>> ---
>>
>> Changes in v3:
>> - don't build this new tools for 'make tools-only'
>
> So this is how far I got.
>
> Tom, your idea with making this multi-config aware (U-Boot, SPL and 
> TPL) does not seem to work as 'tools' are only built once, not once 
> per U-Boot/SPL/TPL. So if we wanted to use this for TPL, too, that 
> would either mean create yet another tool or pass an option to this 
> new tool to differ between SPL and TPL.

If the trouble comes from GENERATED_GBL_DATA_SIZE, you could get its 
value by parsing lib/asm-offsets.s. all the other values could be 
extracted from {.,spl,tpl}/u-boot.cfg

If this flies, it could be done by a python script without the need to 
compile a program

JJ

>
> Regard,
> Simon
>
>>
>> Changes in v2:
>> - added missing tools/spl_size_limit.c
>>
>>   Kconfig                |  8 --------
>>   Makefile               |  3 ++-
>>   common/spl/Kconfig     | 36 ++++++++++++++++++++++++++++++++++++
>>   tools/Makefile         |  4 ++++
>>   tools/spl_size_limit.c | 30 ++++++++++++++++++++++++++++++
>>   5 files changed, 72 insertions(+), 9 deletions(-)
>>   create mode 100644 tools/spl_size_limit.c
>>
>> diff --git a/Kconfig b/Kconfig
>> index 1221d1af69..5f5c5ccfd6 100644
>> --- a/Kconfig
>> +++ b/Kconfig
>> @@ -172,14 +172,6 @@ config TPL_SYS_MALLOC_F_LEN
>>         particular needs this to operate, so that it can allocate the
>>         initial serial device and any others that are needed.
>>   -config SPL_SIZE_LIMIT
>> -    int "Maximum size of SPL image"
>> -    depends on SPL
>> -    default 0
>> -    help
>> -      Specifies the maximum length of the U-Boot SPL image.
>> -      If this value is zero, it is ignored.
>> -
>>   menuconfig EXPERT
>>       bool "Configure standard U-Boot features (expert users)"
>>       default y
>> diff --git a/Makefile b/Makefile
>> index 7d910b3682..ed7e12120f 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -797,7 +797,7 @@ BOARD_SIZE_CHECK =
>>   endif
>>     ifneq ($(CONFIG_SPL_SIZE_LIMIT),0)
>> -SPL_SIZE_CHECK = @$(call size_check,$@,$(CONFIG_SPL_SIZE_LIMIT))
>> +SPL_SIZE_CHECK = @$(call size_check,$@,$$(tools/spl_size_limit))
>>   else
>>   SPL_SIZE_CHECK =
>>   endif
>> @@ -1779,6 +1779,7 @@ checkarmreloc: u-boot
>>   envtools: scripts_basic $(version_h) $(timestamp_h)
>>       $(Q)$(MAKE) $(build)=tools/env
>>   +tools-only: export TOOLS_ONLY=y
>>   tools-only: scripts_basic $(version_h) $(timestamp_h)
>>       $(Q)$(MAKE) $(build)=tools
>>   diff --git a/common/spl/Kconfig b/common/spl/Kconfig
>> index c7cd34449a..6a98536f20 100644
>> --- a/common/spl/Kconfig
>> +++ b/common/spl/Kconfig
>> @@ -25,6 +25,42 @@ config SPL_FRAMEWORK
>>         supports MMC, NAND and YMODEM and other methods loading of 
>> U-Boot
>>         and the Linux Kernel.  If unsure, say Y.
>>   +config SPL_SIZE_LIMIT
>> +    hex "Maximum size of SPL image"
>> +    depends on SPL
>> +    default 0
>> +    help
>> +      Specifies the maximum length of the U-Boot SPL image.
>> +      If this value is zero, it is ignored.
>> +
>> +config SPL_SIZE_LIMIT_SUBTRACT_GD
>> +    bool "SPL image size check: provide space for global data"
>> +    depends on SPL_SIZE_LIMIT > 0
>> +    help
>> +      If enabled, aligned size of global data is reserved in
>> +      SPL_SIZE_LIMIT check to ensure such an image does not overflow 
>> SRAM
>> +      if SPL_SIZE_LIMIT describes the size of SRAM available for SPL 
>> when
>> +      pre-reloc global data is put into this SRAM, too.
>> +
>> +config SPL_SIZE_LIMIT_SUBTRACT_MALLOC
>> +    bool "SPL image size check: provide space for malloc() pool 
>> before relocation"
>> +    depends on SPL_SIZE_LIMIT > 0
>> +    help
>> +      If enabled, SPL_SYS_MALLOC_F_LEN is reserved in SPL_SIZE_LIMIT 
>> check
>> +      to ensure such an image does not overflow SRAM if SPL_SIZE_LIMIT
>> +      describes the size of SRAM available for SPL when pre-reloc 
>> malloc
>> +      pool is put into this SRAM, too.
>> +
>> +config SPL_SIZE_LIMIT_PROVIDE_STACK
>> +    hex "SPL image size check: provide stack space before relocation"
>> +    depends on SPL_SIZE_LIMIT > 0
>> +    default 0
>> +    help
>> +      If set, this size is reserved in SPL_SIZE_LIMIT check to 
>> ensure such
>> +      an image does not overflow SRAM if SPL_SIZE_LIMIT describes 
>> the size
>> +      of SRAM available for SPL when the stack required before 
>> reolcation
>> +      uses this SRAM, too.
>> +
>>   config HANDOFF
>>       bool "Pass hand-off information from SPL to U-Boot proper"
>>       depends on BLOBLIST
>> diff --git a/tools/Makefile b/tools/Makefile
>> index e2f572cae1..33e90a8025 100644
>> --- a/tools/Makefile
>> +++ b/tools/Makefile
>> @@ -199,6 +199,10 @@ hostprogs-$(CONFIG_RISCV) += prelink-riscv
>>   hostprogs-y += fdtgrep
>>   fdtgrep-objs += $(LIBFDT_OBJS) fdtgrep.o
>>   +ifneq ($(TOOLS_ONLY),y)
>> +hostprogs-y += spl_size_limit
>> +endif
>> +
>>   hostprogs-$(CONFIG_MIPS) += mips-relocs
>>     # We build some files with extra pedantic flags to try to 
>> minimize things
>> diff --git a/tools/spl_size_limit.c b/tools/spl_size_limit.c
>> new file mode 100644
>> index 0000000000..98ff491867
>> --- /dev/null
>> +++ b/tools/spl_size_limit.c
>> @@ -0,0 +1,30 @@
>> +// SPDX-License-Identifier: GPL-2.0+
>> +/*
>> + * Copyright (c) 2019, Simon Goldschmidt 
>> <simon.k.r.goldschmidt@gmail.com>
>> + *
>> + * This tool helps to return the size available for SPL image during 
>> build
>> + */
>> +
>> +#include <generated/autoconf.h>
>> +#include <generated/generic-asm-offsets.h>
>> +
>> +int main(int argc, char *argv[])
>> +{
>> +    int spl_size_limit = 0;
>> +
>> +#ifdef CONFIG_SPL_SIZE_LIMIT
>> +    spl_size_limit = CONFIG_SPL_SIZE_LIMIT;
>> +#ifdef CONFIG_SPL_SIZE_LIMIT_SUBTRACT_GD
>> +    spl_size_limit -= GENERATED_GBL_DATA_SIZE;
>> +#endif
>> +#ifdef CONFIG_SPL_SIZE_LIMIT_SUBTRACT_MALLOC
>> +    spl_size_limit -= CONFIG_SPL_SYS_MALLOC_F_LEN;
>> +#endif
>> +#ifdef CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK
>> +    spl_size_limit -= CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK;
>> +#endif
>> +#endif
>> +
>> +    printf("%d", spl_size_limit);
>> +    return 0;
>> +}
>>
>
>
Tom Rini May 27, 2019, 2:54 p.m. UTC | #4
On Mon, May 27, 2019 at 03:47:13PM +0200, Jean-Jacques Hiblot wrote:
> Simon,
> 
> 
> On 24/05/2019 22:10, Simon Goldschmidt wrote:
> >Am 24.05.2019 um 22:07 schrieb Simon Goldschmidt:
> >>This adds a size check for SPL that can dynamically check generated
> >>SPL binaries (including devicetree) for a size limit that ensures
> >>this image plus global data, heap and stack fit in initial SRAM.
> >>
> >>Since some of these sizes are not available to make, a new host tool
> >>'spl_size_limit' is added that dumps the resulting maximum size for
> >>an SPL binary to stdout. This tool is used in toplevel Makefile to
> >>implement the size check on SPL binaries.
> >>
> >>Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
> >>---
> >>
> >>Changes in v3:
> >>- don't build this new tools for 'make tools-only'
> >
> >So this is how far I got.
> >
> >Tom, your idea with making this multi-config aware (U-Boot, SPL and TPL)
> >does not seem to work as 'tools' are only built once, not once per
> >U-Boot/SPL/TPL. So if we wanted to use this for TPL, too, that would
> >either mean create yet another tool or pass an option to this new tool to
> >differ between SPL and TPL.
> 
> If the trouble comes from GENERATED_GBL_DATA_SIZE, you could get its value
> by parsing lib/asm-offsets.s. all the other values could be extracted from
> {.,spl,tpl}/u-boot.cfg

Getting that file to exist has the same problem over for "tools-only".

> If this flies, it could be done by a python script without the need to
> compile a program

I'm not sure that provides better clarity over what we have here tho.
Thanks!
Simon Goldschmidt May 27, 2019, 3:15 p.m. UTC | #5
Tom Rini <trini@konsulko.com> schrieb am Mo., 27. Mai 2019, 16:54:

> On Mon, May 27, 2019 at 03:47:13PM +0200, Jean-Jacques Hiblot wrote:
> > Simon,
> >
> >
> > On 24/05/2019 22:10, Simon Goldschmidt wrote:
> > >Am 24.05.2019 um 22:07 schrieb Simon Goldschmidt:
> > >>This adds a size check for SPL that can dynamically check generated
> > >>SPL binaries (including devicetree) for a size limit that ensures
> > >>this image plus global data, heap and stack fit in initial SRAM.
> > >>
> > >>Since some of these sizes are not available to make, a new host tool
> > >>'spl_size_limit' is added that dumps the resulting maximum size for
> > >>an SPL binary to stdout. This tool is used in toplevel Makefile to
> > >>implement the size check on SPL binaries.
> > >>
> > >>Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
> > >>---
> > >>
> > >>Changes in v3:
> > >>- don't build this new tools for 'make tools-only'
> > >
> > >So this is how far I got.
> > >
> > >Tom, your idea with making this multi-config aware (U-Boot, SPL and TPL)
> > >does not seem to work as 'tools' are only built once, not once per
> > >U-Boot/SPL/TPL. So if we wanted to use this for TPL, too, that would
> > >either mean create yet another tool or pass an option to this new tool
> to
> > >differ between SPL and TPL.
> >
> > If the trouble comes from GENERATED_GBL_DATA_SIZE, you could get its
> value
> > by parsing lib/asm-offsets.s. all the other values could be extracted
> from
> > {.,spl,tpl}/u-boot.cfg
>
> Getting that file to exist has the same problem over for "tools-only".
>
> > If this flies, it could be done by a python script without the need to
> > compile a program
>
> I'm not sure that provides better clarity over what we have here tho.
>

I also think a python script would be less clear than a C tool. But it
could have the problem hidden by not being used for "tools-only" - it would
only be executed after linking SPL...

Regrds,
Simon
Masahiro Yamada May 27, 2019, 4:35 p.m. UTC | #6
On Sat, May 25, 2019 at 5:07 AM Simon Goldschmidt
<simon.k.r.goldschmidt@gmail.com> wrote:
>
> This adds a size check for SPL that can dynamically check generated
> SPL binaries (including devicetree) for a size limit that ensures
> this image plus global data, heap and stack fit in initial SRAM.
>
> Since some of these sizes are not available to make, a new host tool
> 'spl_size_limit' is added that dumps the resulting maximum size for
> an SPL binary to stdout. This tool is used in toplevel Makefile to
> implement the size check on SPL binaries.
>
> Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
> ---

Some architectures have SPL size checks.
CONFIG_SPL_MAX_FOOTPRINT
CONFIG_SPL_MAX_SIZE
CONFIG_SPL_BSS_MAX_SIZE

Will they be replaced by this new mechanism?
Tom Rini May 27, 2019, 4:48 p.m. UTC | #7
On Tue, May 28, 2019 at 01:35:52AM +0900, Masahiro Yamada wrote:
> On Sat, May 25, 2019 at 5:07 AM Simon Goldschmidt
> <simon.k.r.goldschmidt@gmail.com> wrote:
> >
> > This adds a size check for SPL that can dynamically check generated
> > SPL binaries (including devicetree) for a size limit that ensures
> > this image plus global data, heap and stack fit in initial SRAM.
> >
> > Since some of these sizes are not available to make, a new host tool
> > 'spl_size_limit' is added that dumps the resulting maximum size for
> > an SPL binary to stdout. This tool is used in toplevel Makefile to
> > implement the size check on SPL binaries.
> >
> > Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
> > ---
> 
> Some architectures have SPL size checks.
> CONFIG_SPL_MAX_FOOTPRINT
> CONFIG_SPL_MAX_SIZE
> CONFIG_SPL_BSS_MAX_SIZE
> 
> Will they be replaced by this new mechanism?

Yes, as the existing checks are only sufficient for final link time
overflows and not final image overflows.
Simon Goldschmidt May 27, 2019, 7:28 p.m. UTC | #8
Am 27.05.2019 um 18:48 schrieb Tom Rini:
> On Tue, May 28, 2019 at 01:35:52AM +0900, Masahiro Yamada wrote:
>> On Sat, May 25, 2019 at 5:07 AM Simon Goldschmidt
>> <simon.k.r.goldschmidt@gmail.com> wrote:
>>>
>>> This adds a size check for SPL that can dynamically check generated
>>> SPL binaries (including devicetree) for a size limit that ensures
>>> this image plus global data, heap and stack fit in initial SRAM.
>>>
>>> Since some of these sizes are not available to make, a new host tool
>>> 'spl_size_limit' is added that dumps the resulting maximum size for
>>> an SPL binary to stdout. This tool is used in toplevel Makefile to
>>> implement the size check on SPL binaries.
>>>
>>> Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
>>> ---
>>
>> Some architectures have SPL size checks.
>> CONFIG_SPL_MAX_FOOTPRINT
>> CONFIG_SPL_MAX_SIZE
>> CONFIG_SPL_BSS_MAX_SIZE
>>
>> Will they be replaced by this new mechanism?
> 
> Yes, as the existing checks are only sufficient for final link time
> overflows and not final image overflows.

This patch builds on Heinrich Schuchardt's series that add 
CONFIG_SPL_SIZE_LIMIT to check maximum image size (after potentially 
adding image headers):

https://patchwork.ozlabs.org/patch/1074741/

I just now realize I have forgotton to add that dependency to the patch 
mail.

However, we do have numerous max size defines. This patch tries to bring 
a better calculation for the maximum SPL image size by taking SRAM size 
and subtracting what's required in addition to the binary size.

In general, the different max size defines could need a cleanup as well, 
I guess...

Regards,
Simon
Jean-Jacques Hiblot May 28, 2019, 3:18 p.m. UTC | #9
On 27/05/2019 17:15, Simon Goldschmidt wrote:
>
>
> Tom Rini <trini@konsulko.com <mailto:trini@konsulko.com>> schrieb am 
> Mo., 27. Mai 2019, 16:54:
>
>     On Mon, May 27, 2019 at 03:47:13PM +0200, Jean-Jacques Hiblot wrote:
>     > Simon,
>     >
>     >
>     > On 24/05/2019 22:10, Simon Goldschmidt wrote:
>     > >Am 24.05.2019 um 22:07 schrieb Simon Goldschmidt:
>     > >>This adds a size check for SPL that can dynamically check
>     generated
>     > >>SPL binaries (including devicetree) for a size limit that ensures
>     > >>this image plus global data, heap and stack fit in initial SRAM.
>     > >>
>     > >>Since some of these sizes are not available to make, a new
>     host tool
>     > >>'spl_size_limit' is added that dumps the resulting maximum
>     size for
>     > >>an SPL binary to stdout. This tool is used in toplevel Makefile to
>     > >>implement the size check on SPL binaries.
>     > >>
>     > >>Signed-off-by: Simon Goldschmidt
>     <simon.k.r.goldschmidt@gmail.com
>     <mailto:simon.k.r.goldschmidt@gmail.com>>
>     > >>---
>     > >>
>     > >>Changes in v3:
>     > >>- don't build this new tools for 'make tools-only'
>     > >
>     > >So this is how far I got.
>     > >
>     > >Tom, your idea with making this multi-config aware (U-Boot, SPL
>     and TPL)
>     > >does not seem to work as 'tools' are only built once, not once per
>     > >U-Boot/SPL/TPL. So if we wanted to use this for TPL, too, that
>     would
>     > >either mean create yet another tool or pass an option to this
>     new tool to
>     > >differ between SPL and TPL.
>     >
>     > If the trouble comes from GENERATED_GBL_DATA_SIZE, you could get
>     its value
>     > by parsing lib/asm-offsets.s. all the other values could be
>     extracted from
>     > {.,spl,tpl}/u-boot.cfg
>
>     Getting that file to exist has the same problem over for "tools-only".
>
>     > If this flies, it could be done by a python script without the
>     need to
>     > compile a program
>
>     I'm not sure that provides better clarity over what we have here tho.
>
>
> I also think a python script would be less clear than a C tool. But it 
> could have the problem hidden by not being used for "tools-only" - it 
> would only be executed after linking SPL...

Yes that is  what I was trying to express.

Below is an draft of what I had in mind. Admittedly it less clear than 
the C file.

JJ

>
> Regrds,
> Simon


  Makefile                |  2 +-

  tools/spl_size_limit.py | 51 +++++++++++++++++++++++++++++++++++++++++
  2 files changed, 52 insertions(+), 1 deletion(-)
  create mode 100755 tools/spl_size_limit.py

diff --git a/Makefile b/Makefile
index 8de3d4120a..440ea1da2d 100644
--- a/Makefile
+++ b/Makefile
@@ -797,7 +797,7 @@ BOARD_SIZE_CHECK =
  endif

  ifneq ($(CONFIG_SPL_SIZE_LIMIT),0)
-SPL_SIZE_CHECK = @$(call size_check,$@,$$(tools/spl_size_limit))
+SPL_SIZE_CHECK = $(call size_check,$@,$$($(src)/tools/spl_size_limit.py 
SPL))
  else
  SPL_SIZE_CHECK =
  endif
diff --git a/tools/spl_size_limit.py b/tools/spl_size_limit.py
new file mode 100755
index 0000000000..2c40f5701e
--- /dev/null
+++ b/tools/spl_size_limit.py
@@ -0,0 +1,51 @@
+#! /usr/bin/env python
+import os
+import sys
+
+binary_types = {"U-BOOT":("","./"), "SPL":("SPL_","spl/"), 
"TPL":("TPL_","tpl/")}
+
+def get_from_file(f, pattern):
+    for l in f.readlines():
+        if l.startswith(pattern):
+            return l[len(pattern):].strip()
+    return None
+
+def get_from_cfg_file(bintype, name):
+    pattern = '#define CONFIG_{}{} '.format(binary_types[bintype][0], name)
+    with open("{}u-boot.cfg".format(binary_types[bintype][1])) as f:
+        return get_from_file(f, pattern)
+
+def get_from_header(fname, name):
+    pattern = '#define {} '.format(name)
+    with open("{}".format(fname)) as f:
+        return get_from_file(f, pattern).split()[0]
+
+def usage():
+    print("usage: {} [SPL|TPL]")
+    sys.exit(1)
+
+if len(sys.argv) != 2 and len(sys.argv) != 1:
+    usage()
+if len(sys.argv) == 2 and sys.argv[1] not in binary_types.keys():
+    usage()
+
+bintype = sys.argv[1]
+
+gbl_data_size = 
int(get_from_header("include/generated/generic-asm-offsets.h",
+                    "GENERATED_GBL_DATA_SIZE"), 0)
+size_limit_subtract_gd = get_from_cfg_file(bintype, 
"SIZE_LIMIT_SUBTRACT_GD")
+size_limit_subtract_malloc = get_from_cfg_file(bintype,
+                           "SIZE_LIMIT_SUBTRACT_MALLOC")
+sys_malloc_f_len = int(get_from_cfg_file(bintype, "SYS_MALLOC_F_LEN"), 0)
+size_limit_provide_stack = get_from_cfg_file(bintype,
+                         "SIZE_LIMIT_PROVIDE_STACK")
+
+size_limit = int(get_from_cfg_file(bintype, "SIZE_LIMIT"), 0)
+if size_limit_subtract_gd:
+    size_limit = size_limit - gbl_data_size
+if size_limit_subtract_malloc:
+    size_limit = size_limit - sys_malloc_f_len
+if size_limit_provide_stack:
+    size_limit = size_limit - int(size_limit_provide_stack, 0)
+
+print(size_limit)
Simon Goldschmidt May 28, 2019, 3:51 p.m. UTC | #10
Am 28.05.2019 um 17:18 schrieb Jean-Jacques Hiblot:
> 
> On 27/05/2019 17:15, Simon Goldschmidt wrote:
>>
>>
>> Tom Rini <trini@konsulko.com <mailto:trini@konsulko.com>> schrieb am 
>> Mo., 27. Mai 2019, 16:54:
>>
>>     On Mon, May 27, 2019 at 03:47:13PM +0200, Jean-Jacques Hiblot wrote:
>>     > Simon,
>>     >
>>     >
>>     > On 24/05/2019 22:10, Simon Goldschmidt wrote:
>>     > >Am 24.05.2019 um 22:07 schrieb Simon Goldschmidt:
>>     > >>This adds a size check for SPL that can dynamically check
>>     generated
>>     > >>SPL binaries (including devicetree) for a size limit that ensures
>>     > >>this image plus global data, heap and stack fit in initial SRAM.
>>     > >>
>>     > >>Since some of these sizes are not available to make, a new
>>     host tool
>>     > >>'spl_size_limit' is added that dumps the resulting maximum
>>     size for
>>     > >>an SPL binary to stdout. This tool is used in toplevel Makefile to
>>     > >>implement the size check on SPL binaries.
>>     > >>
>>     > >>Signed-off-by: Simon Goldschmidt
>>     <simon.k.r.goldschmidt@gmail.com
>>     <mailto:simon.k.r.goldschmidt@gmail.com>>
>>     > >>---
>>     > >>
>>     > >>Changes in v3:
>>     > >>- don't build this new tools for 'make tools-only'
>>     > >
>>     > >So this is how far I got.
>>     > >
>>     > >Tom, your idea with making this multi-config aware (U-Boot, SPL
>>     and TPL)
>>     > >does not seem to work as 'tools' are only built once, not once per
>>     > >U-Boot/SPL/TPL. So if we wanted to use this for TPL, too, that
>>     would
>>     > >either mean create yet another tool or pass an option to this
>>     new tool to
>>     > >differ between SPL and TPL.
>>     >
>>     > If the trouble comes from GENERATED_GBL_DATA_SIZE, you could get
>>     its value
>>     > by parsing lib/asm-offsets.s. all the other values could be
>>     extracted from
>>     > {.,spl,tpl}/u-boot.cfg
>>
>>     Getting that file to exist has the same problem over for "tools-only".
>>
>>     > If this flies, it could be done by a python script without the
>>     need to
>>     > compile a program
>>
>>     I'm not sure that provides better clarity over what we have here tho.
>>
>>
>> I also think a python script would be less clear than a C tool. But it 
>> could have the problem hidden by not being used for "tools-only" - it 
>> would only be executed after linking SPL...
> 
> Yes that is  what I was trying to express.
> 
> Below is an draft of what I had in mind. Admittedly it less clear than 
> the C file.

If it works, then it's ok for me (maybe with a little added 
documentation to make it cleare). I'm not at all obsessed by my version :-)

Regards,
Simon

> 
> JJ
> 
>>
>> Regrds,
>> Simon
> 
> 
>   Makefile                |  2 +-
> 
>   tools/spl_size_limit.py | 51 +++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 52 insertions(+), 1 deletion(-)
>   create mode 100755 tools/spl_size_limit.py
> 
> diff --git a/Makefile b/Makefile
> index 8de3d4120a..440ea1da2d 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -797,7 +797,7 @@ BOARD_SIZE_CHECK =
>   endif
> 
>   ifneq ($(CONFIG_SPL_SIZE_LIMIT),0)
> -SPL_SIZE_CHECK = @$(call size_check,$@,$$(tools/spl_size_limit))
> +SPL_SIZE_CHECK = $(call size_check,$@,$$($(src)/tools/spl_size_limit.py 
> SPL))
>   else
>   SPL_SIZE_CHECK =
>   endif
> diff --git a/tools/spl_size_limit.py b/tools/spl_size_limit.py
> new file mode 100755
> index 0000000000..2c40f5701e
> --- /dev/null
> +++ b/tools/spl_size_limit.py
> @@ -0,0 +1,51 @@
> +#! /usr/bin/env python
> +import os
> +import sys
> +
> +binary_types = {"U-BOOT":("","./"), "SPL":("SPL_","spl/"), 
> "TPL":("TPL_","tpl/")}
> +
> +def get_from_file(f, pattern):
> +    for l in f.readlines():
> +        if l.startswith(pattern):
> +            return l[len(pattern):].strip()
> +    return None
> +
> +def get_from_cfg_file(bintype, name):
> +    pattern = '#define CONFIG_{}{} '.format(binary_types[bintype][0], name)
> +    with open("{}u-boot.cfg".format(binary_types[bintype][1])) as f:
> +        return get_from_file(f, pattern)
> +
> +def get_from_header(fname, name):
> +    pattern = '#define {} '.format(name)
> +    with open("{}".format(fname)) as f:
> +        return get_from_file(f, pattern).split()[0]
> +
> +def usage():
> +    print("usage: {} [SPL|TPL]")
> +    sys.exit(1)
> +
> +if len(sys.argv) != 2 and len(sys.argv) != 1:
> +    usage()
> +if len(sys.argv) == 2 and sys.argv[1] not in binary_types.keys():
> +    usage()
> +
> +bintype = sys.argv[1]
> +
> +gbl_data_size = 
> int(get_from_header("include/generated/generic-asm-offsets.h",
> +                    "GENERATED_GBL_DATA_SIZE"), 0)
> +size_limit_subtract_gd = get_from_cfg_file(bintype, 
> "SIZE_LIMIT_SUBTRACT_GD")
> +size_limit_subtract_malloc = get_from_cfg_file(bintype,
> +                           "SIZE_LIMIT_SUBTRACT_MALLOC")
> +sys_malloc_f_len = int(get_from_cfg_file(bintype, "SYS_MALLOC_F_LEN"), 0)
> +size_limit_provide_stack = get_from_cfg_file(bintype,
> +                         "SIZE_LIMIT_PROVIDE_STACK")
> +
> +size_limit = int(get_from_cfg_file(bintype, "SIZE_LIMIT"), 0)
> +if size_limit_subtract_gd:
> +    size_limit = size_limit - gbl_data_size
> +if size_limit_subtract_malloc:
> +    size_limit = size_limit - sys_malloc_f_len
> +if size_limit_provide_stack:
> +    size_limit = size_limit - int(size_limit_provide_stack, 0)
> +
> +print(size_limit)
> --
Tom Rini June 7, 2019, 10:05 p.m. UTC | #11
On Fri, May 24, 2019 at 10:07:04PM +0200, Simon Goldschmidt wrote:

> This adds a size check for SPL that can dynamically check generated
> SPL binaries (including devicetree) for a size limit that ensures
> this image plus global data, heap and stack fit in initial SRAM.
> 
> Since some of these sizes are not available to make, a new host tool
> 'spl_size_limit' is added that dumps the resulting maximum size for
> an SPL binary to stdout. This tool is used in toplevel Makefile to
> implement the size check on SPL binaries.
> 
> Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>

Applied to u-boot/master, thanks!
diff mbox series

Patch

diff --git a/Kconfig b/Kconfig
index 1221d1af69..5f5c5ccfd6 100644
--- a/Kconfig
+++ b/Kconfig
@@ -172,14 +172,6 @@  config TPL_SYS_MALLOC_F_LEN
 	  particular needs this to operate, so that it can allocate the
 	  initial serial device and any others that are needed.
 
-config SPL_SIZE_LIMIT
-	int "Maximum size of SPL image"
-	depends on SPL
-	default 0
-	help
-	  Specifies the maximum length of the U-Boot SPL image.
-	  If this value is zero, it is ignored.
-
 menuconfig EXPERT
 	bool "Configure standard U-Boot features (expert users)"
 	default y
diff --git a/Makefile b/Makefile
index 7d910b3682..ed7e12120f 100644
--- a/Makefile
+++ b/Makefile
@@ -797,7 +797,7 @@  BOARD_SIZE_CHECK =
 endif
 
 ifneq ($(CONFIG_SPL_SIZE_LIMIT),0)
-SPL_SIZE_CHECK = @$(call size_check,$@,$(CONFIG_SPL_SIZE_LIMIT))
+SPL_SIZE_CHECK = @$(call size_check,$@,$$(tools/spl_size_limit))
 else
 SPL_SIZE_CHECK =
 endif
@@ -1779,6 +1779,7 @@  checkarmreloc: u-boot
 envtools: scripts_basic $(version_h) $(timestamp_h)
 	$(Q)$(MAKE) $(build)=tools/env
 
+tools-only: export TOOLS_ONLY=y
 tools-only: scripts_basic $(version_h) $(timestamp_h)
 	$(Q)$(MAKE) $(build)=tools
 
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index c7cd34449a..6a98536f20 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -25,6 +25,42 @@  config SPL_FRAMEWORK
 	  supports MMC, NAND and YMODEM and other methods loading of U-Boot
 	  and the Linux Kernel.  If unsure, say Y.
 
+config SPL_SIZE_LIMIT
+	hex "Maximum size of SPL image"
+	depends on SPL
+	default 0
+	help
+	  Specifies the maximum length of the U-Boot SPL image.
+	  If this value is zero, it is ignored.
+
+config SPL_SIZE_LIMIT_SUBTRACT_GD
+	bool "SPL image size check: provide space for global data"
+	depends on SPL_SIZE_LIMIT > 0
+	help
+	  If enabled, aligned size of global data is reserved in
+	  SPL_SIZE_LIMIT check to ensure such an image does not overflow SRAM
+	  if SPL_SIZE_LIMIT describes the size of SRAM available for SPL when
+	  pre-reloc global data is put into this SRAM, too.
+
+config SPL_SIZE_LIMIT_SUBTRACT_MALLOC
+	bool "SPL image size check: provide space for malloc() pool before relocation"
+	depends on SPL_SIZE_LIMIT > 0
+	help
+	  If enabled, SPL_SYS_MALLOC_F_LEN is reserved in SPL_SIZE_LIMIT check
+	  to ensure such an image does not overflow SRAM if SPL_SIZE_LIMIT
+	  describes the size of SRAM available for SPL when pre-reloc malloc
+	  pool is put into this SRAM, too.
+
+config SPL_SIZE_LIMIT_PROVIDE_STACK
+	hex "SPL image size check: provide stack space before relocation"
+	depends on SPL_SIZE_LIMIT > 0
+	default 0
+	help
+	  If set, this size is reserved in SPL_SIZE_LIMIT check to ensure such
+	  an image does not overflow SRAM if SPL_SIZE_LIMIT describes the size
+	  of SRAM available for SPL when the stack required before reolcation
+	  uses this SRAM, too.
+
 config HANDOFF
 	bool "Pass hand-off information from SPL to U-Boot proper"
 	depends on BLOBLIST
diff --git a/tools/Makefile b/tools/Makefile
index e2f572cae1..33e90a8025 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -199,6 +199,10 @@  hostprogs-$(CONFIG_RISCV) += prelink-riscv
 hostprogs-y += fdtgrep
 fdtgrep-objs += $(LIBFDT_OBJS) fdtgrep.o
 
+ifneq ($(TOOLS_ONLY),y)
+hostprogs-y += spl_size_limit
+endif
+
 hostprogs-$(CONFIG_MIPS) += mips-relocs
 
 # We build some files with extra pedantic flags to try to minimize things
diff --git a/tools/spl_size_limit.c b/tools/spl_size_limit.c
new file mode 100644
index 0000000000..98ff491867
--- /dev/null
+++ b/tools/spl_size_limit.c
@@ -0,0 +1,30 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019, Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
+ *
+ * This tool helps to return the size available for SPL image during build
+ */
+
+#include <generated/autoconf.h>
+#include <generated/generic-asm-offsets.h>
+
+int main(int argc, char *argv[])
+{
+	int spl_size_limit = 0;
+
+#ifdef CONFIG_SPL_SIZE_LIMIT
+	spl_size_limit = CONFIG_SPL_SIZE_LIMIT;
+#ifdef CONFIG_SPL_SIZE_LIMIT_SUBTRACT_GD
+	spl_size_limit -= GENERATED_GBL_DATA_SIZE;
+#endif
+#ifdef CONFIG_SPL_SIZE_LIMIT_SUBTRACT_MALLOC
+	spl_size_limit -= CONFIG_SPL_SYS_MALLOC_F_LEN;
+#endif
+#ifdef CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK
+	spl_size_limit -= CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK;
+#endif
+#endif
+
+	printf("%d", spl_size_limit);
+	return 0;
+}