[U-Boot] [PATCH] NAND: Support dynamic location of enviromnent (CONFIG_ENV_OFFSET_OOB)
Ben Gardiner
bengardiner at nanometrics.ca
Thu May 27 01:38:28 CEST 2010
Thank you for the thorough review, Scott.
On Wed, May 26, 2010 at 6:58 PM, Scott Wood <scottwood at freescale.com> wrote:
> On Mon, May 17, 2010 at 05:04:30PM -0400, Ben Gardiner wrote:
>> diff --git a/common/cmd_dynenv.c b/common/cmd_dynenv.c
>> new file mode 100644
>> index 0000000..5167875
>> --- /dev/null
>> +++ b/common/cmd_dynenv.c
>> @@ -0,0 +1,112 @@
>> +/*
>> + * (C) Copyright 2006-2007 OpenMoko, Inc.
>> + * Author: Harald Welte <laforge at openmoko.org>
>> + * (C) Copyright 2008 Harald Welte <laforge at openmoko.org>
>
> Is this correct and up-to-date?
The code was taken from Harald's patches he submitted to the mailing
list. I didn't do much to them except to re-factor the 'get'
functionality. Should I have added myself / my organization to the
copyright list? I figured my changes were not enough to warrant the
additional attribution of copyright.
>> +unsigned long env_offset;
>
> This is a pretty generic name for something NAND-specific -- as is "dynenv".
>
> Maybe this should be a nand subcommand? Putting it in cmd_nand.c would also
> eliminate the need to export arg_off_size().
>
I'm glad you brought this up. I was wondering if the command might be
better suited under the nand command -- I agree that it would
eliminate the export of arg_off_size and all the renames, which would
be very nice. Would 'nand dynenv' do? How about 'nand env.oob' ?
>> + if(mtd->oobavail < CONFIG_ENV_OFFSET_SIZE){
>
> Please put a space after "if" and before the opening brace (in fact, there's
> no need for the braces at all on this one-liner).
will do
>> + printf("Insufficient available OOB bytes: %d OOB bytes available but %d required for dynenv support\n",mtd->oobavail,8);
>
> Keep lines under 80 columns (both in source code and in output), and put
> spaces after commas.
sorry about that, I should know better :)
>> + }
>> +
>> + oob_buf = malloc(mtd->oobsize);
>> + if(!oob_buf)
>> + return -ENOMEM;
>
> Let the user know it didn't work?
>
> You only really need 8 bytes, why not just put it on the stack? Likewise in
> get_dynenv().
good ideas
>> + ops.datbuf = NULL;
>> + ops.mode = MTD_OOB_AUTO;
>> + ops.ooboffs = 0;
>> + ops.ooblen = CONFIG_ENV_OFFSET_SIZE;
>> + ops.oobbuf = (void *) oob_buf;
>> +
>> + ret = mtd->read_oob(mtd, CONFIG_ENV_OFFSET_SIZE, &ops);
>> + oob_buf[0] = ENV_OOB_MARKER;
>> +
>> + if (!ret) {
>> + if(addr & ~oob_buf[1]) {
>> + printf("ERROR: erase OOB block 0 to "
>> + "write this value\n");
>
> You cannot erase OOB without erasing the entire block, so this message
> is a little confusing.
>
> Do you really expect to make use of the ability to set a new address
> without erasing, if it only clears bits?
No, I suppose not. The main use-case seems to be 'dynenv set' on a
freshly erased nand when using u-boot for programming. OTOH I have
noticed that (one of) the nand erase utility that comes with the TI
OMAP L138 EVM erases the NAND w/o erasing the OOB; so it was useful
during testing to know if I was able to write the correct value to the
OOB. I could replace this with a read-back check to accomplish the
same task -- this will also make 'set' commit the new offset 'live'
(see below)
>> + ret = mtd->write_oob(mtd, CONFIG_ENV_OFFSET_SIZE, &ops);
>> + if (!ret)
>> + CONFIG_ENV_OFFSET = addr;
>> + else {
>> + printf("Error writing OOB block 0\n");
>> + goto fail;
>> + }
>
> If you put braces on one side of the else, put them on both.
>
>> +
>> + free(oob_buf);
>> + } else
>> + goto usage;
>
> Likewise.
will do
> Is there anything you can do on "dynenv set" so that the user won't have to
> reboot after setting the dynenv to be able to saveenv into the new
> environment?
Good catch. Yes I think this could also be handled by replacing the
OOB bit-check with a call and check of the 'dynenv get' command after
set. In this way the global variable that has been swapped inplace of
CONFIG_ENV_OFFSET will have the value of the newly set dynamic
environment.
>> +U_BOOT_CMD(dynenv, 4, 1, do_dynenv,
>> + "dynenv - dynamically placed (NAND) environment",
>> + "set off - set enviromnent offset\n"
>> + "dynenv get - get environment offset");
>> \ No newline at end of file
>
> Please put a newline at the end of the file.
sorry I really should have caught that one.
>> diff --git a/common/cmd_nand.h b/common/cmd_nand.h
>> new file mode 100644
>> index 0000000..023ed4f
>> --- /dev/null
>> +++ b/common/cmd_nand.h
>> @@ -0,0 +1,33 @@
>> +/*
>> + * cmd_nand.h - Convenience functions
>> + *
>> + * (C) Copyright 2006-2007 OpenMoko, Inc.
>> + * Author: Werner Almesberger <werner at openmoko.org>
>
> Is this really the right copyright/authorship for this file?
see answer above; but this file will be removed in the next version
since I will stick the dynenv command under the nand command.
>> + if(!ret) {
>> + if(oob_buf[0] == ENV_OOB_MARKER) {
>> + *result = oob_buf[1];
>
> Should probably encode the environment location as a block number, rather
> than as a byte, for flashes larger than 4GiB (there are other places in the
> environment handling where this won't work, but let's not add more).
good idea
>> + }
>> + else {
>
> } else {
>
>> #ifdef CONFIG_ENV_OFFSET_REDUND
>> void env_relocate_spec (void)
>> {
>> @@ -357,12 +398,23 @@ void env_relocate_spec (void)
>> #if !defined(ENV_IS_EMBEDDED)
>> int ret;
>>
>> +#if defined(CONFIG_ENV_OFFSET_OOB)
>> + ret = get_dynenv(&CONFIG_ENV_OFFSET);
>
> Taking the address of a macro looks really weird. This will only work if
> the macro is defined as env_offset, so why not just use env_offset?
Yeah... it's pretty weird, I'll subs env_offset here. :)
>> ret = readenv(CONFIG_ENV_OFFSET, (u_char *) env_ptr);
>> if (ret)
>> return use_default();
>>
>> if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc)
>> return use_default();
>> +
>> #endif /* ! ENV_IS_EMBEDDED */
>
> Unrelated whitespace change, please leave out.
will do
>> #endif /* CONFIG_ENV_OFFSET_REDUND */
>> diff --git a/include/environment.h b/include/environment.h
>> index b9924fd..03b6c92 100644
>> --- a/include/environment.h
>> +++ b/include/environment.h
>> @@ -74,15 +74,24 @@
>> #endif /* CONFIG_ENV_IS_IN_FLASH */
>>
>> #if defined(CONFIG_ENV_IS_IN_NAND)
>> -# ifndef CONFIG_ENV_OFFSET
>> -# error "Need to define CONFIG_ENV_OFFSET when using CONFIG_ENV_IS_IN_NAND"
>> -# endif
>> +# if defined(CONFIG_ENV_OFFSET_OOB)
>> +# ifdef CONFIG_ENV_OFFSET_REDUND
>> +# error "CONFIG_ENV_OFFSET_REDUND is not supported when CONFIG_ENV_OFFSET_OOB is set"
>> +# endif
>> +extern unsigned long env_offset;
>> +# undef CONFIG_ENV_OFFSET
>> +# define CONFIG_ENV_OFFSET env_offset
>
> Don't undef CONFIG_ENV_OFFSET, we want the build to fail if the user tries
> to do it both ways (just like if CONFIG_ENV_OFFSET_REDUND is specified).
will do
>> +#define CONFIG_ENV_OFFSET_SIZE 8
>
> Why is this configurable?
Can't think of a good reason. I'll just make a #define in a restricted
scope to avoid magic number 8.
Best Regards,
Ben Gardiner
--
Ben Gardiner
Nanometrics Inc.
+1 (613) 592-6776 x239
http://www.nanometrics.ca
More information about the U-Boot
mailing list