[U-Boot] [RFC] skip area in flash/memory commands (cp, cmp, ...)

Objective: Skip an area in memory commands
Example use case: Skip over embedded environment when updating U-Boot
In case of an embedded environment, a complete U-Boot binary consists of two code sections and an environment block in between. In an update flow tftp/erase/cp/cmp conveniently using the complete image, the environment is also overwritten. As the env might contain device specific data, this is not always desirable. Of course, one could overcome this with several approaches, e.g. - provide two distinct U-Boot parts on the tftp server - load the complete image and erase/cp/cmp only the desired parts, either via hardcoded addresses and sizes or via some setexpr magic - other ways I simply missed
While this is sufficent, I'd find it handy to be able to skip an area in the above commands. Possible approaches: - explicit via additional parameters to cp, cmp, etc. - implicit for the embedded environment (confusing and less generic) - based on e.g. some skip_addr, skip_len environment variables or even sets (addr1,addr2 + len1,len2)
There might be other use cases I didn't thought of by now. Also, the command list is probably not complete.
What do you think, worth the effort, acceptable in mainline or over-engineering ?

Le 11/04/2011 20:52, Andreas Pretzsch a écrit :
Objective: Skip an area in memory commands
Example use case: Skip over embedded environment when updating U-Boot
In case of an embedded environment, a complete U-Boot binary consists of two code sections and an environment block in between. In an update flow tftp/erase/cp/cmp conveniently using the complete image, the environment is also overwritten. As the env might contain device specific data, this is not always desirable. Of course, one could overcome this with several approaches, e.g.
- provide two distinct U-Boot parts on the tftp server
- load the complete image and erase/cp/cmp only the desired parts, either via hardcoded addresses and sizes or via some setexpr magic
- other ways I simply missed
While this is sufficent, I'd find it handy to be able to skip an area in the above commands. Possible approaches:
- explicit via additional parameters to cp, cmp, etc.
- implicit for the embedded environment (confusing and less generic)
- based on e.g. some skip_addr, skip_len environment variables or even sets (addr1,addr2 + len1,len2)
There might be other use cases I didn't thought of by now. Also, the command list is probably not complete.
What do you think, worth the effort, acceptable in mainline or over-engineering ?
Over-engineering IMO.
There is a reason why a board defines its environment as embedded, and it is because it wants it applied when flashing a new U-Boot.
But if you really want to keep the existing embedded environment when flashing a new U-Boot, then after you have loaded the new U-Boot in RAM as usual, all you need is to overwrite its environment with the one already in Flash with a single, standard, cp.b instruction. After that you can erase Flash and copy from RAM to Flash as usual.
Amicalement,

Am Montag, den 11.04.2011, 21:31 +0200 schrieb Albert ARIBAUD:
Le 11/04/2011 20:52, Andreas Pretzsch a écrit :
Objective: Skip an area in memory commands
Example use case: Skip over embedded environment when updating U-Boot
In case of an embedded environment, a complete U-Boot binary consists of two code sections and an environment block in between. In an update flow tftp/erase/cp/cmp conveniently using the complete image, the environment is also overwritten. As the env might contain device specific data, this is not always desirable. Of course, one could overcome this with several approaches, e.g.
- provide two distinct U-Boot parts on the tftp server
- load the complete image and erase/cp/cmp only the desired parts, either via hardcoded addresses and sizes or via some setexpr magic
- other ways I simply missed
While this is sufficent, I'd find it handy to be able to skip an area in the above commands. Possible approaches:
- explicit via additional parameters to cp, cmp, etc.
- implicit for the embedded environment (confusing and less generic)
- based on e.g. some skip_addr, skip_len environment variables or even sets (addr1,addr2 + len1,len2)
There might be other use cases I didn't thought of by now. Also, the command list is probably not complete.
What do you think, worth the effort, acceptable in mainline or over-engineering ?
Over-engineering IMO.
There is a reason why a board defines its environment as embedded, and it is because it wants it applied when flashing a new U-Boot.
Or simply not to waste flash when having a few small sectors.
But if you really want to keep the existing embedded environment when flashing a new U-Boot, then after you have loaded the new U-Boot in RAM as usual, all you need is to overwrite its environment with the one already in Flash with a single, standard, cp.b instruction. After that you can erase Flash and copy from RAM to Flash as usual.
ACK. The most obvious and simple approach for this scenario. And rewriting the environment during an U-Boot update doesn't hurt that much either, the possible window of data loss is reasonably small.

Dear Andreas Pretzsch,
In message 1302551856.13241.146.camel@ws-apr.office.loc you wrote:
What do you think, worth the effort, acceptable in mainline or over-engineering ?
Over-engineering IMO.
I agree with Albert here.
There is a reason why a board defines its environment as embedded, and it is because it wants it applied when flashing a new U-Boot.
Or simply not to waste flash when having a few small sectors.
Right, that's exactly why this was invented.
But if you really want to keep the existing embedded environment when flashing a new U-Boot, then after you have loaded the new U-Boot in RAM as usual, all you need is to overwrite its environment with the one already in Flash with a single, standard, cp.b instruction. After that you can erase Flash and copy from RAM to Flash as usual.
ACK. The most obvious and simple approach for this scenario. And
No. It may be obvious, but there are far easier ways.
The most simple way is a sequence of tftp, protect off, erase, cp, and finally saveenv.
As long as your flash layout does not change (and experience shows that these are extremely rare cases) a simple "saveenv" is enough to update your current environment in the freshly written U-Boot image.
For more fancy operations, you can use "env export".
Best regards,
Wolfgang Denk

Am Montag, den 11.04.2011, 23:08 +0200 schrieb Wolfgang Denk:
But if you really want to keep the existing embedded environment when flashing a new U-Boot, then after you have loaded the new U-Boot in RAM as usual, all you need is to overwrite its environment with the one already in Flash with a single, standard, cp.b instruction. After that you can erase Flash and copy from RAM to Flash as usual.
ACK. The most obvious and simple approach for this scenario. And
No. It may be obvious, but there are far easier ways.
The most simple way is a sequence of tftp, protect off, erase, cp, and finally saveenv.
True, but it would pollute the env with transient variables like fileaddr, filesize and serveraddr. Nothing serious, of course. But in case of bootlimit enabled, it would also save "bootcount", which might be a bad idea...
BTW, not sure if it's worth the effort (or a good idea at all), but one might think about a concept of transient variables (in standard parser, not checked hush parser).

Dear Andreas Pretzsch,
In message 1302614926.27200.12.camel@ws-apr.office.loc you wrote:
True, but it would pollute the env with transient variables like fileaddr, filesize and serveraddr. Nothing serious, of course.
Do you really care to delete these before each and every saveenv? Or is your environment so small that you have to worry about 20 or 30 additional bytes?
But in case of bootlimit enabled, it would also save "bootcount", which might be a bad idea...
Why? It does not matter at all.
BTW, not sure if it's worth the effort (or a good idea at all), but one might think about a concept of transient variables (in standard parser, not checked hush parser).
You can use hush, and plain shell variables there.
Best regards,
Wolfgang Denk

Am Dienstag, den 12.04.2011, 16:15 +0200 schrieb Wolfgang Denk:
Dear Andreas Pretzsch,
In message 1302614926.27200.12.camel@ws-apr.office.loc you wrote:
True, but it would pollute the env with transient variables like fileaddr, filesize and serveraddr. Nothing serious, of course.
Do you really care to delete these before each and every saveenv? Or is your environment so small that you have to worry about 20 or 30 additional bytes?
Neither. As stated, pure, irrelevant cosmetics.
But in case of bootlimit enabled, it would also save "bootcount", which might be a bad idea...
Why? It does not matter at all.
ACK. Looked at the code, bootcount is initialized via board-specific bootcount_load(), not from env. So again, pure cosmetics. Sorry for the noise.
participants (3)
-
Albert ARIBAUD
-
Andreas Pretzsch
-
Wolfgang Denk