[U-Boot] [PATCH v1 1/1] fastboot: Add support for flashing zImage

Rob Herring robherring2 at gmail.com
Thu Feb 26 01:30:30 CET 2015


On Wed, Feb 25, 2015 at 4:56 PM, Dileep Katta <dileep.katta at linaro.org> wrote:
> This patch adds support to flash zImage to the boot partition on eMMC.
> Usage: fastboot flash zImage <path_to_zImage>

So this replaces the kernel in an existing bootimage. What's wrong
with "fastboot flash boot", "fastboot flash:raw boot <kernel>" or
"fastboot boot <kernel>"? It is a bit fragile to be updating your
kernel without updating the ramdisk. arm64 has no zImage, so this
command is somewhat arm32 specific.

Fastboot is already plagued with a variety of implementations and
behaviors. Some unification here would be good and just adding
whatever various commands have been added to vendor u-boot's is not
going to help. Adding to the combinations of things to test also
bothers me.

Rob

>
> Signed-off-by: Angela Stegmaier <angelabaker at ti.com>
>
> Signed-off-by: Dileep Katta <dileep.katta at linaro.org>
> ---
>  drivers/usb/gadget/f_fastboot.c | 152 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 152 insertions(+)
>
> diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
> index 310175a..d3d16c0 100644
> --- a/drivers/usb/gadget/f_fastboot.c
> +++ b/drivers/usb/gadget/f_fastboot.c
> @@ -23,6 +23,7 @@
>  #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
>  #include <fb_mmc.h>
>  #endif
> +#include <android_image.h>
>
>  #define FASTBOOT_VERSION               "0.4"
>
> @@ -492,6 +493,152 @@ static void cb_continue(struct usb_ep *ep, struct usb_request *req)
>  }
>
>  #ifdef CONFIG_FASTBOOT_FLASH
> +static int fastboot_update_zimage(void);
> +
> +static u32 fastboot_get_boot_ptn(struct andr_img_hdr *hdr, char *response,
> +                                               block_dev_desc_t *dev_desc)
> +{
> +       u32 hdr_sectors = 0;
> +       u32 sector_size;
> +       int status = 0;
> +       strcpy(response, "OKAY");
> +       disk_partition_t info;
> +
> +       status = get_partition_info_efi_by_name(dev_desc, "boot", &info);
> +       if (status) {
> +               strcpy(response, "FAILCannot find boot partition");
> +               goto out;
> +       }
> +
> +       /* Read the boot image header */
> +       sector_size = info.blksz;
> +       hdr_sectors = (sizeof(struct andr_img_hdr)/sector_size) + 1;
> +       status = dev_desc->block_read(dev_desc->dev, info.start,
> +                                     hdr_sectors, (void *)hdr);
> +
> +       if (status < 0) {
> +               strcpy(response, "FAILCannot read hdr from boot partition");
> +               goto out;
> +       }
> +       if (android_image_check_header(hdr) != 0) {
> +               printf("bad boot image magic\n");
> +               strcpy(response, "FAILBoot partition not initialized");
> +               goto out;
> +       }
> +
> +       return hdr_sectors;
> +
> +out:
> +       strcpy(response, "INFO");
> +       fastboot_tx_write_str(response);
> +
> +       return -1;
> +}
> +
> +#define CEIL(a, b) (((a) / (b)) + ((a % b) > 0 ? 1 : 0))
> +
> +static int fastboot_update_zimage(void)
> +{
> +       struct andr_img_hdr *hdr = NULL;
> +       u8 *ramdisk_buffer;
> +       u32 ramdisk_sector_start, ramdisk_sectors;
> +       u32 kernel_sector_start, kernel_sectors;
> +       u32 hdr_sectors = 0;
> +       u32 sectors_per_page = 0;
> +       int ret = 0;
> +       block_dev_desc_t *dev_desc;
> +       disk_partition_t info;
> +       char response[RESPONSE_LEN];
> +       u32 addr = CONFIG_USB_FASTBOOT_BUF_ADDR;
> +
> +       strcpy(response, "OKAY");
> +       printf("Flashing zImage...%d bytes\n", download_bytes);
> +
> +       dev_desc = get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
> +       if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
> +               sprintf(response + strlen(response),
> +                       "FAILInvalid mmc device");
> +               ret = -1;
> +               goto out;
> +       }
> +
> +       addr += CEIL(download_bytes, 0x1000) * 0x1000;
> +       hdr = (struct andr_img_hdr *)addr;
> +
> +       hdr_sectors = fastboot_get_boot_ptn(hdr, response, dev_desc);
> +       if (hdr_sectors <= 0) {
> +               sprintf(response + strlen(response),
> +                       "FAILInvalid number of boot sectors %d", hdr_sectors);
> +               ret = -1;
> +               goto out;
> +       }
> +       ret = get_partition_info_efi_by_name(dev_desc, "boot", &info);
> +       if (ret) {
> +               strcpy(response, "FAILCannot find boot partition");
> +               ret = -1;
> +               goto out;
> +       }
> +
> +       /* Extract ramdisk location and read it into local buffer */
> +       sectors_per_page = hdr->page_size / info.blksz;
> +       ramdisk_sector_start = info.start + sectors_per_page;
> +       ramdisk_sector_start += CEIL(hdr->kernel_size, hdr->page_size)*
> +                                    sectors_per_page;
> +       ramdisk_sectors = CEIL(hdr->ramdisk_size, hdr->page_size)*
> +                              sectors_per_page;
> +
> +       ramdisk_buffer = (u8 *)hdr;
> +       ramdisk_buffer += (hdr_sectors * info.blksz);
> +       ret = dev_desc->block_read(dev_desc->dev, ramdisk_sector_start,
> +                                  ramdisk_sectors, ramdisk_buffer);
> +       if (ret < 0) {
> +               sprintf(response, "FAILCannot read ramdisk from 'boot'");
> +               ret = -1;
> +               goto out;
> +       }
> +
> +       /* Change the boot img hdr */
> +       hdr->kernel_size = download_bytes;
> +       ret = dev_desc->block_write(dev_desc->dev, info.start,
> +                                   hdr_sectors, (void *)hdr);
> +       if (ret < 0) {
> +               sprintf(response, "FAILCannot writeback boot img hdr");
> +               ret = -1;
> +               goto out;
> +       }
> +
> +       /* Write the new downloaded kernel*/
> +       kernel_sector_start = info.start + sectors_per_page;
> +       kernel_sectors = CEIL(hdr->kernel_size, hdr->page_size)*
> +                             sectors_per_page;
> +       ret = dev_desc->block_write(dev_desc->dev, kernel_sector_start,
> +                                   kernel_sectors,
> +                                   (const void *)CONFIG_USB_FASTBOOT_BUF_ADDR);
> +       if (ret < 0) {
> +               sprintf(response, "FAILCannot write new kernel");
> +               ret = -1;
> +               goto out;
> +       }
> +
> +       /* Write the saved Ramdisk back */
> +       ramdisk_sector_start = info.start + sectors_per_page;
> +       ramdisk_sector_start += CEIL(hdr->kernel_size, hdr->page_size)*
> +                                    sectors_per_page;
> +       ret = dev_desc->block_write(dev_desc->dev, ramdisk_sector_start,
> +                                   ramdisk_sectors, ramdisk_buffer);
> +       if (ret < 0) {
> +               sprintf(response, "FAILCannot write back original ramdisk");
> +               ret = -1;
> +               goto out;
> +       }
> +       fastboot_tx_write_str(response);
> +       return 0;
> +
> +out:
> +       fastboot_tx_write_str(response);
> +       return ret;
> +}
> +
>  static void cb_flash(struct usb_ep *ep, struct usb_request *req)
>  {
>         char *cmd = req->buf;
> @@ -505,6 +652,11 @@ static void cb_flash(struct usb_ep *ep, struct usb_request *req)
>         }
>
>         strcpy(response, "FAILno flash device defined");
> +
> +       if (!strcmp(cmd, "zImage") || !strcmp(cmd, "zimage")) {
> +               fastboot_update_zimage();
> +               return;
> +       }
>  #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
>         fb_mmc_flash_write(cmd, (void *)CONFIG_USB_FASTBOOT_BUF_ADDR,
>                            download_bytes, response);
> --
> 1.8.3.2
>


More information about the U-Boot mailing list