[PATCH] env: Leave invalid env for nowhere location

Marek Vasut marex at denx.de
Tue May 25 09:35:32 CEST 2021


On 5/12/21 4:09 PM, Kunihiko Hayashi wrote:
> When CONFIG_ENV_IS_NOWHERE is enabled, env_nowhere_init() sets ENV_INVALID
> to gd->env_valid, and sets default_environment before relocation to
> gd->env_addr. After that, env_init() switches gd->env_valid to ENV_VALID
> by the previous fix.
> 
> If gd->env_valid is ENV_INVALID, env_get_char() returns relocated
> default_environment, however, env_get_char() returns gd->env_addr before
> relocation since gd->env_valid is ENV_VALID, and access to gd->env_addr
> will cause a fault.
> 
> This leaves gd->env_valid as ENV_INVALID for "nowhere" location.

So do I understand this correctly that _after_ relocation, env_init() is 
called and env_init() does not update gd->env_addr to the relocated one?

I would expect that after relocation, if all you have is env_nowhere 
driver, the env_nowhere_init() is called again from the first for() loop 
of env_init() [1], which would set gd->env_valid to ENV_INVALID [1], and 
that for() loop would exit with ret = -ENOENT [2], so then the last part 
of env_init() would check for ret == -ENOENT and update gd->env_addr to 
relocated default_environment [3].

324  int env_init(void)
325  {
326    struct env_driver *drv;
327    int ret = -ENOENT;
328    int prio;
329
330    for (prio = 0; (drv = env_driver_lookup(ENVOP_INIT, prio)); prio++) {
          /* Part [1] */
331      if (!drv->init || !(ret = drv->init()))
332        env_set_inited(drv->location);
333      if (ret == -ENOENT)
334        env_set_inited(drv->location);
335
336      debug("%s: Environment %s init done (ret=%d)\n", __func__,
337            drv->name, ret);
338
          /* Part [2] */
339      if (gd->env_valid == ENV_INVALID)
340        ret = -ENOENT;
341    }
342
343    if (!prio)
344      return -ENODEV;
345
        /* Part [3] */
346    if (ret == -ENOENT) {
          /* This should be relocated default_environment address */
347      gd->env_addr = (ulong)&default_environment[0];
348      gd->env_valid = ENV_VALID;
349
350      return 0;
351    }
352
353    return ret;
354  }

Or am I missing something obvious ?

> diff --git a/env/env.c b/env/env.c
> index e534008..3233172 100644
> --- a/env/env.c
> +++ b/env/env.c
> @@ -336,7 +336,8 @@ int env_init(void)
>   		debug("%s: Environment %s init done (ret=%d)\n", __func__,
>   		      drv->name, ret);
>   
> -		if (gd->env_valid == ENV_INVALID)
> +		if (gd->env_valid == ENV_INVALID
> +		    && drv->location != ENVL_NOWHERE)
>   			ret = -ENOENT;
>   	}


More information about the U-Boot mailing list