[PATCH 0/2] Convert env export and import to use getopt()

Simon Glass sjg at chromium.org
Sat May 23 02:08:25 CEST 2026


Hi Tom,

On Fri, 22 May 2026 at 11:03, Tom Rini <trini at konsulko.com> wrote:
>
> On Wed, May 20, 2026 at 02:12:12PM -0600, Simon Glass wrote:
>
> > U-Boot has had a getopt() implementation for over five years but it is
> > not used much; most commands hand-roll their own argv loops to spot
> > -x style flags. The env export and env import sub-commands have the
> > gnarliest of these parsers in nvedit.c
> >
> > Each one walks every -prefixed argv element by hand, opens an inner
> > loop to split grouped flags and tracks a counter to catch a repeated
> > format flag.
> >
> > This short series converts both sub-commands to getopt(). The mutex
> > check for the format flags is done after the option loop, since it is
> > a per-command rule rather than an option-parsing rule, and the trailing
> > positional list is read straight out of argv from gs.index onwards.
> >
> > There is no functional change. getopt() stops at the first non-option,
> > just as the hand-rolled loops did, so options still have to appear
> > before the positional arguments.
> >
> > Each command gains a 'select GETOPT' so the parser is linked in on
> > boards that do not already enable it.
> >
> > For firefly-rk3399:
> >
> >   03: cmd: nvedit: Use getopt() in env export
> >      aarch64: (for 1/1 boards) all -45.0 rodata +27.0 text -72.0
> >   04: cmd: nvedit: Use getopt() in env import
> >      aarch64: (for 1/1 boards) all -27.0 rodata -55.0 text +28.0
> >
> >
> > Simon Glass (2):
> >   cmd: nvedit: Use getopt() in env export
> >   cmd: nvedit: Use getopt() in env import
> >
> >  cmd/Kconfig  |   2 +
> >  cmd/nvedit.c | 186 +++++++++++++++++++++++----------------------------
> >  env/common.c |   2 +-
> >  3 files changed, 85 insertions(+), 105 deletions(-)
>
> For the record, here's a link to v2:
> https://lore.kernel.org/u-boot/20260519233207.2765755-1-sjg@chromium.org/
> And here's the full size change for firefly-rk3399:
> Summary of 3 commits for 1 boards (1 thread, 12 jobs per thread)
> 01: arm: Fix typo in linker script
>    aarch64:  w+   firefly-rk3399
> +(firefly-rk3399) Image 'simple-bin' is missing external blobs and is non-functional: atf-bl31
> +(firefly-rk3399)
> +(firefly-rk3399) /binman/simple-bin/fit/images/@atf-SEQ/atf-bl31 (atf-bl31):
> +(firefly-rk3399)    See the documentation for your board. You may need to build ARM Trusted
> +(firefly-rk3399)    Firmware and build with BL31=/path/to/bl31.bin
> +(firefly-rk3399) Image 'simple-bin' is missing optional external blobs but is still functional: tee-os
> +(firefly-rk3399) /binman/simple-bin/fit/images/@tee-SEQ/tee-os (tee-os):
> +(firefly-rk3399)    See the documentation for your board. You may need to build Open Portable
> +(firefly-rk3399)    Trusted Execution Environment (OP-TEE) and build with TEE=/path/to/tee.bin
> +(firefly-rk3399) Some images are invalid
> 02: cmd: nvedit: Use getopt() in env export
>    aarch64: (for 1/1 boards) all +883.0 rodata +199.0 text +684.0
>             firefly-rk3399 : all +883 rodata +199 text +684
>                u-boot: add: 5/0, grow: 0/-2 bytes: 1184/-500 (684)
>                  function                                   old     new   delta
>                  __getopt                                     -     520    +520
>                  static.bdinfo_print_all                      -     324    +324
>                  print_eth                                    -     236    +236
>                  print_bi_dram                                -      92     +92
>                  getopt_init_state                            -      12     +12
>                  do_env_export                              548     476     -72
>                  do_bdinfo                                  588     160    -428
> 03: cmd: nvedit: Use getopt() in env import
>    aarch64: (for 1/1 boards) all -27.0 rodata -55.0 text +28.0
>             firefly-rk3399 : all -27 rodata -55 text +28
>                u-boot: add: 0/0, grow: 1/0 bytes: 28/0 (28)
>                  function                                   old     new   delta
>                  do_env_import                              668     696     +28
>
> And so this is why I'm just deferring this until someone has the time to
> pick up and address the underlying problems with this potential
> migration that have been raised in the previous iterations.

That is actually what I am trying to do.

Just to restate, the main question to resolve is whether we are OK
with ~1K of growth in order to have any sort of getopt(). I did find a
way to shave ~200 bytes off it (v2 series), but it is still growth. We
could migrate the less common commands first, to avoid that growth for
most boards, which that seems a little sneaky. Better to decide
whether to use getopt() or not.

If you are asking whether someone can write a getopt() which fits in
500 bytes or less, I don't believe so, but you never know.

This v3 series is mostly about showing that we can likely avoid
(additional) growth for each command which converts.

I won't send it for now, but I did try passing the getopt struct to
each command (instead of argc/argv). That does reduce code size for
each command by about 10-20 bytes, so if we converted all the commands
we would likely break even in the end.

Regards,
Simon


More information about the U-Boot mailing list