[U-Boot-Users] Atmel DataFlash hooks.

Wolfgang Denk wd at denx.de
Sun Jan 28 16:01:36 CET 2007

In message <528646bc0701271419l8069e56nb06bb328cf85b8b7 at mail.gmail.com> you wrote:
> Just for the moment; forget the term 'block device' and forget about
> the current implementation of u-boot.  How significant are the


> difference between the following devices? mmc, CF, IDE HD, SCSI HD,
> DataFlash, memmapped flash, NAND flash, i2c eeprom, USB storage.
> Here's my short list:
> - different block sizes; DataFlash can be written byte at a time;
> while other devices have minimum write sizes.  Some devices need
> blocks to be specifically erased before rewriting.

- some devices can also only be read in blocks of a certain size

- some device can have sectors / blocks write protected,  both  logi-
  cally  (in  U-Boot),  or in hardware; some of these devices come up
  write protected out of reset i. e. you have to unprotect  these  to
  make them writable.

- some devices may require (re-) write operations evey now  and  then
  to avoid data loss.

- some devices must never be wrtitten to when the board resets / loses

- some devices may be "banked"; right now, for example,  we  have  no
  way to access flash devices on systems that need bank switching.

> - memmapped flash can be be read directly on the memory bus; but
> writing requires a special routine
> - Large variation of size, from a few kbytes up to thousands of gigabytes.
> - Some devices are typically partitioned for convenience
> - speed differences
> - large number of

of ???

> The technology varies wildly, but they are all storage devices which
> store of an ordered sequence of bytes.  In every device, the address
> of a single item of data can be boiled down to a single integer.

...assuming your "integer" type has enough bits to address any byte.

> Take a look at the following interface.  For *most* commands; how well
> does this is this api encapsulate those differences for common
> commands?  Assume that device specific commands still exist for things
> that don't fit well into the model.  ie. block erase and protect
> commands.

I don't doubt that you can come up with aninterface that fits more or
less nicely on oll possible tyes of storage media. After all, a  file
is a file is a file, as we all have learnt - haven't we?

IN addition to your own fun inh  designing  nice  interfaces,  please
also  keep  in  minde  the mental welfare of the normal end user, who
thinks of "flash memory" as some simple thing where you can just read
data from.

> open(device) # Prepare for read/write operation
> seek(distance, abs_flag)  # Relative or absolute seek
> read(buffer, count)
> write(buffer, count)
> close() # Operation finished; sync any pending buffers back to disk.

Please keep in mind that this is a boot loader, not an  OS.  One  im-
portant  point  is, and always has been, to keep the memory footprint
small. I often sacrificed beautiful code  for  an  uglier,  but  much
smaller implementation. And I guess I will (have to) do this again.

> Notes:
>    - assume device can only be opened once.  ie. it's a bug to call open() twice


>    - this could be used by commands like mm, md, bootm, etc.  I'm not
> trying to design a full control interface (protect, erase, etc).

Why not? I'm not willing to see such functions dropped.

>    - common commands would typically call open(), seek(),
> read/write(), read/write(), ..., close() before returning to user.
> ie. device would *not* be left open after command completes.

Sounds like a lot of code to implement (code size) and run (execution

>    - should be suitable for partition access too
>    - read/write commands are expected to transparently handle block
> boundaries.  ie. if one byte is written to the middle of a block; the
> write hook should read the block, modify the byte, and keep it
> buffered until it either a read/write/seek() moves to another sector,
> or close() is called.
>    - and yes, I'm just using the each device as a file perspective.

> It's a well established abstraction, so why not here too?

Well, just to name one of the potential issues: U-Boot is designed to
make porting to new hardware as eassy as possible. So we want to have
serial console output as soon as possible. That means that very, very
early in the boot process you will have to read  the  environment  to
read  environment  variables like "baudrate" and some others. In this
stage, we usually don't have a regular stack, we have no BSS, and  we
have  no  writable  data  segment.  In  other  words, we don't have a
regular C environment, only a very primitve subset.  But  *all*  your
new  code  would  have  to  be able to run in this environment. Or we
would need duplicate implementations which is even worse than what we
have today. If you want, you can even go one step further  and  think
about NAND booting, where you have even more severe size restrictions
(for which we don't have a good solution yet).

I don't want to say it's impossible what you usggest, but I  have  to
admit  that  I  cannot see a way to implement this without redefining
the basics of the project.

> Thoughts?  Feel free to tell me if I'm flying too high in the
> stratosphere on this one.

I can't read your altimeter from here, but it seems you did take  off
(i. e. lose ground ;-)

Best regards,

Wolfgang Denk

Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
God made machine language; all the rest is the work of man.

More information about the U-Boot mailing list