[U-Boot] [PATCH] Save environment data to mmc.

Andy Fleming afleming at gmail.com
Wed Apr 28 15:30:07 CEST 2010


On Wed, Apr 28, 2010 at 2:52 AM, Terry Lv <r65388 at freescale.com> wrote:
> This patch is to save environment data to mmc card.
> It uses interfaces defined in generic mmc.
>
> Signed-off-by: Terry Lv <r65388 at freescale.com>


> diff --git a/common/env_mmc.c b/common/env_mmc.c
> new file mode 100644
> index 0000000..202370e
> --- /dev/null
> +++ b/common/env_mmc.c
> @@ -0,0 +1,160 @@
> +/*
> + * (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
> +
> + * (C) Copyright 2000-2006
> + * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
> + *
> + * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
> + * Andreas Heppel <aheppel at sysgo.de>

Are these non-Freescale copyrights here for a reason, or were they
just copied from somewhere?

> +#ifdef ENV_IS_EMBEDDED
> +extern uchar environment[];
> +env_t *env_ptr = (env_t *)(&environment[0]);
> +#else /* ! ENV_IS_EMBEDDED */
> +env_t *env_ptr;
> +#endif /* ENV_IS_EMBEDDED */

You should probably initialize env_ptr to NULL, here.

> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define BLOCK_ALIGN(x) ((x & (0x200 - 1)) \
> +                        ? ((x >> 9) + 1) : (x >> 9))

No need to reinvent the wheel, here.  This is the same as:

ALIGN(x, 0x200);

See: include/common.h

Also, are you sure the block size is 0x200?  That's a very common
block size, but the MMC spec allows a whole bunch of alternate ones.
You should use the actual value of mmc->read_bl_len and
mmc->write_bl_len;


> +int env_init(void)
> +{
> +       /* use default */
> +       gd->env_addr = (ulong)&default_environment[0];
> +       gd->env_valid = 1;
> +
> +       return 0;
> +}
> +
> +inline int init_mmc_for_env(struct mmc *mmc)

Why is this inlined?  Don't inline a function if there's no good reason.

> +{
> +       if (!mmc) {
> +               puts("No MMC card found\n");
> +               return -1;
> +       }
> +
> +       if (mmc_init(mmc)) {
> +               puts("MMC init failed\n");
> +               return  -1;
> +       }
> +
> +       return 0;
> +}

> +inline int write_env(struct mmc *mmc, unsigned long size,
> +                                               unsigned long offset, const void *buffer)
> +{
> +       uint blk_start = 0, blk_cnt = 0, n = 0;

Don't initialize variables to zero right before assigning them.

> +
> +       blk_start = BLOCK_ALIGN(offset);
> +       blk_cnt   = BLOCK_ALIGN(size);
> +
> +       n = mmc->block_dev.block_write(CONFIG_SYS_MMC_ENV_DEV, blk_start , blk_cnt, (u_char *)buffer);
> +
> +       return (n == blk_cnt) ? 0 : -1;
> +}
> +
> +int saveenv(void)
> +{
> +       struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
> +
> +       if (init_mmc_for_env(mmc))
> +               return 1;
> +
> +       printf("Writing to MMC(%d)... ", CONFIG_SYS_MMC_ENV_DEV);
> +       if (write_env(mmc, CONFIG_ENV_SIZE, \

You don't need that "\".  C does that for you automatically.



> +inline int read_env(struct mmc *mmc, unsigned long size,
> +                                               unsigned long offset, const void *buffer)
> +{
> +       uint blk_start = 0, blk_cnt = 0, n = 0;

Again, don't bother zeroing out values like this.

> +
> +       blk_start = BLOCK_ALIGN(offset);
> +       blk_cnt   = BLOCK_ALIGN(size);
> +
> +       n = mmc->block_dev.block_read(CONFIG_SYS_MMC_ENV_DEV, blk_start, blk_cnt, (uchar *)buffer);
> +
> +       return (n == blk_cnt) ? 0 : -1;
> +}
> +
> +void env_relocate_spec(void)
> +{
> +#if !defined(ENV_IS_EMBEDDED)
> +       struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
> +
> +       if (init_mmc_for_env(mmc))
> +               return;
> +
> +       if (read_env(mmc, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, env_ptr))
> +               return use_default();


This is broken.  env_ptr hasn't been initialized to a value, yet!
This writes to random memory!  env_ptr needs to be malloc'ed.


Andy


More information about the U-Boot mailing list