[U-Boot] [PATCH] envcrc: extract default environment from target ELF files
Mike Frysinger
vapier at gentoo.org
Fri Jun 19 11:36:12 CEST 2009
On Tuesday 16 June 2009 14:02:16 Wolfgang Denk wrote:
> Mike Frysinger wrote:
> > Rather than rely on dirty hacks to compile the environment on the host
> > and extract the CRC from that, have envcrc extract the environment
> > straight from the ELF object that will be linked into u-boot itself.
> > This makes the envcrc code a bit more complicated, but it simplifies the
> > build process and host requirements because we don't have to try and
> > recreate the environment that the target will be seeing on the host.
> > This avoids some issues that crop up from time to time where the
> > preprocessor defines on the host don't expand in the same way as for the
> > target -- in case the target uses those defines to customize the
> > environment, or the host defines conflicts with some of the target
> > values.
>
> Can you please be a bit more specific about which sort of problems you
> are talking here?
sure ... i'll be verbose so hopefully you can see what i see
> We've been using this code for many years now, but I
> cannot remember any problems with it.
that's because the code paths have slowly acquired platform-specific hacks so
that it kept working :)
at any rate, here's a longer problem description and surrounding issues ...
if the default environment utilizes defines that come from the toolchain in
any level of indirection, the environment that is built into the target u-boot
will not match the environment that is compiled on the host for crc
generation.
a real world example is the unified ADI config header. it generates a default
environment based on functionality actually available. the BF537 family has
networking hardware in some parts, but not all (BF534 does not). so we key
off of the variant to determine whether to enable networking by default. or
we determine that some on-chip rom functions are available for certain
variants and enable only those functions.
so the CPP dependency chain looks something like:
- Blackfin toolchain sets up variant defines
- ADI board headers set up capabilities based on variant defines
- common ADI board header enables some commands based on variant defines
- common ADI board header sets up default environment based on capabilities
and commands available
since the host toolchain does not set up the same CPP dependencies as the
Blackfin toolchain, this tree falls apart and the resulting environment string
that envcrc operates on differs, so the CRCs differ.
i can understand your position of "setting up board configs this way is
wrong", but i've structured it this way because it greatly reduces my
maintenance burden while increasing regression capabilities. for example, i
have a Blackfin-specific patch to the MAKEALL script that allows me to
regression test not only the board-specific configuration, but also uncommon
or otherwise untested cpu and boot mode configurations. for example, the
bf537-stamp defaults to the BF537 cpu and BYPASS boot mode. but now my
regression builds can automatically verify BF534/BF536 cpu code paths as well
as PARALLEL/SPI/NAND/UART code paths. previously, some changes would
accidentally break these uncommon edge cases and wouldnt be noticed until
someone else happened to build. to say that these code paths were horribly
broken most of the time is an understatement :).
i have also seen a case or two where the host toolchain inadvertently expanded
things that ended up in the environment because they were not declared as
strings. for example, many defines are not:
#define CONFIG_FOO "foo"
but rather they are:
#define CONFIG_FOO foo
just grep common/env_*.c for MKSTR() to see just how many things are affected
in this way. having to worry about values here which may be arbitrarily
expanded across host toolchains is a bad design practice imo.
if the environment is only ever compiled by one toolchain, the target one,
then it significantly reduces the chance for unexpected and unwelcomed
surprises. after all, the only way to notice something has gone wrong is to
build the source with a specific host toolchain, burn the image, reset, and
see the dreaded "CRC mismatch, using default environment" error from u-boot.
unless you're familiar with this problem and/or have seen/root caused this
before, attempting to track down the source of this problem can be very time
consuming (as it was the first time i hit this problem).
> > common/Makefile | 4 +-
> > common/env_embedded.c | 30 +---------
> > tools/Makefile | 3 +-
> > tools/envcrc.c | 156
> > ++++++++++++++++++++++++++++++++++++++++++-------
>
> The diffstat indicates that the new solution is more complicated than
> the old one, so I'd like to understand why this is needed (or if).
if LoC are the metric, then yes, but conceptually this change is simpler. the
current behavior requires mixing target u-boot environment headers with the
host toolchain, and a whole bunch of hacks to make sure things actually
compile, produce the same end environment with two vastly different build
environments, and end up with the same crc value. my proposed change means we
only compile 1 environment object -- the one that is going into the target u-
boot binary. we then extract the environment directly from the object which
is actually going into u-boot (so we are absolutely assured that the
environment we are working with on the host matches the target).
hope this clears things up
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20090619/1e3a4b95/attachment-0001.pgp
More information about the U-Boot
mailing list