From patchwork Tue Dec 22 14:09:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 1419406 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=samsung.com header.i=@samsung.com header.a=rsa-sha256 header.s=mail20170921 header.b=ZhdpZO9w; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D0dXh3bWCz9sT5 for ; Wed, 23 Dec 2020 01:10:43 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 63A1182ADA; Tue, 22 Dec 2020 15:10:20 +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="ZhdpZO9w"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 67FA582ACF; Tue, 22 Dec 2020 15:09:59 +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 C6E0E82ACA for ; Tue, 22 Dec 2020 15:09:50 +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 20201222140950euoutp02e3b2f6c8d2f916a5eec03b7671159407~TDy-r_oNq1679716797euoutp02J for ; Tue, 22 Dec 2020 14:09:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20201222140950euoutp02e3b2f6c8d2f916a5eec03b7671159407~TDy-r_oNq1679716797euoutp02J DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1608646190; bh=tDFCjWKocLJWkA8qepdKzWD2NKv/q7ZbWXv1gpTOKOc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZhdpZO9wmLekWduTEBlin04tDwbDdsgBiVbrRsGuzXBZxgDuQPab2P5xBv31vFy58 yVc2RfM66DCERozzARhgVO47CG22FOd2g5dIa+Oz4ntXofnjRJTOqDqnY561Yzk5vY 9R5Vjuf2xZiJ54X6KqF83ybpK0PMxaEdzlMxFHAI= Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20201222140950eucas1p273b4012e982b266d72a732c67a369045~TDy-fF0so0132001320eucas1p20; 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 EC.8D.45488.E2EF1EF5; Tue, 22 Dec 2020 14:09:50 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20201222140949eucas1p2cff5aaa0cc0e602762470b61d4e157aa~TDy_48N5U2496624966eucas1p2n; Tue, 22 Dec 2020 14:09:49 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20201222140949eusmtrp12c4e0aaea5420375e451732fd2007801~TDy_4YksN0854808548eusmtrp1U; Tue, 22 Dec 2020 14:09:49 +0000 (GMT) X-AuditID: cbfec7f5-c77ff7000000b1b0-f8-5fe1fe2ef0f9 Received: from eusmtip1.samsung.com ( [203.254.199.221]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 11.6A.21957.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 20201222140949eusmtip161dfe821050075787b9cceddcd041550~TDy_e8MU50859208592eusmtip1D; 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 5/6] disk: dos: add code for creating MBR partition layout Date: Tue, 22 Dec 2020 15:09:13 +0100 Message-Id: <20201222140914.9933-6-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: H4sIAAAAAAAAA+NgFnrHIsWRmVeSWpSXmKPExsWy7djPc7p6/x7GG1z7x2axccZ6Vosbv9pY LZ6/u8xksfbIXXaLb1u2MVq83dvJbnF46gdGB3aP2Q0XWTzmzTrB4vHhY5zH2Ts7GD36tqxi DGCN4rJJSc3JLEst0rdL4Mo4vv8WS0GDYcWS7z1sDYx9al2MnBwSAiYSX64dZe5i5OIQEljB KHH05ywmCOcLo8TxSbtYQKqEBD4zSlw+otTFyAHW8XSDG0TNckaJ/Sv2ssA13FrUygbSwCZg KNH1tgvMFhGQkPjVf5URpIhZ4B+jxMFfH1lBEsIC/hIHL30Fs1kEVCU6X69nBrF5BWwk1uz4 xgpxn7zE6g0HwOKcArYSx17cAbtVQmAmh8T3txdZIIpcJH6dfg7VICzx6vgWdghbRuL05B4W iIZmRomH59ayQzg9QP80zWCEqLKWuHPuFxvIc8wCmhLrd+lDhB0l9i9tY4P4mU/ixltBkDAz kDlp23RmiDCvREebEES1msSs4+vg1h68cIkZwvaQeNB4gRkSihMYJRZuMJjAKD8LYdcCRsZV jOKppcW56anFxnmp5XrFibnFpXnpesn5uZsYgUni9L/jX3cwrnj1Ue8QIxMH4yFGCQ5mJRFe M6n78UK8KYmVValF+fFFpTmpxYcYpTlYlMR5d21dEy8kkJ5YkpqdmlqQWgSTZeLglGpg2mGn mnu53sRyU63W1/8VAg94LA9xvW99dP612CeF+h/Xz3BJLzv64nUTz1fFM9sqb9z+aPQg6G/8 0jMOmw7MdfrtEnH64PNSl691ueulj9lF8qzlZMwN3nrVgeNJafnK9QXixhxxL0z2R/5+98M3 efbm+qWlZzN6I6/aXo80OZi44Wyp5P/YyTa67ksshVdo3Jh8+MAOo4zfpX7vyx1VjyQ0B99d fMwk0lmIZX/itpNNbK5XJ4vJrnLSkjB/fT4kLbt9KQfDv98dkS+L4jZfknpUfoCf21Kv/69B EfcaJWExw+7FPEtc/JlCpPT4bzwrkWPbbNl9necRV1SRmYXoraPT+Ez87Co4y6fuF/BQYinO SDTUYi4qTgQAbZqzJYEDAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrHLMWRmVeSWpSXmKPExsVy+t/xu7q6/x7GG8y6LW2xccZ6Vosbv9pY LZ6/u8xksfbIXXaLb1u2MVq83dvJbnF46gdGB3aP2Q0XWTzmzTrB4vHhY5zH2Ts7GD36tqxi DGCN0rMpyi8tSVXIyC8usVWKNrQw0jO0tNAzMrHUMzQ2j7UyMlXSt7NJSc3JLEst0rdL0Ms4 vv8WS0GDYcWS7z1sDYx9al2MHBwSAiYSTze4dTFycQgJLGWUWL+7m7WLkRMoLiNxcloDlC0s 8edaFxtE0SdGiYtPtrCAJNgEDCW63oIkODlEBCQkfvVfZQSxmQWamCTW/gezhQV8JXbt2csM YrMIqEp0vl4PZvMK2Eis2fENaoG8xOoNB8DinAK2Esde3GEGOU4IqObM3uoJjHwLGBlWMYqk lhbnpucWG+oVJ+YWl+al6yXn525iBAbstmM/N+9gnPfqo94hRiYOxkOMEhzMSiK8ZlL344V4 UxIrq1KL8uOLSnNSiw8xmgKdMZFZSjQ5HxgzeSXxhmYGpoYmZpYGppZmxkrivFvnrokXEkhP LEnNTk0tSC2C6WPi4JRqYKp+tfDv/XeOYm+YGm1nWB5IjDY023c6kP2EmPiTWem7dmSpfjwV kHFp48sJ8y5se2pUP2nZgYrNF64uiN6yUm11cVhk8pvLyV5uz78IrVow13hB0YpHC3xfnRQx rQ47siJ2YXGchds0Cza11EiWNhvzN4uOKRZO/jZf83q6fza77uEp0kl8/Xs2CEy5yqd0uXDO 662vA865/c7v+V6fspX/5tGIyeEzWHWvhF6YmPz1yWcltqNH3h3qLrjW9KnBcjGDyJSr3Eua fXh/5D57U29m6Mzdu6lX6J+JxKFbmn8m2s3bss5jSZ1vj+Qko+6fHxV33mvuXXjl8IkfeoxC Nk7bw983ndrVadkze7Gdw6lOJZbijERDLeai4kQAVVHjPuECAAA= X-CMS-MailID: 20201222140949eucas1p2cff5aaa0cc0e602762470b61d4e157aa X-Msg-Generator: CA X-RootMTR: 20201222140949eucas1p2cff5aaa0cc0e602762470b61d4e157aa X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20201222140949eucas1p2cff5aaa0cc0e602762470b61d4e157aa 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 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(+) 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