Skip to contentSkip to conversation

fastboot: Add support for flashing zImage

PATCH New Dileep Katta 4 participants 6 messages Feb 25, 2015 – Mar 12, 2015 USB

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 fastboot: Add support for flashing zImage

This patch adds support to flash zImage to the boot partition on eMMC.
Usage: fastboot flash zImage <path_to_zImage>

---
 drivers/usb/gadget/f_fastboot.c | 152 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 152 insertions(+)
drivers/usb/gadget/f_fastboot.c +152 -0
index 310175a..d3d16c0 100644
@@ -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);
Signature · 1 line
1.8.3.2
#1 lore raw

PATCH 1/1 fastboot: Add support for flashing zImage

Quoted 2 lines · Dileep Katta

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

Quoted 188 lines
---
 drivers/usb/gadget/f_fastboot.c | 152 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 152 insertions(+)
drivers/usb/gadget/f_fastboot.c +152 -1
index 310175a..d3d16c0 100644
@@ -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

#2 lore raw

PATCH 1/1 fastboot: Add support for flashing zImage

Quoted 10 lines · Rob Herring
Quoted 2 lines · Dileep Katta

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.

Quoted 5 lines

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.

+1. Just how much room do we have, or not have, to be compatible with existing tools but also abstract some of this out so that different boards can "I want a layout like this ..." (one set of kernel, device tree, initrd) and another "I want a layout like this ..." (two sets, for redundancy).

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150302/9a845458/attachment.sig>
#3 lore raw

PATCH 1/1 fastboot: Add support for flashing zImage

In reply to Rob Herring

Hi Rob,

Quoted 213 lines
Quoted 2 lines · Dileep Katta

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

Quoted 194 lines
---
 drivers/usb/gadget/f_fastboot.c | 152

++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+)

(quoted diff) +0 -0

b/drivers/usb/gadget/f_fastboot.c index 310175a..d3d16c0 100644

drivers/usb/gadget/f_fastboot.c +25 -0
@@ -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");

drivers/usb/gadget/f_fastboot.c +5 -0
+               goto out;
+       }
+       if (android_image_check_header(hdr) != 0) {
+               printf("bad boot image magic\n");
+               strcpy(response, "FAILBoot partition not

initialized");

drivers/usb/gadget/f_fastboot.c +43 -0
+               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);

drivers/usb/gadget/f_fastboot.c +3 -0
+       if (hdr_sectors <= 0) {
+               sprintf(response + strlen(response),
+                       "FAILInvalid number of boot sectors %d",

hdr_sectors);

drivers/usb/gadget/f_fastboot.c +4 -0
+               ret = -1;
+               goto out;
+       }
+       ret = get_partition_info_efi_by_name(dev_desc, "boot",

&info);

drivers/usb/gadget/f_fastboot.c +10 -0
+       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)*

drivers/usb/gadget/f_fastboot.c +7 -0
+                                    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,

drivers/usb/gadget/f_fastboot.c +3 -0
+                                  ramdisk_sectors, ramdisk_buffer);
+       if (ret < 0) {
+               sprintf(response, "FAILCannot read ramdisk from

'boot'");

drivers/usb/gadget/f_fastboot.c +10 -0
+               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");

drivers/usb/gadget/f_fastboot.c +9 -0
+               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,

drivers/usb/gadget/f_fastboot.c +2 -0
+                                   kernel_sectors,
+                                   (const void

*)CONFIG_USB_FASTBOOT_BUF_ADDR);

drivers/usb/gadget/f_fastboot.c +9 -0
+       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)*

drivers/usb/gadget/f_fastboot.c +2 -0
+                                    sectors_per_page;
+       ret = dev_desc->block_write(dev_desc->dev,

ramdisk_sector_start,
+ ramdisk_sectors,
ramdisk_buffer);

drivers/usb/gadget/f_fastboot.c +2 -0
+       if (ret < 0) {
+               sprintf(response, "FAILCannot write back original

ramdisk");

drivers/usb/gadget/f_fastboot.c +11 -0
+               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) }
 
Quoted 12 lines
Quoted 10 lines
drivers/usb/gadget/f_fastboot.c +5 -1
        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);
--
Quoted 2 lines

1.8.3.2

Is this patch dropped or will there be any new revision?

Signature · 5 lines
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group
#4 lore raw

PATCH 1/1 fastboot: Add support for flashing zImage

Hi Lukasz,

Quoted 215 lines · Lukasz Majewski

Hi Rob,

Quoted 213 lines
Quoted 2 lines · Dileep Katta

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

Quoted 194 lines
---
 drivers/usb/gadget/f_fastboot.c | 152

++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+)

(quoted diff) +0 -0

b/drivers/usb/gadget/f_fastboot.c index 310175a..d3d16c0 100644

drivers/usb/gadget/f_fastboot.c +25 -0
@@ -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");

drivers/usb/gadget/f_fastboot.c +5 -0
+               goto out;
+       }
+       if (android_image_check_header(hdr) != 0) {
+               printf("bad boot image magic\n");
+               strcpy(response, "FAILBoot partition not

initialized");

drivers/usb/gadget/f_fastboot.c +43 -0
+               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);

drivers/usb/gadget/f_fastboot.c +3 -0
+       if (hdr_sectors <= 0) {
+               sprintf(response + strlen(response),
+                       "FAILInvalid number of boot sectors %d",

hdr_sectors);

drivers/usb/gadget/f_fastboot.c +4 -0
+               ret = -1;
+               goto out;
+       }
+       ret = get_partition_info_efi_by_name(dev_desc, "boot",

&info);

drivers/usb/gadget/f_fastboot.c +10 -0
+       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)*

drivers/usb/gadget/f_fastboot.c +7 -0
+                                    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,

drivers/usb/gadget/f_fastboot.c +3 -0
+                                  ramdisk_sectors, ramdisk_buffer);
+       if (ret < 0) {
+               sprintf(response, "FAILCannot read ramdisk from

'boot'");

drivers/usb/gadget/f_fastboot.c +10 -0
+               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");

drivers/usb/gadget/f_fastboot.c +9 -0
+               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,

drivers/usb/gadget/f_fastboot.c +2 -0
+                                   kernel_sectors,
+                                   (const void

*)CONFIG_USB_FASTBOOT_BUF_ADDR);

drivers/usb/gadget/f_fastboot.c +9 -0
+       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)*

drivers/usb/gadget/f_fastboot.c +2 -0
+                                    sectors_per_page;
+       ret = dev_desc->block_write(dev_desc->dev,

ramdisk_sector_start,
+ ramdisk_sectors,
ramdisk_buffer);

drivers/usb/gadget/f_fastboot.c +2 -0
+       if (ret < 0) {
+               sprintf(response, "FAILCannot write back original

ramdisk");

drivers/usb/gadget/f_fastboot.c +11 -0
+               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) }
 
Quoted 15 lines
Quoted 4 lines
Quoted 4 lines
drivers/usb/gadget/f_fastboot.c +3 -0
        strcpy(response, "FAILno flash device defined");
+
+       if (!strcmp(cmd, "zImage") || !strcmp(cmd, "zimage")) {
+               fastboot_update_zimage();
Quoted 8 lines
Quoted 8 lines
drivers/usb/gadget/f_fastboot.c +2 -1
+               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

Is this patch dropped or will there be any new revision?

I am verifying existing flash commands with zImage, and if required there might be a new version for this patch.

Quoted 8 lines

--
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group

Regards, Dileep

#5 lore raw

PATCH 1/1 fastboot: Add support for flashing zImage

In reply to Dileep Katta

Hi Dileep,

Quoted 24 lines

This patch adds support to flash zImage to the boot partition on eMMC.
Usage: fastboot flash zImage <path_to_zImage>

---
 drivers/usb/gadget/f_fastboot.c | 152

++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+)

(quoted diff) +0 -0

b/drivers/usb/gadget/f_fastboot.c index 310175a..d3d16c0 100644

drivers/usb/gadget/f_fastboot.c +1 -0
@@ -23,6 +23,7 @@
 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
 #include <fb_mmc.h>
 #endif
+#include <android_image.h>
 
 #define FASTBOOT_VERSION		"0.4"
 

drivers/usb/gadget/f_fastboot.c static void cb_continue(struct usb_ep *ep, · line 498

Quoted 6 lines
drivers/usb/gadget/f_fastboot.c +3 -0
@@ -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

^^^^^ could you explain this acronym?
My gut feeling is that this function name could be better. As fair as I can tell you return number of header sectors.

Quoted 9 lines
drivers/usb/gadget/f_fastboot.c +7 -0
 *response,
+						block_dev_desc_t
 *dev_desc) +{
+	u32 hdr_sectors = 0;
+	u32 sector_size;
+	int status = 0;
+	strcpy(response, "OKAY");
+	disk_partition_t info;
+

drivers/usb/gadget/f_fastboot.c static void cb_continue(struct usb_ep *ep, struct usb_request *req) · line 515

Quoted 10 lines
drivers/usb/gadget/f_fastboot.c +9 -0
+	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;

^^^ checkpatch.pl would complain about this line.

drivers/usb/gadget/f_fastboot.c static void cb_continue(struct usb_ep *ep, struct usb_request *req) · line 524

Quoted 10 lines
drivers/usb/gadget/f_fastboot.c +5 -0
+	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");

drivers/usb/gadget/f_fastboot.c +4 -0
+		goto out;
+	}
+	if (android_image_check_header(hdr) != 0) {
+		printf("bad boot image magic\n");
		^^^^^^ error()?

drivers/usb/gadget/f_fastboot.c static void cb_continue(struct usb_ep *ep, struct usb_request *req) · line 535

Quoted 12 lines
drivers/usb/gadget/f_fastboot.c +1 -0
+		strcpy(response, "FAILBoot partition not

initialized");

drivers/usb/gadget/f_fastboot.c +10 -0
+		goto out;
+	}
+
+	return hdr_sectors;
+
+out:
+	strcpy(response, "INFO");
+	fastboot_tx_write_str(response);
+
+	return -1;

Please use appropriate -Exxxxx error code in the whole file.

drivers/usb/gadget/f_fastboot.c static void cb_continue(struct usb_ep *ep, struct usb_request *req) · line 538

Quoted 3 lines
drivers/usb/gadget/f_fastboot.c +3 -0
+}
+
+#define CEIL(a, b) (((a) / (b)) + ((a % b) > 0 ? 1 : 0))

Maybe you could add this code to ./include/common.h file, so it would be reusable in the future?

drivers/usb/gadget/f_fastboot.c static void cb_continue(struct usb_ep *ep, struct usb_request *req) · line 551

Quoted 13 lines
drivers/usb/gadget/f_fastboot.c +13 -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];

^^^^^^^^^^^^ this is defined as (64 + 1)
Isn't there any change that such unaligned buffer would cause cache flush/invalidation related bugs?

Please look into ALLOC_CACHE_ALIGN_BUFFER comment at ./include/common.h file

Quoted 4 lines
drivers/usb/gadget/f_fastboot.c +4 -0
+	u32 addr = CONFIG_USB_FASTBOOT_BUF_ADDR;
+
+	strcpy(response, "OKAY");
+	printf("Flashing zImage...%d bytes\n", download_bytes);

drivers/usb/gadget/f_fastboot.c static void cb_continue(struct usb_ep *ep, struct usb_request *req) · line 565

Quoted 10 lines
drivers/usb/gadget/f_fastboot.c +10 -0
+
+	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;

^^^^^^ Please use define for this magic number. It would be more informative.

drivers/usb/gadget/f_fastboot.c static void cb_continue(struct usb_ep *ep, struct usb_request *req) · line 568

Quoted 3 lines
drivers/usb/gadget/f_fastboot.c +3 -0
+	hdr = (struct andr_img_hdr *)addr;
+
+	hdr_sectors = fastboot_get_boot_ptn(hdr, response, dev_desc);

^^^ the comment the same as above.

Quoted 88 lines
drivers/usb/gadget/f_fastboot.c +3 -0
+	if (hdr_sectors <= 0) {
+		sprintf(response + strlen(response),
+			"FAILInvalid number of boot sectors %d",

hdr_sectors);

drivers/usb/gadget/f_fastboot.c +4 -0
+		ret = -1;
+		goto out;
+	}
+	ret = get_partition_info_efi_by_name(dev_desc, "boot",

&info);

drivers/usb/gadget/f_fastboot.c +10 -0
+	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)*

drivers/usb/gadget/f_fastboot.c +7 -0
+				     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,

drivers/usb/gadget/f_fastboot.c +3 -0
+				   ramdisk_sectors, ramdisk_buffer);
+	if (ret < 0) {
+		sprintf(response, "FAILCannot read ramdisk from

'boot'");

drivers/usb/gadget/f_fastboot.c +10 -0
+		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");

drivers/usb/gadget/f_fastboot.c +9 -0
+		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,

drivers/usb/gadget/f_fastboot.c +2 -0
+				    kernel_sectors,
+				    (const void

*)CONFIG_USB_FASTBOOT_BUF_ADDR);

drivers/usb/gadget/f_fastboot.c +9 -0
+	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)*

drivers/usb/gadget/f_fastboot.c +2 -0
+				     sectors_per_page;
+	ret = dev_desc->block_write(dev_desc->dev,

ramdisk_sector_start,

drivers/usb/gadget/f_fastboot.c +3 -0
+				    ramdisk_sectors, ramdisk_buffer);
+	if (ret < 0) {
+		sprintf(response, "FAILCannot write back original

ramdisk");

drivers/usb/gadget/f_fastboot.c +11 -0
+		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;

drivers/usb/gadget/f_fastboot.c static void cb_flash(struct usb_ep *ep, struct · line 656

Quoted 5 lines
drivers/usb/gadget/f_fastboot.c +2 -0
@@ -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")) {

Maybe you could use strcasecmp() function from ./lib/string.c?

Quoted 6 lines
drivers/usb/gadget/f_fastboot.c +3 -0
+		fastboot_update_zimage();
+		return;
+	}
 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
 	fb_mmc_flash_write(cmd, (void *)CONFIG_USB_FASTBOOT_BUF_ADDR,
 			   download_bytes, response);
Signature · 5 lines
Best regards,

Lukasz Majewski

Samsung R&D Institute Poland (SRPOL) | Linux Platform Group