From patchwork Wed Dec 23 12:55: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: 351448 Delivered-To: patch@linaro.org Received: by 2002:a02:85a7:0:0:0:0:0 with SMTP id d36csp6172460jai; Wed, 23 Dec 2020 04:56:16 -0800 (PST) X-Google-Smtp-Source: ABdhPJwsG/B8Tgjta9GKbpfvgAYRUDx9qqqErcl0mvfg+lIPwFhmBt9QHNxrk/QQIkv2KHru19iN X-Received: by 2002:a17:906:7a18:: with SMTP id d24mr24302261ejo.324.1608728176188; Wed, 23 Dec 2020 04:56:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1608728176; cv=none; d=google.com; s=arc-20160816; b=Z/BEFKyJAkFQnRNtUMJCp/Na/go8d3oAGyCC1e+uEcNNSpDtgs0ZMo+m78M0M1kDyE 7bZZ4CTErFvMRzDbjSzICY8r7W7veNNL8bx/DJIrI1kdsq5qAmtNGTg3hf+I0yvFYjRb BWY9dbcbkorD5YB4RvqqlSpzT/aJd44KZ+erv3vSnjcYyVUgtaljetMohXQVmKVSACSR jxkWNqUiAUbTfkzJmkP3MbYABSNp/gXOqcsJS20JbgsbsVSeXN8pugCrXttgaV+0Yrrp rXhugdDMbbtlU71HYLNz90ph3ju8r7RRA0E9ur8tnX3KXJaHrSnJn6tCtlLRFTye3oMv 9dAg== 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=k9oMBZwID77q6mtg2L5cpHL5kStBnaPFM2CjIM8gmj0=; b=Qhm/BkhfU+p6aWLWR4Rjwms/rtZ3/awUuXnerqJptPfUukwPaWDOxohPAQplu4xfO2 pycI+51tVn8YGoxQLjSyHepIbEmG0uD7QiAzUHDERygZ8vWztjLx4vdOapbOVUXpDCnF PTv5DiG4vcykrvohBWV/k0QG/lCHnrTLktYtQQ3HdfQrfifKdgdmC7BynN+Qv8nj8wWi K9w82y2rR3slZlCfpDgbrksPfDgjJ34dKQ4TMgnMfDjrIBwxiM/M60spFDenU3H/Gske vhKB38maoMd0rd+PKUGTpqTPcWqwWZqrcEvQjYj1lQX/nb+SdAk/7tS7rC4q1Q75M2nV SKJw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@samsung.com header.s=mail20170921 header.b=tgzAgLNu; 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 c35si13514970edf.522.2020.12.23.04.56.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Dec 2020 04:56:16 -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=tgzAgLNu; 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 0A3368273E; Wed, 23 Dec 2020 13:55:52 +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="tgzAgLNu"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id BD90D82770; Wed, 23 Dec 2020 13:55:43 +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 552F48272E for ; Wed, 23 Dec 2020 13:55:36 +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 mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20201223125535euoutp0239a07892a6e1c7622d1eff00bb6655be~TWbdW0rIU3178531785euoutp02e for ; Wed, 23 Dec 2020 12:55:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20201223125535euoutp0239a07892a6e1c7622d1eff00bb6655be~TWbdW0rIU3178531785euoutp02e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1608728135; bh=k9oMBZwID77q6mtg2L5cpHL5kStBnaPFM2CjIM8gmj0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tgzAgLNut+xfFD/GIMd2vE2+yp2FZwg8CgsBAEoBGVoer2Upf5CZbiW1y2s5jsIXg Z22QSLkFlNgbWHEtKirqw6tYY2T2emu+Ye90t4iYiYhKeQrpfpIEmih/wOw3ajUSGk jU/xZbPWrAEJty7jVe1TD48rI/fR8153H0hXqgYQ= Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20201223125535eucas1p2eb932cf4db93a6c845283571fc9f41ff~TWbdGIgli0881908819eucas1p2E; Wed, 23 Dec 2020 12:55:35 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id FD.41.45488.74E33EF5; Wed, 23 Dec 2020 12:55:35 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20201223125535eucas1p2358eef28313de969c15405450a5b9acf~TWbcxDeR_0881908819eucas1p2D; 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 20201223125535eusmtrp1cf5b55962d9a7eb1ee0b65629372ae6d~TWbcwZp7S2414424144eusmtrp1k; Wed, 23 Dec 2020 12:55:35 +0000 (GMT) X-AuditID: cbfec7f5-c5fff7000000b1b0-62-5fe33e47d44d Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 82.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 20201223125534eusmtip23fcb9a67bcea49d16ad8393f81c7fc7b~TWbcYimYq2192921929eusmtip28; Wed, 23 Dec 2020 12:55:34 +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 5/6] disk: dos: add code for creating MBR partition layout Date: Wed, 23 Dec 2020 13:55:14 +0100 Message-Id: <20201223125515.28865-6-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+NgFnrPIsWRmVeSWpSXmKPExsWy7djPc7rudo/jDVa1K1hsnLGe1eLGrzZW i+fvLjNZrD1yl93i25ZtjBZv93ayWxye+oHRgd1jdsNFFo95s06weHz4GOdx9s4ORo++LasY A1ijuGxSUnMyy1KL9O0SuDKOLT3MWNBgWLHkew9bA2OfWhcjJ4eEgInE/rMzGLsYuTiEBFYw SvROncYE4XxhlDh8ZBYbhPOZUaJz8i92mJavM79DtSwHStw5i9Cyt+8pK0gVm4ChRNfbLjYQ W0RAQuJX/1WwDmaBf4wSB399BCri4BAW8JdYtkILpIZFQFXi8cazYPW8ArYSq9ddY4LYJi+x esMBZhCbU8BO4tuCDlaQORICUzkk5q5+CFXkIvG88y4LhC0s8er4FqhTZSROT+5hgWhoZpR4 eG4tO4TTwyhxuQnkb5Aqa4k7536xgVzELKApsX6XPkTYUWL7ov+MIGEJAT6JG28FQcLMQOak bdOZIcK8Eh1tQhDVahKzjq+DW3vwwiWoEg+J85MjIeEzkVGiadsKlgmM8rMQdi1gZFzFKJ5a WpybnlpsnJdarlecmFtcmpeul5yfu4kRmCZO/zv+dQfjilcf9Q4xMnEwHmKU4GBWEuG9xP84 Xog3JbGyKrUoP76oNCe1+BCjNAeLkjjvrq1r4oUE0hNLUrNTUwtSi2CyTBycUg1MQd+3T+RS iJz74bH0LZZZDZvzqtIOSdgtDvo6yfpl1n0tJ22mzdGujMe2L27eulagd7PKReXZcxKbdu90 Kq679bU2/ADbxONidg3WPxUvlq6y7t2pcIxj/d09Yclah5hiNdaJSt1Mf+f4b3FO9ZWtQV94 J9vNOuV+4tA+n+9/u27xBRjcvmj1wdS0KC3KzGE6S62/RdGvnQzZjpmTTq1YtJs3YoNioMHn i6W96cqG1YuP/ta2850owJIfuP/cozXf1O7NY5m74uG5R7pp+ScfidvuPf/HSEbeu2tzwY9F OcfWG3WJ5U5/pVFp8uvs/u9pUzqOVK+9ovfuQ7ulaseDt0s0jxe3Hz0XYb5jtmegrhJLcUai oRZzUXEiABEHVIiCAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrALMWRmVeSWpSXmKPExsVy+t/xe7rudo/jDR4e5LLYOGM9q8WNX22s Fs/fXWayWHvkLrvFty3bGC3e7u1ktzg89QOjA7vH7IaLLB7zZp1g8fjwMc7j7J0djB59W1Yx BrBG6dkU5ZeWpCpk5BeX2CpFG1oY6RlaWugZmVjqGRqbx1oZmSrp29mkpOZklqUW6dsl6GUc W3qYsaDBsGLJ9x62BsY+tS5GTg4JAROJrzO/M3YxcnEICSxllPiyo4sdIiEjcXJaAyuELSzx 51oXG0TRJ0aJLfPOMoIk2AQMJbregiQ4OUQEJCR+9V8FizMLNDFJrP0PZgsL+EqsubeUCcRm EVCVeLzxLFg9r4CtxOp115ggFshLrN5wgBnE5hSwk/i2oANssRBQzaxT65gnMPItYGRYxSiS Wlqcm55bbKRXnJhbXJqXrpecn7uJERi024793LKDceWrj3qHGJk4GA8xSnAwK4nwXuJ/HC/E m5JYWZValB9fVJqTWnyI0RTojonMUqLJ+cC4ySuJNzQzMDU0MbM0MLU0M1YS5zU5siZeSCA9 sSQ1OzW1ILUIpo+Jg1OqgWlBzjsp6eumKfGnwtdfvaHqs9ubgeno576fB3cdfl3UlzjJdoaE z8Gn5XkhGczz0+/cfD6zoevC/7/bdxs0zVI63K2Wv/O68ckPt3tfZtwp/nXDWWNu+pxvPGXH Fu9/YeZnJiJxKafFOeqO1aX34XMFeVd/ib2ipVAWJSYZ0FRcH59rs+GphMvenWLGjuyr4u7O 3LGcpWOPStGpSWIViw/J6WbO2cb7Nf18T+iT3Uc+vza17cxMn/vZSMOZ93zQJ2t1lUyTpmMF duf0YoO0o/ucN8/1N19lW545OyOkuOYAk/H/GbXfDj+YVbJvknuFjXN1pkFWdRnHsm3LKqNT nvQJGr7ST0n2vnuHhX/NPiWW4oxEQy3mouJEAFH5h3TjAgAA X-CMS-MailID: 20201223125535eucas1p2358eef28313de969c15405450a5b9acf X-Msg-Generator: CA X-RootMTR: 20201223125535eucas1p2358eef28313de969c15405450a5b9acf X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20201223125535eucas1p2358eef28313de969c15405450a5b9acf 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 code for creating and writing MBR partition layout. The code generates similar layout of EBRs (Exteneded Block Records) and logical volumes as Linux's fdisk utility. Signed-off-by: Marek Szyprowski --- disk/part_dos.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++ disk/part_dos.h | 2 + include/part.h | 5 ++ 3 files changed, 174 insertions(+) -- 2.17.1 diff --git a/disk/part_dos.c b/disk/part_dos.c index 2c4ad0b6ba..f77f927995 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -319,6 +319,173 @@ int is_valid_dos_buf(void *buf) return test_block_type(buf) == DOS_MBR ? 0 : -1; } +#if CONFIG_IS_ENABLED(CMD_MBR) +static void lba_to_chs(lbaint_t lba, unsigned char *rc, unsigned char *rh, + unsigned char *rs) +{ + unsigned int c, h, s; + /* use fixed CHS geometry */ + unsigned int sectpertrack = 63; + unsigned int heads = 255; + + c = (lba + 1) / sectpertrack / heads; + h = (lba + 1) / sectpertrack - c * heads; + s = (lba + 1) - (c * heads + h) * sectpertrack; + + if (c > 1023) { + c = 1023; + h = 254; + s = 63; + } + + *rc = c & 0xff; + *rh = h; + *rs = s + ((c & 0x300) >> 2); +} + +static void mbr_fill_pt_entry(dos_partition_t *pt, lbaint_t start, + lbaint_t relative, lbaint_t size, uchar sys_ind, bool bootable) +{ + pt->boot_ind = bootable ? 0x80 : 0x00; + pt->sys_ind = sys_ind; + lba_to_chs(start, &pt->cyl, &pt->head, &pt->sector); + lba_to_chs(start + size - 1, &pt->end_cyl, &pt->end_head, &pt->end_sector); + put_unaligned_le32(relative, &pt->start4); + put_unaligned_le32(size, &pt->size4); +} + +int write_mbr_partitions(struct blk_desc *dev, + struct disk_partition *p, int count, unsigned int disksig) +{ + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev->blksz); + lbaint_t ext_part_start = 0, ext_part_size = 0, ext_part_sect = 0; + dos_partition_t *pt; + int i; + + memset(buffer, 0, dev->blksz); + buffer[DOS_PART_MAGIC_OFFSET] = 0x55; + buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa; + put_unaligned_le32(disksig, &buffer[DOS_PART_DISKSIG_OFFSET]); + pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); + + /* create all primary partitions */ + for (i = 0; i < 4 && i < count; i++, pt++) { + mbr_fill_pt_entry(pt, p[i].start, p[i].start, p[i].size, + p[i].sys_ind, p[i].bootable); + if (is_extended(p[i].sys_ind)) { + ext_part_start = p[i].start; + ext_part_size = p[i].size; + ext_part_sect = p[i].start; + } + } + + if (i < count && !ext_part_start) { + printf("%s: extended partition is needed for more than 4 partitions\n", + __func__); + return -1; + } + + /* write MBR */ + if (blk_dwrite(dev, 0, 1, buffer) != 1) { + printf("%s: failed writing 'MBR' (1 blks at 0x0)\n", + __func__); + return -1; + } + + /* create extended volumes */ + for (; i < count; i++) { + lbaint_t next_ebr = 0; + + memset(buffer, 0, dev->blksz); + buffer[DOS_PART_MAGIC_OFFSET] = 0x55; + buffer[DOS_PART_MAGIC_OFFSET + 1] = 0xaa; + pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); + + mbr_fill_pt_entry(pt, p[i].start, p[i].start - ext_part_sect, + p[i].size, p[i].sys_ind, p[i].bootable); + + if (i + 1 < count) { + pt++; + next_ebr = p[i].start + p[i].size; + mbr_fill_pt_entry(pt, next_ebr, + next_ebr - ext_part_start, + p[i+1].start + p[i+1].size - next_ebr, + DOS_PART_TYPE_EXTENDED, 0); + } + + /* write EBR */ + if (blk_dwrite(dev, ext_part_sect, 1, buffer) != 1) { + printf("%s: failed writing 'EBR' (1 blks at 0x%lx)\n", + __func__, ext_part_sect); + return -1; + } + ext_part_sect = next_ebr; + } + + return 0; +} + +int layout_mbr_partitions(struct disk_partition *p, int count, + lbaint_t total_sectors) +{ + struct disk_partition *ext = NULL; + int i, j; + lbaint_t ext_vol_start; + + /* calculate primary partitions start and size if needed */ + if (!p[0].start) + p[0].start = DOS_PART_DEFAULT_GAP; + for (i = 0; i < 4 && i < count; i++) { + if (!p[i].start) + p[i].start = p[i - 1].start + p[i - 1].size; + if (!p[i].size) { + lbaint_t end = total_sectors; + lbaint_t allocated = 0; + + for (j = i + 1; j < 4 && j < count; j++) { + if (p[j].start) { + end = p[j].start; + break; + } + allocated += p[j].size; + } + p[i].size = end - allocated - p[i].start; + } + if (p[i].sys_ind == 0x05) + ext = &p[i]; + } + + if (i >= 4 && !ext) { + printf("%s: extended partition is needed for more than 4 partitions\n", + __func__); + return -1; + } + + /* calculate extended volumes start and size if needed */ + ext_vol_start = ext->start; + for (i = 4; i < count; i++) { + if (!p[i].start) + p[i].start = ext_vol_start + DOS_PART_DEFAULT_GAP; + if (!p[i].size) { + lbaint_t end = ext->start + ext->size; + lbaint_t allocated = 0; + + for (j = i + 1; j < count; j++) { + if (p[j].start) { + end = p[j].start - DOS_PART_DEFAULT_GAP; + break; + } + allocated += p[j].size + DOS_PART_DEFAULT_GAP; + } + p[i].size = end - allocated - p[i].start; + } + ext_vol_start = p[i].start + p[i].size; + } + + return 0; +} +#endif + int write_mbr_sector(struct blk_desc *dev_desc, void *buf) { if (is_valid_dos_buf(buf)) diff --git a/disk/part_dos.h b/disk/part_dos.h index dd909a9317..5055822422 100644 --- a/disk/part_dos.h +++ b/disk/part_dos.h @@ -19,6 +19,8 @@ #define DOS_PART_TYPE_EXTENDED_LBA 0x0F #define DOS_PART_TYPE_EXTENDED_LINUX 0x85 +#define DOS_PART_DEFAULT_GAP 2048 + typedef struct dos_partition { unsigned char boot_ind; /* 0x80 - active */ unsigned char head; /* starting head */ diff --git a/include/part.h b/include/part.h index 67b8b2a5cc..fac36364bd 100644 --- a/include/part.h +++ b/include/part.h @@ -474,6 +474,11 @@ int is_valid_dos_buf(void *buf); */ int write_mbr_sector(struct blk_desc *dev_desc, void *buf); +int write_mbr_partitions(struct blk_desc *dev, + struct disk_partition *p, int count, unsigned int disksig); +int layout_mbr_partitions(struct disk_partition *p, int count, + lbaint_t total_sectors); + #endif