From patchwork Tue Dec 22 14:09:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 346641 Delivered-To: patch@linaro.org Received: by 2002:a02:85a7:0:0:0:0:0 with SMTP id d36csp5358818jai; Tue, 22 Dec 2020 06:11:04 -0800 (PST) X-Google-Smtp-Source: ABdhPJz01CSRkRBpRHokQ+U0G4YlcJ5Uq1YXAC95H5znRvROUc8m3W2dhkjJTjwueYdLX+mpUKbN X-Received: by 2002:a17:906:9382:: with SMTP id l2mr20487442ejx.162.1608646264768; Tue, 22 Dec 2020 06:11:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1608646264; cv=none; d=google.com; s=arc-20160816; b=vpn713LAJKwiH3ThnmD+2cDRAGrzeFQDgCXA5BtdR3FOITBXCTpSTXOTn8xKt4OF2J obSAObVoQGHx9OiVoLWbZGyUrfnpMbjd8HvdveC9Cyi+Y0TF9ah8pDzo4GoLDm1SZgGf gXZyqzx/lEmpzQymVP2KOFqQF332s+Km0XSbSS7LKWop90dg2MmCisqDozVICHgHANSo nRBZONdD5OrIqgmmx8vSOFGJX4dVSRm4T2ZZMM/kts6hDTmm565otP/e8HszYGAuyiLm lMc0llc2vHS+KQQk4yKdCddTs8JtO9suEgBpMCc/+glMZkEio5Duwwu9htMnsTKFKZqJ LhNg== 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=BJlLE2lFOJNAOf2plvGrZniyHqHHYkxXA3UOhXtmdC8=; b=kSMy6mN6Sjmfn6anIV2KvQJ6ZF0hZnm8br+nvnnIS+vuIqOcJTuVNaAo9zEvOP4Nd1 Ehu60T/YWYONVhHHcPjKsjgZpqxqIrghg7EtO5aeDf4Biel/bCHMgPwDf6jCsq0gPykD UBMQgc/tEemUjEiFC7elrQo+IZXSFT+IH9wK1mUlT/r1Tra4lsuN6J/WaRWwQOpNOTR7 cY88mAYUQ+avWXBzjKtaB4BrY+pkCiNjckb1teNBZ/uDYBufHKaiFXDntgmKdjF+6m5W 8FV/ZUg2BV+l1RbRTKQk0bgc78TF8aE2nLtB/lV/V24DVANQy32QYv5WQOESGRi6HrEW 7YMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=nMEYDNFf; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 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. [85.214.62.61]) by mx.google.com with ESMTPS id s16si8869858ejf.641.2020.12.22.06.11.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 22 Dec 2020 06:11:04 -0800 (PST) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=nMEYDNFf; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 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 A111782AE8; Tue, 22 Dec 2020 15:10:33 +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="nMEYDNFf"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 4F3C882ACB; Tue, 22 Dec 2020 15:10:06 +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 mailout1.w1.samsung.com (mailout1.w1.samsung.com [210.118.77.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 25E2282ACB for ; Tue, 22 Dec 2020 15:09:51 +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 eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20201222140950euoutp01fe15a310671d1c60b9ebc7614a2aa899~TDy---imw2159821598euoutp01h for ; Tue, 22 Dec 2020 14:09:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20201222140950euoutp01fe15a310671d1c60b9ebc7614a2aa899~TDy---imw2159821598euoutp01h DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1608646190; bh=BJlLE2lFOJNAOf2plvGrZniyHqHHYkxXA3UOhXtmdC8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nMEYDNFfA7hz3xDqL18isx6afSDw2CA/1u//ovgZIFzzQZ29tYEuM0OXtTLt7eJJF 9cVoEx0FbAdHREIlR86Ccrs5Y3GgNdDB+FvDMQxrckvllxVe7qxQNQO7sez0CrFzVH HArgSOW/gRRNp+skfd14niWKcv25N8qX4/W+ssXI= Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20201222140950eucas1p2942c51cfa51bd893a171b0d6a8882633~TDy-w8XlQ3184531845eucas1p2I; Tue, 22 Dec 2020 14:09:50 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id BD.8D.45488.E2EF1EF5; Tue, 22 Dec 2020 14:09:50 +0000 (GMT) Received: from eusmtrp2.samsung.com (unknown [182.198.249.139]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20201222140949eucas1p2b78da473484eb152426266c7ac7a11bb~TDy-N8u1N0132001320eucas1p2z; Tue, 22 Dec 2020 14:09:49 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eusmtrp2.samsung.com (KnoxPortal) with ESMTP id 20201222140949eusmtrp269ac0b810dc153c4a70446bcbe4b20cc~TDy-NQNwb0701407014eusmtrp2z; Tue, 22 Dec 2020 14:09:49 +0000 (GMT) X-AuditID: cbfec7f5-c77ff7000000b1b0-fa-5fe1fe2e6f08 Received: from eusmtip1.samsung.com ( [203.254.199.221]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 77.37.16282.D2EF1EF5; Tue, 22 Dec 2020 14:09:49 +0000 (GMT) Received: from AMDC2765.digital.local (unknown [106.120.51.73]) by eusmtip1.samsung.com (KnoxPortal) with ESMTPA id 20201222140949eusmtip12f8269b9b947ca9c8b6ae3b146164f55~TDy_0rzuQ0857608576eusmtip1H; Tue, 22 Dec 2020 14:09:49 +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 v2 6/6] cmd: Add MBR partition layout control utility Date: Tue, 22 Dec 2020 15:09:14 +0100 Message-Id: <20201222140914.9933-7-m.szyprowski@samsung.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20201222140914.9933-1-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA0VSZ0wTYRjmu7u2B6Z6LUZeEDUUJwkroFbBLUn1h4p7gLXKyRCQ9EBBCUPZ IjOgLUQ0ziCIAxAxoq2EJYUi0qDWINEooBiQYgLRIueh/nveZ3zPmzcfiYuHCTsyODySVoYr QiV8K6K6YazN2cXcK3czvwHpvYsVPGn3eApP+vlbJyYtr38nkP6orEbSwSfpAunzgiG0ViAr SuggZJfUTYRsaPigTGesQbKsylK0jbffyjuADg0+QStdVx+yCqoeMWERg3R065MelIBKtmYg SxIoTygprORnICtSTN1CUPP9O48bTAiMVWoBN4wgKLzxhvgbyXp3nuCEm5ORh4//R8wPx/ms i0+5Q8Zgxh88kwIYz+5CrAmnzAg048M8VrCmfMBseopYTFAL4Gl/0p+AkPKGuk/NiKubB7fv PsNZbEmtgoY+I84+BJSKhK+pOgFn2gi/8gwYh61hoLFyireHiUclGBc4i6C3rVzADZkIOs9c nKrwAmMbuzc5ud8SqKh15eh18OBaPsbSQE2H7kERS+OTMK/6As7RQkhLEXPuhaBuvPOvVqN/ iXNYBmMj16YulINAl/qYyEHz1P/LLiNUimzoKCYskGY8wumTLowijIkKD3Q5cjzsPpr8FS/M jaM16NbAsIsWYSTSIiBxyUzhMrseuVgYoIg5RSuPy5VRoTSjRbNJQmIjrK0qk4upQEUkfYym I2jlXxUjLe0SsNjkj7OOYo4hhhEHY0oar+mcNs7Dq6JoWX7rnjVLN+jDcCdR+QWRxbY5r2Pj fSWHlxjTYwSLu8oKDF89M+cv36w0TOw1xF5OnYinR0PrfBMFqq0zyt4vXG9TkdieJoq51Nnk x08yvXq+qMfRQZ64cq7uhL4+wV9rLO7bdXOs5kBIoDtz3fishWdiVP074lT1dk1XF7T01xbg e3xqrTWjzgMqYk7dlml+re3+SuKIusjTJq1Pv1uyr3FnjK3GHkUwHQ6q5B/1Rc039umv2E5s qnK1KHXr+yl6q9KBd/f2D1/aZ+WERAevKHYKqiux7PKL3sFbk+udLbSV5qoamMNxpyUEE6Rw d8KVjOI3Ai9kKIQDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrPLMWRmVeSWpSXmKPExsVy+t/xu7q6/x7GG3S/NrTYOGM9q8WNX22s Fs/fXWayWHvkLrvFty3bGC3e7u1ktzg89QOjA7vH7IaLLB7zZp1g8fjwMc7j7J0djB59W1Yx BrBG6dkU5ZeWpCpk5BeX2CpFG1oY6RlaWugZmVjqGRqbx1oZmSrp29mkpOZklqUW6dsl6GVs +/yFqeBtasWZvfcZGxjn+3cxcnJICJhI9N3tZeli5OIQEljKKPFgxlJWiISMxMlpDVC2sMSf a11sEEWfGCXu/lzBApJgEzCU6HoLkuDkEBGQkPjVf5URxGYWaGKSWPsfzBYWcJX492U/mM0i oCqx/2ULWD2vgI3EvmcnGSEWyEus3nCAGcTmFLCVOPbiDpDNAbTMRuLM3uoJjHwLGBlWMYqk lhbnpucWG+kVJ+YWl+al6yXn525iBIbstmM/t+xgXPnqo94hRiYOxkOMEhzMSiK8ZlL344V4 UxIrq1KL8uOLSnNSiw8xmgKdMZFZSjQ5Hxg1eSXxhmYGpoYmZpYGppZmxkrivCZH1sQLCaQn lqRmp6YWpBbB9DFxcEo1MK3KKFn09GFR4Yp50rU8d9MTnhacrPK2+u3vuo3X4m3bpr6T1xa9 0BbZHJLy8/5pltK9Gr5TRBKMXDb/fbiNe8OBqB9zzfo5fh/Jz8pjaLkprnju9WHRqfMmT+Wt tbmR7lD8YP/cygcdWby333bOu/b8Z1/VXVHXT++vLi2zOtXXFmgy+azj9PeZTR//u286sevE 2bndr84muQoaNDHeWBn2VquZ9dXS1RHRN1NbtT1Ylt3d1KOy7ukqzi7GG8LyTOcdI1qzr4gE sE41OPhETO11oohBb4WiWvHnWYUKC2Yt3bdUdUdTdG/Q3RuWJuknosrnLdi0/l3wisvbsmYy Hbi/esNUm1v/JLxu3O1lvXNdiaU4I9FQi7moOBEAMlkZgeICAAA= X-CMS-MailID: 20201222140949eucas1p2b78da473484eb152426266c7ac7a11bb X-Msg-Generator: CA X-RootMTR: 20201222140949eucas1p2b78da473484eb152426266c7ac7a11bb X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20201222140949eucas1p2b78da473484eb152426266c7ac7a11bb References: <20201222140914.9933-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 user create or verify MBR partition layout based on the provided text description. The partition layout is altearnatively read from '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 system ID). 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 the 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..ee27b00c75 --- /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 user to create or verify MBR partition layout +based on the provided text description. The partition layout is +altearnatively read from '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 system ID) + +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 the 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 | ++---+------------------------------+