[U-Boot] [ RFC ] fastboot protocol support in u-boot

Sebastian Andrzej Siewior bigeasy at linutronix.de
Wed Aug 10 20:07:42 CEST 2011


Hi,

The patch which should come as a reply to this email contains a fastboot
gadget for u-boot. I don't claim that the code has been tested or
anything. I just want to post what I have now and get some feedback on it.

The code uses the "newer" gadget API which is used by the rndis gadget for
instance. The only udc implementing it (as far as I know) is the at91 udc
sitting in cdc-at91 branch [0]. The other udcs in tree (musb for intance)
is using the old interface which is something linux kernel 2.4 time frame.
Since nobody plans to develop a udc for both frameworks I went for the newer
framework.
The gadget uses the same callbacks as the the at91 driver. It additionally
requires usb_gadget_init_udc() and usb_gadget_exit_udc() to be exported by
the driver. This is the ->probe() and ->exit() function from the kernel.
The at91 driver does this in its board-setup code which is something I
don't like.

The fastboot protocol is described in [1]. Let me give a short summary
based on the code I post (which is more or less clean up of [3]). It
implements the protocol with a few extensions:
- ep0 communication is only used for initial enumeration
- one EP-IN BULK and one EP-OUT BULK is required for the communication
  between host and device.
- the device waits until a command is sent by the host. This command is
  acknowledged (either as OKAY or FAIL).
- one command is "download:%08x". Here the Host specifies that it wants to
  send binary data. The gadget does _not_ know the purpose of the data, it
  has to suck it up. Once the transfer is complete the host sends another
  command like "flash:%s" which specifies where to write the earlier
  received data.
- the "boot" command is used to boot the image. The code right now uses the
  do_bootm() function. However the expected format is different from the
  uImage format:
  - it contains phys addr + size of kernel and ram disk.
  - it contains phys addr + size of "second". I don't know its purpose.
    Its user [2] is setting this to zero, the gadget code does not use it.
  - There is tags field. I assume that this are atags but it is also
    unused.
  - it contains a command line and a "name" of the image
  - after the "Android" header, the image follows.
- the "flash" command checks in case of the MMC media for the "sparse"
  header. It is implemented on per-board. Two types are currently
  implemented:
  - CHUNK_TYPE_DONT_CARE: don't not write this part to media
  - CHUNK_TYPE_RAW: write this part 1:1 to media
  A third type is defined only: CHUNK_TYPE_FILL. It looks like RLE i.e.
  avoid sending blocks of 0x00 over the wire but write it to the media.
- There is support for "oem" commands. The "format" sub command is
  passed to the board and creates a partition table on MMC.
  The second sub command is "recovery" which resets the board and starts
  linux from a recovery partition.
- commands "mmcerase" and "mmcwrite". Those seem to serve same purpose as
  "erase" and "flash" if the media is pointing to mmc except that the
  "sparse" case is not considered.
- partitions (name, offset) are loaded from board coded. This looks like
  EFI in [3].

This should list everything fastboot specific unless I forgot something.

One think that I don't like is the fact after "download:" we have have
suck up the complete data stream. An advantage would be if we could write
the data directly to flash/mmc. So we could have two buffers or so and
will USB and MMC/NAND one one buffer is complete.
Another thing is the custom sparse format. I would prefer to pipe the data
via lzo instead. This not only shrinks the amount of 0x00 blocks but also
compresses the data image which in case of MMC is mostly uncompressed.
The boot image format that is used by Andorid is different from uImage but
I don't see any advantages. AFAIK the uImage format is capable of
including kernel + ramdisk into one image.

I've been looking at DFU as an alternative. I think its main problem is
the fact that it is ep0 based which limits the USB packet size to 64bytes
on HighSpeed which makes it slower than necessary.

Given the amount of features we require and the complexity what about
implementing the whole gadget as a user space application with a
minimal root file system? We could have graphical output during the update
process instead some printf on serial line. Only an idea. Linux boots
actually quite fast so it shouldn't be an argument. This would also make
it easy to use ubiformat for nand upates in order not to lose the erase
counters. The userland approach would use same linux udc driver so we
wouldn't have two code basis for same driver which might grow apart.

So, any comments on that? Suggestions? Anything?
I would prefer a solution which is accepted by both projects Das U-Boot
and Android in terms of the protocol and approach (u-boot implementation
vs userland).

[0] git://git.denx.de/u-boot-usb.git
[1] http://android.git.kernel.org/?p=platform/bootloader/legacy.git;a=blob_plain;f=fastboot_protocol.txt;hb=d08c9e9444e2fb688ca4d3c4d807ba69c680fb3c
[2] http://android.git.kernel.org/?p=platform/system/core.git;a=tree;f=fastboot;h=1b8baa394459efbbef44e59c5a5494c2e3f37177;hb=810cf41b6d5b772846bbb16700f8c69f03710e60
[3] git://git.omapzoom.org/repo/u-boot.git

Sebastian



More information about the U-Boot mailing list