[U-Boot] [PATCH] fastboot: add support for writing raw MMC

The current fastboot implementation is only able to flash partition images. However sometimes it is needed to write the raw MMC, e.g. when storing the U-boot environment image or SPL.
This patch adds the possibility to write MMC as a block device using a special target name composed of "lba:" followed by the block address. The address can be in decimal or hexadecimal with the "0x" prefix.
Signed-off-by: Petr Kulhavy brain@jikos.cz --- common/fb_mmc.c | 38 +++++++++++++++++++++++++++++++++++++- doc/README.android-fastboot | 15 +++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/common/fb_mmc.c b/common/fb_mmc.c index 81a3bd0..c4fe2ac 100644 --- a/common/fb_mmc.c +++ b/common/fb_mmc.c @@ -27,6 +27,9 @@ #define CONFIG_FASTBOOT_MBR_NAME "mbr" #endif
+#define FB_RAW_PREFIX "lba:" +#define FB_RAW_PREFIX_LEN 4 + struct fb_mmc_sparse { struct blk_desc *dev_desc; }; @@ -68,6 +71,29 @@ static lbaint_t fb_mmc_sparse_reserve(struct sparse_storage *info, return blkcnt; }
+/* + * attempt to interpret the partition name as raw LBA + * on success return 1 and fill info + * on failure (not a LBA matching name) return 0 (info undefined) + */ +static int get_raw_part_info(const struct blk_desc *dev_desc, const char *name, + disk_partition_t *info) +{ + if (strlen(name) <= FB_RAW_PREFIX_LEN || + strncmp(name, FB_RAW_PREFIX, FB_RAW_PREFIX_LEN) != 0) + return 0; + +#if CONFIG_SYS_64BIT_LBA + info->start = simple_strtoull(name + FB_RAW_PREFIX_LEN, NULL, 10); +#else + info->start = simple_strtoul(name + FB_RAW_PREFIX_LEN, NULL, 10); +#endif + info->size = dev_desc->lba - info->start; + info->blksz = dev_desc->blksz; + + return 1; +} + static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info, const char *part_name, void *buffer, unsigned int download_bytes) @@ -153,7 +179,17 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer, } #endif
- if (part_get_info_by_name_or_alias(dev_desc, cmd, &info)) { + /* first try to interpret as a raw write */ + if (get_raw_part_info(dev_desc, cmd, &info)) { + printf("%s: writing raw data at LBA 0x%llx\n", __func__, + (unsigned long long) info.start); + /* check if start is within the media */ + if (info.start >= dev_desc->lba) { + error("Attempt to write beyond the end of media\n"); + fastboot_fail("LBA write out of media"); + return; + } + } else 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; diff --git a/doc/README.android-fastboot b/doc/README.android-fastboot index b8afa15..cbc42a1 100644 --- a/doc/README.android-fastboot +++ b/doc/README.android-fastboot @@ -97,6 +97,21 @@ configuration options: CONFIG_FASTBOOT_GPT_NAME CONFIG_FASTBOOT_MBR_NAME
+Writing as a Block Device +========================= +Sometimes it is useful to write sections of eMMC which are not allocated as +partitions. For instance to store the SPL or U-Boot environment. + +This can be achieved by writing a special target with the name "lba:" (lower +case) followed by the block address at which the image should be stored. The +block address can be noted in decimal or hexadecimal (prefixed with "0x"). + +Example command: + + $ fastboot flash "lba:1024" uboot-env.bin + +This writes the uboot-env.bin image file at logical block 1024, i.e. 512KiB. + In Action ========= Enter into fastboot by executing the fastboot command in u-boot and you

On 10/05/2016 10:38 PM, Petr Kulhavy wrote:
The current fastboot implementation is only able to flash partition images. However sometimes it is needed to write the raw MMC, e.g. when storing the U-boot environment image or SPL.
This patch adds the possibility to write MMC as a block device using a special target name composed of "lba:" followed by the block address. The address can be in decimal or hexadecimal with the "0x" prefix.
Signed-off-by: Petr Kulhavy brain@jikos.cz
common/fb_mmc.c | 38 +++++++++++++++++++++++++++++++++++++- doc/README.android-fastboot | 15 +++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/common/fb_mmc.c b/common/fb_mmc.c index 81a3bd0..c4fe2ac 100644 --- a/common/fb_mmc.c +++ b/common/fb_mmc.c @@ -27,6 +27,9 @@ #define CONFIG_FASTBOOT_MBR_NAME "mbr" #endif
+#define FB_RAW_PREFIX "lba:" +#define FB_RAW_PREFIX_LEN 4
struct fb_mmc_sparse { struct blk_desc *dev_desc; }; @@ -68,6 +71,29 @@ static lbaint_t fb_mmc_sparse_reserve(struct sparse_storage *info, return blkcnt; }
+/*
- attempt to interpret the partition name as raw LBA
- on success return 1 and fill info
- on failure (not a LBA matching name) return 0 (info undefined)
- */
+static int get_raw_part_info(const struct blk_desc *dev_desc, const char *name,
disk_partition_t *info)
Is it right about "const struct blk_desc ..."? Why use "const"?
+{
- if (strlen(name) <= FB_RAW_PREFIX_LEN ||
strncmp(name, FB_RAW_PREFIX, FB_RAW_PREFIX_LEN) != 0)
strlen(name) was need to check?
return 0;
+#if CONFIG_SYS_64BIT_LBA
- info->start = simple_strtoull(name + FB_RAW_PREFIX_LEN, NULL, 10);
+#else
- info->start = simple_strtoul(name + FB_RAW_PREFIX_LEN, NULL, 10);
+#endif
- info->size = dev_desc->lba - info->start;
- info->blksz = dev_desc->blksz;
- return 1;
+}
static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info, const char *part_name, void *buffer, unsigned int download_bytes) @@ -153,7 +179,17 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer, } #endif
- if (part_get_info_by_name_or_alias(dev_desc, cmd, &info)) {
- /* first try to interpret as a raw write */
- if (get_raw_part_info(dev_desc, cmd, &info)) {
printf("%s: writing raw data at LBA 0x%llx\n", __func__,
(unsigned long long) info.start);
/* check if start is within the media */
if (info.start >= dev_desc->lba) {
error("Attempt to write beyond the end of media\n");
fastboot_fail("LBA write out of media");
return;
}
- } else 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;
diff --git a/doc/README.android-fastboot b/doc/README.android-fastboot index b8afa15..cbc42a1 100644 --- a/doc/README.android-fastboot +++ b/doc/README.android-fastboot @@ -97,6 +97,21 @@ configuration options: CONFIG_FASTBOOT_GPT_NAME CONFIG_FASTBOOT_MBR_NAME
+Writing as a Block Device +========================= +Sometimes it is useful to write sections of eMMC which are not allocated as +partitions. For instance to store the SPL or U-Boot environment.
+This can be achieved by writing a special target with the name "lba:" (lower +case) followed by the block address at which the image should be stored. The +block address can be noted in decimal or hexadecimal (prefixed with "0x").
+Example command:
- $ fastboot flash "lba:1024" uboot-env.bin
+This writes the uboot-env.bin image file at logical block 1024, i.e. 512KiB.
In Action
Enter into fastboot by executing the fastboot command in u-boot and you

On 07/10/16 01:57, Jaehoon Chung wrote:
On 10/05/2016 10:38 PM, Petr Kulhavy wrote:
The current fastboot implementation is only able to flash partition images. However sometimes it is needed to write the raw MMC, e.g. when storing the U-boot environment image or SPL.
This patch adds the possibility to write MMC as a block device using a special target name composed of "lba:" followed by the block address. The address can be in decimal or hexadecimal with the "0x" prefix.
Signed-off-by: Petr Kulhavy brain@jikos.cz
common/fb_mmc.c | 38 +++++++++++++++++++++++++++++++++++++- doc/README.android-fastboot | 15 +++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/common/fb_mmc.c b/common/fb_mmc.c index 81a3bd0..c4fe2ac 100644 --- a/common/fb_mmc.c +++ b/common/fb_mmc.c @@ -27,6 +27,9 @@ #define CONFIG_FASTBOOT_MBR_NAME "mbr" #endif
+#define FB_RAW_PREFIX "lba:" +#define FB_RAW_PREFIX_LEN 4
- struct fb_mmc_sparse { struct blk_desc *dev_desc; };
@@ -68,6 +71,29 @@ static lbaint_t fb_mmc_sparse_reserve(struct sparse_storage *info, return blkcnt; }
+/*
- attempt to interpret the partition name as raw LBA
- on success return 1 and fill info
- on failure (not a LBA matching name) return 0 (info undefined)
- */
+static int get_raw_part_info(const struct blk_desc *dev_desc, const char *name,
disk_partition_t *info)
Is it right about "const struct blk_desc ..."? Why use "const"?
This is a standard practice in C to make sure the function doesn't alter *dev_desc and in the header to indicate which parameters are inputs (read-only) and which outputs. In fact this should be used all over the code, but in U-boot it's not very strictly followed.
+{
- if (strlen(name) <= FB_RAW_PREFIX_LEN ||
strncmp(name, FB_RAW_PREFIX, FB_RAW_PREFIX_LEN) != 0)
strlen(name) was need to check?
To make sure there is at least one character after the ":", i.e. the input is not just "lba:". Otherwise the simple_stroul() returns 0. There still could be some non-numeric characters though, but that check would be more complex and ideally done in simple_strtoul()
Regards Petr
participants (2)
-
Jaehoon Chung
-
Petr Kulhavy