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%3Ba=blob_pla... [2] http://android.git.kernel.org/?p=platform/system/core.git%3Ba=tree%3Bf=fastb... [3] git://git.omapzoom.org/repo/u-boot.git
Sebastian