From b6dd69a4d6b20862a2075f402f9edfb0de6d14ed Mon Sep 17 00:00:00 2001 From: Petr Kulhavy Date: Fri, 9 Sep 2016 10:27:16 +0200 Subject: [PATCH] fastboot: add support for writing MBR Add special target "mbr" (otherwise configurable via CONFIG_FASTBOOT_MBR_NAME) to write MBR partition table. Partitions are now searched using the generic function which finds any partiiton by name. For MBR the partition names hda1, sda1, etc. are used. Signed-off-by: Petr Kulhavy Reviewed-by: Tom Rini Acked-by: Steve Rae Reviewed-by: Simon Glass --- README | 7 +++++++ common/fb_mmc.c | 40 +++++++++++++++++++++++++++++++------ disk/part_dos.c | 20 +++++++++++++++++++ doc/README.android-fastboot | 37 ++++++++++++++++++++++++++++++++++ include/part.h | 23 +++++++++++++++++++++ 5 files changed, 121 insertions(+), 6 deletions(-) diff --git a/README b/README index bc626dc7a8..3ea4d012f6 100644 --- a/README +++ b/README @@ -1683,6 +1683,13 @@ The following options need to be configured: "fastboot flash" command line matches this value. Default is GPT_ENTRY_NAME (currently "gpt") if undefined. + CONFIG_FASTBOOT_MBR_NAME + The fastboot "flash" command supports writing the downloaded + image to DOS MBR. + This occurs when the "partition name" specified on the + "fastboot flash" command line matches this value. + If not defined the default value "mbr" is used. + - Journaling Flash filesystem support: CONFIG_JFFS2_NAND, CONFIG_JFFS2_NAND_OFF, CONFIG_JFFS2_NAND_SIZE, CONFIG_JFFS2_NAND_DEV diff --git a/common/fb_mmc.c b/common/fb_mmc.c index a0a4a83143..4bc68a7657 100644 --- a/common/fb_mmc.c +++ b/common/fb_mmc.c @@ -14,15 +14,20 @@ #include #include -#ifndef CONFIG_FASTBOOT_GPT_NAME +#if defined(CONFIG_EFI_PARTITION) && !defined(CONFIG_FASTBOOT_GPT_NAME) #define CONFIG_FASTBOOT_GPT_NAME GPT_ENTRY_NAME #endif + +#if defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_FASTBOOT_MBR_NAME) +#define CONFIG_FASTBOOT_MBR_NAME "mbr" +#endif + struct fb_mmc_sparse { struct blk_desc *dev_desc; }; -static int part_get_info_efi_by_name_or_alias(struct blk_desc *dev_desc, +static int part_get_info_by_name_or_alias(struct blk_desc *dev_desc, const char *name, disk_partition_t *info) { int ret; @@ -103,6 +108,7 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer, return; } +#ifdef CONFIG_EFI_PARTITION if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) { printf("%s: updating MBR, Primary and Backup GPT(s)\n", __func__); @@ -114,14 +120,36 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer, } if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) { printf("%s: writing GPT partitions failed\n", __func__); - fastboot_fail( - "writing GPT partitions failed"); + fastboot_fail("writing GPT partitions failed"); return; } printf("........ success\n"); fastboot_okay(""); return; - } else if (part_get_info_efi_by_name_or_alias(dev_desc, cmd, &info)) { + } +#endif + +#ifdef CONFIG_DOS_PARTITION + if (strcmp(cmd, CONFIG_FASTBOOT_MBR_NAME) == 0) { + printf("%s: updating MBR\n", __func__); + if (is_valid_dos_buf(download_buffer)) { + printf("%s: invalid MBR - refusing to write to flash\n", + __func__); + fastboot_fail("invalid MBR partition"); + return; + } + if (write_mbr_partition(dev_desc, download_buffer)) { + printf("%s: writing MBR partition failed\n", __func__); + fastboot_fail("writing MBR partition failed"); + return; + } + printf("........ success\n"); + fastboot_okay(""); + return; + } +#endif + + if (part_get_info_by_name_or_alias(dev_desc, cmd, &info)) { error("cannot find partition: '%s'\n", cmd); fastboot_fail("cannot find partition"); return; @@ -172,7 +200,7 @@ void fb_mmc_erase(const char *cmd) return; } - ret = part_get_info_efi_by_name_or_alias(dev_desc, cmd, &info); + ret = part_get_info_by_name_or_alias(dev_desc, cmd, &info); if (ret) { error("cannot find partition: '%s'", cmd); fastboot_fail("cannot find partition"); diff --git a/disk/part_dos.c b/disk/part_dos.c index 82266012ef..8e6aae5736 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -297,6 +297,26 @@ int part_get_info_dos(struct blk_desc *dev_desc, int part, return part_get_info_extended(dev_desc, 0, 0, 1, part, info, 0); } +int is_valid_dos_buf(void *buf) +{ + return test_block_type(buf) == DOS_MBR ? 0 : -1; +} + +int write_mbr_partition(struct blk_desc *dev_desc, void *buf) +{ + if (is_valid_dos_buf(buf)) + return -1; + + /* write MBR */ + if (blk_dwrite(dev_desc, 0, 1, buf) != 1) { + printf("%s: failed writing '%s' (1 blks at 0x0)\n", + __func__, "MBR"); + return 1; + } + + return 0; +} + U_BOOT_PART_TYPE(dos) = { .name = "DOS", .part_type = PART_TYPE_DOS, diff --git a/doc/README.android-fastboot b/doc/README.android-fastboot index ce12bc594f..dea70669f1 100644 --- a/doc/README.android-fastboot +++ b/doc/README.android-fastboot @@ -59,6 +59,43 @@ To define a partition alias add an environment variable similar to: fastboot_partition_alias_= Example: fastboot_partition_alias_boot=LNX +Partition Names +=============== +The Fastboot implementation in U-boot allows to write images into disk +partitions (currently on eMMC). Target partitions are referred on the host +computer by their names. + +For GPT/EFI the respective partition name is used. + +For MBR the partitions are referred by generic names according to the +following schema: + + + +Example: hda3, sdb1, usbda1 + +The device type is as follows: + + * IDE, ATAPI and SATA disks: hd + * SCSI disks: sd + * USB media: usbd + * Disk on chip: docd + * other: xx + +The device index starts from 'a' and refers to the interface (e.g. USB +controller, SD/MMC controller) or disk index. The partition index starts +from 1 and describes the partition number on the particular device. + +Writing Partition Table +======================= +Fastboot also allows to write the partition table to the media. This can be +done by writing the respective partition table image to a special target +"gpt" or "mbr". These names can be customized by defining the following +configuration options: + +CONFIG_FASTBOOT_GPT_NAME +CONFIG_FASTBOOT_MBR_NAME + In Action ========= Enter into fastboot by executing the fastboot command in u-boot and you diff --git a/include/part.h b/include/part.h index bd8fd4958c..b17c219a51 100644 --- a/include/part.h +++ b/include/part.h @@ -351,4 +351,27 @@ int gpt_verify_partitions(struct blk_desc *dev_desc, gpt_header *gpt_head, gpt_entry **gpt_pte); #endif +#ifdef CONFIG_DOS_PARTITION +/** + * is_valid_dos_buf() - Ensure that a DOS MBR image is valid + * + * @param buf - buffer which contains the MBR + * + * @return - '0' on success, otherwise error + */ +int is_valid_dos_buf(void *buf); + +/** + * write_mbr_partition() - write DOS MBR + * + * @param dev_desc - block device descriptor + * @param buf - buffer which contains the MBR + * + * @return - '0' on success, otherwise error + */ +int write_mbr_partition(struct blk_desc *dev_desc, void *buf); + +#endif + + #endif /* _PART_H */