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 <brain@jikos.cz>
Reviewed-by: Tom Rini <trini@konsulko.com>
Acked-by: Steve Rae <steve.rae@raedomain.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Petr Kulhavy 2016-09-09 10:27:16 +02:00 committed by Tom Rini
parent 87b8530fe2
commit b6dd69a4d6
5 changed files with 121 additions and 6 deletions

7
README
View file

@ -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

View file

@ -14,15 +14,20 @@
#include <mmc.h>
#include <div64.h>
#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");

View file

@ -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,

View file

@ -59,6 +59,43 @@ To define a partition alias add an environment variable similar to:
fastboot_partition_alias_<alias partition name>=<actual partition name>
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:
<device type> <device index letter> <partition index>
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

View file

@ -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 */