From patchwork Wed Dec 23 12:55:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 351449 Delivered-To: patch@linaro.org Received: by 2002:a02:85a7:0:0:0:0:0 with SMTP id d36csp6172555jai; Wed, 23 Dec 2020 04:56:27 -0800 (PST) X-Google-Smtp-Source: ABdhPJyNjjCuR1B3zJQiAqhp31A1mGHA63z/570Z6yFOyWkrE7SNkkD+TRsAjzUTLGnrOcf+wz5p X-Received: by 2002:aa7:ce16:: with SMTP id d22mr24371769edv.381.1608728187001; Wed, 23 Dec 2020 04:56:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1608728186; cv=none; d=google.com; s=arc-20160816; b=bfx6h620EH57ucAKlJJEXTy1MS/MLihpWQCrdc6JtR+uHFEZyk8iV/fGl0IlHhRF2U hdo/894AAkRR3+ie+yWjjvFbOTU0/RsLisSULwKbjEQl8CLo9r+JbCgcGtCDSBFPKXQl 2r4TafUBzXj+9O/PadbsT/DOoKE1ZOYxvP+/vg/UhLOTMUa5u+p4Bcou1Z59LsOxiitN BU361wqIM+HkQzM0d/tjt39C7SxJFT4oCJzKKd79tEAcCArHGFVFX2c/KSoQeKp1NxqI 7G6CL8WUPkL3CMD+uoRmjUYSXIcHdZKBh7hW2A1TZXt5uUFj3+A/7Jzq9GTFxgqHmrw9 JRVQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:references:cms-type:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature:dkim-filter; bh=YUeodYq328UOaGDmorIXBTVhQyce30ifgR+1xLeRAa8=; b=GL5x9/uAJx1X7uMJgTs8uIy6YxejdQeaJ5CkZ8Y9zeITnOoo45RvzXTQ8fhOX2LMP2 LW0ZNebwJFA/ojUNawozIOVnugdOffAPnNDOQQ0dQuQPR/6cveuhtMLZgv3ffEJzUJKG gMl4sZMamkQ7MuislzgZmlMDX3oYrP994VLUETULLs7ljN7zj7RaOTmVPjovnpQOSJns 4UqYpU4orl3RUiMIOdzCTJ6oSWVmjdclxL/MGcxBdhPm8ie65niF3J4t1Bglu4FLUneB L5G9ZmMSXM2jo34jDQXzSkj5c/aV3+YSY2bNcPfsQ9yGzW+1ebmkRefqlFDuA6XLsscS xyaw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=sXlzAqtO; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=samsung.com Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id e16si11888259ejd.747.2020.12.23.04.56.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Dec 2020 04:56:26 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=sXlzAqtO; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=samsung.com Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1D3AC82784; Wed, 23 Dec 2020 13:55:54 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=samsung.com header.i=@samsung.com header.b="sXlzAqtO"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 2A56382743; Wed, 23 Dec 2020 13:55:44 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_DNSWL_HI, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mailout2.w1.samsung.com (mailout2.w1.samsung.com [210.118.77.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 0289782731 for ; Wed, 23 Dec 2020 13:55:37 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=m.szyprowski@samsung.com Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20201223125536euoutp022411b18adb1e89a7fc6d72302852a3c3~TWbeB88513118931189euoutp02_ for ; Wed, 23 Dec 2020 12:55:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20201223125536euoutp022411b18adb1e89a7fc6d72302852a3c3~TWbeB88513118931189euoutp02_ DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1608728136; bh=YUeodYq328UOaGDmorIXBTVhQyce30ifgR+1xLeRAa8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sXlzAqtOB89DzlNFFNMQTyJN+GwZvcmEvW/FP2yYUGhc6gFw9+9JPm+WbAvHJNUup kQQmImogQvuuDqVA6dooFdFafrso4gXE3UEDsq+mfeUvJ67osI5JvxYPynazgxTtUw MQwDhcEsIRDngNq9ppLGgDA4/lJB+RLsTUn0ZqpI= Received: from eusmges1new.samsung.com (unknown [203.254.199.242]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20201223125536eucas1p2f6c8204d32ca0c60f7aabc11189bfd34~TWbduLk2B0474004740eucas1p2V; Wed, 23 Dec 2020 12:55:36 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges1new.samsung.com (EUCPMTA) with SMTP id 05.79.27958.84E33EF5; Wed, 23 Dec 2020 12:55:36 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p1.samsung.com (KnoxPortal) with ESMTPA id 20201223125535eucas1p12eefba574c1dad89834fa4e12ee35e56~TWbdPQON43267632676eucas1p1Z; Wed, 23 Dec 2020 12:55:35 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20201223125535eusmtrp1c9cf7d7da5999521202f2dedae7caee6~TWbdOnX-N2521725217eusmtrp1B; Wed, 23 Dec 2020 12:55:35 +0000 (GMT) X-AuditID: cbfec7f2-efdff70000006d36-0f-5fe33e48a5c2 Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 03.E8.16282.74E33EF5; Wed, 23 Dec 2020 12:55:35 +0000 (GMT) Received: from AMDC2765.digital.local (unknown [106.120.51.73]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20201223125535eusmtip2fd5a3547517734ad8cf70de40e14d4a4~TWbcuFHMq2463824638eusmtip2k; Wed, 23 Dec 2020 12:55:35 +0000 (GMT) From: Marek Szyprowski To: u-boot@lists.denx.de Cc: Marek Szyprowski , Lukasz Majewski , Simon Glass , Heinrich Schuchardt , Jaehoon Chung , Bartlomiej Zolnierkiewicz Subject: [PATCH v3 6/6] cmd: Add MBR partition layout control utility Date: Wed, 23 Dec 2020 13:55:15 +0100 Message-Id: <20201223125515.28865-7-m.szyprowski@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201223125515.28865-1-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrIIsWRmVeSWpSXmKPExsWy7djP87oedo/jDU5f4LTYOGM9q8WNX22s Fs/fXWayWHvkLrvFty3bGC3e7u1ktzg89QOjA7vH7IaLLB7zZp1g8fjwMc7j7J0djB59W1Yx BrBGcdmkpOZklqUW6dslcGVcPrOZseBPasWdhZdZGhhX+3cxcnJICJhIfJ48n62LkYtDSGAF o0TDzh/sEM4XRokVDT2sEM5nRon29WfZYFrWX2yGqlrOKHH7yk02uJaGr8+YQarYBAwlut52 gXWICEhI/Oq/yghSxCzwj1Hi4K+PrCAJYQFXiT/PpjGB2CwCqhKND+aBNfAK2Eq82PKPCWKd vMTqDQfAhnIK2El8W9ABdpOEwEwOiY6F+1khilwk1sx5zAxhC0u8Or6FHcKWkTg9uYcFoqGZ UeLhubXsEE4Po8TlphmMEFXWEnfO/QJazQF0n6bE+l36EGFHiaUL37OChCUE+CRuvBUECTMD mZO2TWeGCPNKdLQJQVSrScw6vg5u7cELl6DO8ZB4f7GNCRJCExkl/q5cxTyBUX4WwrIFjIyr GMVTS4tz01OLDfNSy/WKE3OLS/PS9ZLzczcxAlPF6X/HP+1gnPvqo94hRiYOxkOMEhzMSiK8 l/gfxwvxpiRWVqUW5ccXleakFh9ilOZgURLnXTV7TbyQQHpiSWp2ampBahFMlomDU6qBSTH8 x42o0mW/P57ekWjXda1mWbnmmf0RB9mEFgdWCZwI3qi/1qTuUrlmx8eyd/G7V1nUB6iLz/vX P23ZFNHl3UuTXx+dLDQp363vzPuoW45ucfcs7t0z4E12bdkcsOpIoJHwucC+yCPr23lzz264 ueiYWWrwKtvXe9Xv1pfIfmo4eniX4IWJlVePcdq/tVmr5NSqHCYRO/npqrmzLj3bpa7MwDmZ xWvfBpV7P53a77Os4FthlzfTRmPeO1W94NAN22wOTt+sdLl1TYQ2m4euPw93a8ARUYllR80t mCtFD4osc/U5lzRd6tBlqT2Pp5reW3Scmdn2iqaJ8/1Pqnmznd8cvTz9iYl3u2aCiYBWpxJL cUaioRZzUXEiANeMjVKEAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrPLMWRmVeSWpSXmKPExsVy+t/xe7rudo/jDZ4fV7DYOGM9q8WNX22s Fs/fXWayWHvkLrvFty3bGC3e7u1ktzg89QOjA7vH7IaLLB7zZp1g8fjwMc7j7J0djB59W1Yx BrBG6dkU5ZeWpCpk5BeX2CpFG1oY6RlaWugZmVjqGRqbx1oZmSrp29mkpOZklqUW6dsl6GVc PrOZseBPasWdhZdZGhhX+3cxcnJICJhIrL/YzN7FyMUhJLCUUeLawXPsEAkZiZPTGlghbGGJ P9e62EBsIYFPjBJfN4WC2GwChhJdbyHiIgISEr/6rzKC2MwCTUwSa/+D2cICrhJ/nk1jArFZ BFQlGh/MA6vnFbCVeLHlHxPEfHmJ1RsOMIPYnAJ2Et8WdLBC7LKVmHVqHfMERr4FjAyrGEVS S4tz03OLjfSKE3OLS/PS9ZLzczcxAkN227GfW3Ywrnz1Ue8QIxMH4yFGCQ5mJRHeS/yP44V4 UxIrq1KL8uOLSnNSiw8xmgLdMZFZSjQ5Hxg1eSXxhmYGpoYmZpYGppZmxkrivCZH1sQLCaQn lqRmp6YWpBbB9DFxcEo1MDVO8MmrOMoX0Bb4LC/V1Txwz8srJTrGNiF9O4Ly9VW9VINPd5zc fXhryP//prM23JNa4PnSJ/G5cmvDzimO2U/eXbPPc2a1iOL/+Mv66r6uo+kzp/25cEpohrXg FZvlk77PLZX8fT2adxWv+IH85d53ryzcZLDu8NNO30gxH4nOg9KlkryG1+M/HJzgs9NR/9/H 2mNnA37ZOh7OURE/dnDK8nnzegNu/FXO4fprrSq75P15BeFPfUxT557M/fb4sHV7+NF5+z54 trm23PmyVEct/+6R7t2HvCJWpi/h9K5JmXC6rVxPSkHe1iaS+82N7oYJP8O6v6ucYNnsusF3 if+tp437Em938Hw/2esl+V6JpTgj0VCLuag4EQAoXagc4gIAAA== X-CMS-MailID: 20201223125535eucas1p12eefba574c1dad89834fa4e12ee35e56 X-Msg-Generator: CA X-RootMTR: 20201223125535eucas1p12eefba574c1dad89834fa4e12ee35e56 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20201223125535eucas1p12eefba574c1dad89834fa4e12ee35e56 References: <20201223125515.28865-1-m.szyprowski@samsung.com> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean Add a 'mbr' command to let users create or verify MBR partition layout based on the provided text description. The partition layout is alternatively read from the 'mbr_parts' environment variable. This can be used in scripts to help system image flashing tools to ensure proper partition layout. The syntax of the text description of the partition list is similar to the one used by the 'gpt' command. Supported parameters are: name (currently ignored), start (partition start offset in bytes), size (in bytes or '-' to expand it to the whole free area), bootable (boolean flag) and id (MBR partition type). If one wants to create more than 4 partitions, an 'Extended' primary partition (with 0x05 ID) has to be explicitely provided as a one of the first 4 entries. Here is an example how to create a 6 partitions (3 on the 'extended volume'), some of the predefined sizes: > setenv mbr_parts 'name=boot,start=4M,size=128M,bootable,id=0x0e; name=rootfs,size=3072M,id=0x83; name=system-data,size=512M,id=0x83; name=[ext],size=-,id=0x05; name=user,size=-,id=0x83; name=modules,size=100M,id=0x83; name=ramdisk,size=8M,id=0x83' > mbr write mmc 0 Signed-off-by: Marek Szyprowski --- cmd/Kconfig | 8 ++ cmd/Makefile | 1 + cmd/mbr.c | 314 ++++++++++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + doc/usage/mbr.rst | 93 +++++++++++++ 5 files changed, 417 insertions(+) create mode 100644 cmd/mbr.c create mode 100644 doc/usage/mbr.rst -- 2.17.1 diff --git a/cmd/Kconfig b/cmd/Kconfig index 1595de999b..2c3358e359 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1025,6 +1025,14 @@ config CMD_LSBLK Print list of available block device drivers, and for each, the list of known block devices. +config CMD_MBR + bool "MBR (Master Boot Record) command" + select DOS_PARTITION + select HAVE_BLOCK_DEVICE + help + Enable the 'mbr' command to ready and write MBR (Master Boot Record) + style partition tables. + config CMD_MISC bool "misc" depends on MISC diff --git a/cmd/Makefile b/cmd/Makefile index dd86675bf2..41379d9a0e 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -178,6 +178,7 @@ obj-$(CONFIG_CMD_ZFS) += zfs.o obj-$(CONFIG_CMD_DFU) += dfu.o obj-$(CONFIG_CMD_GPT) += gpt.o +obj-$(CONFIG_CMD_MBR) += mbr.o obj-$(CONFIG_CMD_ETHSW) += ethsw.o obj-$(CONFIG_CMD_AXI) += axi.o obj-$(CONFIG_CMD_PVBLOCK) += pvblock.o diff --git a/cmd/mbr.c b/cmd/mbr.c new file mode 100644 index 0000000000..da2e3a4722 --- /dev/null +++ b/cmd/mbr.c @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * cmd_mbr.c -- MBR (Master Boot Record) handling command + * + * Copyright (C) 2020 Samsung Electronics + * author: Marek Szyprowski + * + * based on the gpt command. + */ + +#include +#include +#include +#include +#include + +/** + * extract_val() - Extract a value from the key=value pair list + * @str: pointer to string with key=values pairs + * @key: pointer to the key to search for + * + * The list of parameters is come separated, only a value for + * the given key is returend. + * + * Function allocates memory for the value, remember to free! + * + * Return: Pointer to allocated string with the value. + */ +static char *extract_val(const char *str, const char *key) +{ + char *v, *k; + char *s, *strcopy; + char *new = NULL; + + strcopy = strdup(str); + if (strcopy == NULL) + return NULL; + + s = strcopy; + while (s) { + v = strsep(&s, ","); + if (!v) + break; + k = strsep(&v, "="); + if (!k) + break; + if (strcmp(k, key) == 0) { + new = strdup(v); + break; + } + } + + free(strcopy); + + return new; +} + +/** + * found_key() - Search for a key without a value in the parameter list + * @str: pointer to string with key + * @key: pointer to the key to search for + * + * The list of parameters is come separated. + * + * Return: True if key has been found. + */ +static bool found_key(const char *str, const char *key) +{ + char *k; + char *s, *strcopy; + bool result = false; + + strcopy = strdup(str); + if (!strcopy) + return NULL; + + s = strcopy; + while (s) { + k = strsep(&s, ","); + if (!k) + break; + if (strcmp(k, key) == 0) { + result = true; + break; + } + } + + free(strcopy); + + return result; +} + +static int str_to_partitions(const char *str_part, int blksz, + unsigned long *disk_uuid, struct disk_partition **partitions, + int *parts_count) +{ + char *tok, *str, *s; + int i; + char *val, *p; + int p_count; + struct disk_partition *parts; + int errno = 0; + uint64_t size_ll, start_ll; + + if (str_part == NULL) + return -1; + + str = strdup(str_part); + if (str == NULL) + return -ENOMEM; + + /* extract disk guid */ + s = str; + val = extract_val(str, "uuid_disk"); + if (val) { + val = strsep(&val, ";"); + p = val; + *disk_uuid = ustrtoull(p, &p, 0); + free(val); + /* Move s to first partition */ + strsep(&s, ";"); + } + if (s == NULL) { + printf("Error: is the partitions string NULL-terminated?\n"); + return -EINVAL; + } + + /* remove the optional semicolon at the end of the string */ + i = strlen(s) - 1; + if (s[i] == ';') + s[i] = '\0'; + + /* calculate expected number of partitions */ + p_count = 1; + p = s; + while (*p) { + if (*p++ == ';') + p_count++; + } + + /* allocate memory for partitions */ + parts = calloc(sizeof(struct disk_partition), p_count); + if (parts == NULL) + return -ENOMEM; + + /* retrieve partitions data from string */ + for (i = 0; i < p_count; i++) { + tok = strsep(&s, ";"); + + if (tok == NULL) + break; + + /* size */ + val = extract_val(tok, "size"); + if (!val) { /* 'size' is mandatory */ + errno = -4; + goto err; + } + p = val; + if ((strcmp(p, "-") == 0)) { + /* auto extend the size */ + parts[i].size = 0; + } else { + size_ll = ustrtoull(p, &p, 0); + parts[i].size = size_ll / blksz; + } + free(val); + + /* start address */ + val = extract_val(tok, "start"); + if (val) { /* start address is optional */ + p = val; + start_ll = ustrtoull(p, &p, 0); + parts[i].start = start_ll / blksz; + free(val); + } + + /* system id */ + val = extract_val(tok, "id"); + if (!val) { /* '' is mandatory */ + errno = -4; + goto err; + } + p = val; + parts[i].sys_ind = ustrtoul(p, &p, 0); + free(val); + + /* bootable */ + if (found_key(tok, "bootable")) + parts[i].bootable = PART_BOOTABLE; + } + + *parts_count = p_count; + *partitions = parts; + free(str); + + return 0; +err: + free(str); + free(parts); + + return errno; +} + +static int do_write_mbr(struct blk_desc *dev, const char *str) +{ + unsigned long disk_uuid = 0; + struct disk_partition *partitions; + int blksz = dev->blksz; + int count; + + if (str_to_partitions(str, blksz, &disk_uuid, &partitions, &count)) { + printf("MBR: failed to setup partitions from \"%s\"\n", str); + return -1; + } + + if (layout_mbr_partitions(partitions, count, dev->lba)) { + printf("MBR: failed to layout partitions on the device\n"); + free(partitions); + return -1; + } + + if (write_mbr_partitions(dev, partitions, count, disk_uuid)) { + printf("MBR: failed to write partitions to the device\n"); + free(partitions); + return -1; + } + + return 0; +} + +static int do_verify_mbr(struct blk_desc *dev, const char *str) +{ + unsigned long disk_uuid = 0; + struct disk_partition *partitions; + int blksz = dev->blksz; + int count, i, ret = 1; + + if (str_to_partitions(str, blksz, &disk_uuid, &partitions, &count)) { + printf("MBR: failed to setup partitions from \"%s\"\n", str); + return -1; + } + + for (i = 0; i < count; i++) { + struct disk_partition p; + + if (part_get_info(dev, i+1, &p)) + goto fail; + + if ((partitions[i].size && p.size < partitions[i].size) || + (partitions[i].start && p.start < partitions[i].start) || + (p.sys_ind != partitions[i].sys_ind)) + goto fail; + } + ret = 0; +fail: + free(partitions); + return ret; +} + +static int do_mbr(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + const char *parts = NULL; + int ret = CMD_RET_SUCCESS; + int dev = 0; + char *ep; + struct blk_desc *blk_dev_desc = NULL; + + if (argc != 4 && argc != 5) + return CMD_RET_USAGE; + + dev = (int)simple_strtoul(argv[3], &ep, 10); + if (!ep || ep[0] != '\0') { + printf("'%s' is not a number\n", argv[3]); + return CMD_RET_USAGE; + } + blk_dev_desc = blk_get_dev(argv[2], dev); + if (!blk_dev_desc) { + printf("%s: %s dev %d NOT available\n", + __func__, argv[2], dev); + return CMD_RET_FAILURE; + } + + if ((strcmp(argv[1], "write") == 0)) { + parts = (argc == 5) ? argv[4] : env_get("mbr_parts"); + printf("MBR: write "); + ret = do_write_mbr(blk_dev_desc, parts); + } else if ((strcmp(argv[1], "verify") == 0)) { + printf("MBR: verify "); + parts = (argc == 5) ? argv[4] : env_get("mbr_parts"); + ret = do_verify_mbr(blk_dev_desc, parts); + } else { + return CMD_RET_USAGE; + } + + if (ret) { + printf("error!\n"); + return CMD_RET_FAILURE; + } + + printf("success!\n"); + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(mbr, CONFIG_SYS_MAXARGS, 1, do_mbr, + "MBR (Master Boot Record)", + " \n" + " - MBR partition table restoration utility\n" + " Restore or check partition information on a device connected\n" + " to the given block interface\n" + " Example usage:\n" + " mbr write mmc 0 [\"${mbr_parts}\"]\n" + " mbr verify mmc 0 [\"${partitions}\"]\n" +); diff --git a/doc/usage/index.rst b/doc/usage/index.rst index fbb2c0481c..5869fba189 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -14,4 +14,5 @@ Shell commands bootefi bootmenu button + mbr pstore diff --git a/doc/usage/mbr.rst b/doc/usage/mbr.rst new file mode 100644 index 0000000000..2339162098 --- /dev/null +++ b/doc/usage/mbr.rst @@ -0,0 +1,93 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +mbr command +=========== + +Synopsis +-------- + +:: + + mbr verify [interface] [device no] [partition list] + mbr write [interface] [device no] [partition list] + +Description +----------- + +The mbr command lets users create or verify the MBR (Master Boot Record) +partition layout based on the provided text description. The partition +layout is alternatively read from the 'mbr_parts' environment variable. +This can be used in scripts to help system image flashing tools to ensure +proper partition layout. + +The syntax of the text description of the partition list is similar to +the one used by the 'gpt' command. + +Supported partition parameters are: + +* name (currently ignored) +* start (partition start offset in bytes) +* size (in bytes or '-' to expand it to the whole free area) +* bootable (boolean flag) +* id (MBR partition type) + +If one wants to create more than 4 partitions, an 'Extended' primary +partition (with 0x05 ID) has to be explicitly provided as a one of the +first 4 entries. + +Here is an example how to create a 6 partitions (3 on the 'extended +volume'), some of the predefined sizes: + +:: + + => setenv mbr_parts 'name=boot,start=4M,size=128M,bootable,id=0x0e; + name=rootfs,size=3072M,id=0x83; + name=system-data,size=512M,id=0x83; + name=[ext],size=-,id=0x05; + name=user,size=-,id=0x83; + name=modules,size=100M,id=0x83; + name=ramdisk,size=8M,id=0x83' + => mbr write mmc 0 + +To check if the layout on the MMC #0 storage device matches the provided +text description one has to issue following command (assuming that +mbr_parts environment variable is set): + +:: + + => mbr verify mmc 0 + +The verify sub-command is especially useful in the system update scripts: + +:: + => if mbr verify mmc 0; then + echo MBR layout needs to be updated + ... + fi + +The 'mbr write' command returns 0 on success write or 1 on failure. + +The 'mbr verify' returns 0 if the layout matches the one on the storage +device or 1 if not. + +Configuration +------------- + +To use the mbr command you must specify CONFIG_CMD_MBR=y. + +Return value +------------ + +The variable *$?* takes the following values + ++---+------------------------------+ +| 0 | mbr write was succesful | ++---+------------------------------+ +| 1 | mbr write failed | ++---+------------------------------+ +| 0 | mbr verify was succesful | ++---+------------------------------+ +| 1 | mbr verify was not succesful | ++---+------------------------------+ +|-1 | invalid arguments | ++---+------------------------------+