From patchwork Thu Sep 13 08:10:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?=C5=81ukasz_Majewski?= X-Patchwork-Id: 183545 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 69E802C0081 for ; Thu, 13 Sep 2012 18:11:21 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 340D228174; Thu, 13 Sep 2012 10:11:08 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Y-tK9j51aD9L; Thu, 13 Sep 2012 10:11:07 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 4AC632816B; Thu, 13 Sep 2012 10:10:59 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D597C28166 for ; Thu, 13 Sep 2012 10:10:56 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3sxp6FtTYDTz for ; Thu, 13 Sep 2012 10:10:56 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mailout1.samsung.com (mailout1.samsung.com [203.254.224.24]) by theia.denx.de (Postfix) with ESMTP id 5EACA28145 for ; Thu, 13 Sep 2012 10:10:43 +0200 (CEST) Received: from epcpsbgm2.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MAA00JKR3ZC2R90@mailout1.samsung.com> for u-boot@lists.denx.de; Thu, 13 Sep 2012 17:10:33 +0900 (KST) X-AuditID: cbfee61b-b7f586d000007adc-de-505194f9c579 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id AE.E9.31452.9F491505; Thu, 13 Sep 2012 17:10:33 +0900 (KST) Received: from mcdsrvbld02.digital.local ([106.116.37.23]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MAA00LL040VU440@mmp1.samsung.com> for u-boot@lists.denx.de; Thu, 13 Sep 2012 17:10:33 +0900 (KST) From: Lukasz Majewski To: u-boot@lists.denx.de Date: Thu, 13 Sep 2012 10:10:03 +0200 Message-id: <1347523805-17825-6-git-send-email-l.majewski@samsung.com> X-Mailer: git-send-email 1.7.10 In-reply-to: <1347523805-17825-1-git-send-email-l.majewski@samsung.com> References: <1345795995-24656-1-git-send-email-l.majewski@samsung.com> <1347523805-17825-1-git-send-email-l.majewski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrMJMWRmVeSWpSXmKPExsVy+t9jAd2fUwIDDK7dMbF4u7eT3YHR4+yd HYwBjFFcNimpOZllqUX6dglcGXtXsRQcVK74v62LpYHxnUwXIyeHhICJRMv3FYwQtpjEhXvr 2boYuTiEBBYxSvScvMMEkhASWMwk8XJtFojNJqAn8fnuU7C4iICExK/+q4wgDcwC25kkjp/6 xgaSEBbwl+humMAKYrMIqEpcX/eIGcTmFXCT+DL9JDPENnmJp/f7wOo5Bdwl/u37zwKxuZlR 4tCuHSwTGHkXMDKsYhRNLUguKE5KzzXSK07MLS7NS9dLzs/dxAj2+jPpHYyrGiwOMQpwMCrx 8GY+DwgQYk0sK67MPcQowcGsJMKr3h0YIMSbklhZlVqUH19UmpNafIhRmoNFSZzX6ZxdgJBA emJJanZqakFqEUyWiYNTqoExzCGs9zgnL9NjEcujIhHnmOJf8xelM0340OaYFfQikOnxmwvy h6NlrK5unRmceEjtVP/leZY375pZvJM/E2o1Xb+KQ33p+X03HtadnPSSaXONiiOHZEqfpjqL 4dS2VxPu60k2lNs+WuH1+k+clJ6yFkvdSj/Lb1YP+/PvLtRdnL/xpcTBZSeUWIozEg21mIuK EwEVcocH9gEAAA== Cc: Stephen Warren , Kyungmin Park , Tom Warren , Tom Rini Subject: [U-Boot] [PATCH v3 5/7] gpt: Support for GPT (GUID Partition Table) restoration X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de The restoration of GPT table (both primary and secondary) is now possible. Simple GUID generation is supported. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park --- Changes for v2: - Move GPT Header and Page Table Entries generation code to cmd_gpt.c - Provide clean API to use set_gpt_table function for GPT restoration on a block device Changes for v3: - Replace printf with puts --- disk/part_efi.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/part.h | 3 ++ 2 files changed, 102 insertions(+), 0 deletions(-) diff --git a/disk/part_efi.c b/disk/part_efi.c index d4c61d2..19821f3 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -403,4 +403,103 @@ static int is_pte_valid(gpt_entry * pte) return 1; } } + +/** + * set_protective_mbr(): Set the EFI protective MBR + * @param dev_desc - block device descriptor + * + * @return - zero on success, otherwise error + */ +static int set_protective_mbr(block_dev_desc_t *dev_desc) +{ + legacy_mbr p_mbr; + + /* Setup the Protective MBR */ + memset((u32 *) &p_mbr, 0x00, sizeof(p_mbr)); + /* Append signature */ + p_mbr.signature = MSDOS_MBR_SIGNATURE; + p_mbr.partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; + p_mbr.partition_record[0].start_sect = 1; + p_mbr.partition_record[0].nr_sects = (u32) dev_desc->lba; + + /* Write MBR sector to the MMC device */ + if (dev_desc->block_write(dev_desc->dev, 0, 1, &p_mbr) != 1) { + printf("** Can't write to device %d **\n", + dev_desc->dev); + return -1; + } + + return 0; +} + +/** + * set_gpt_table() - Restore the GUID Partition Table + * + * @param dev_desc - block device descriptor + * @param parts - number of partitions + * @param size - pointer to array with each partition size + * @param name - pointer to array with each partition name + * + * @return - zero on success, otherwise error + */ +int set_gpt_table(block_dev_desc_t *dev_desc, + gpt_header *gpt_h, gpt_entry *gpt_e) +{ + const int pte_blk_num = (GPT_ENTRY_NUMBERS * sizeof(gpt_entry)) / + dev_desc->blksz; + u32 calc_crc32; + u64 val; + + debug("max lba: %x\n", (u32) dev_desc->lba); + + /* Setup the Protective MBR */ + if (set_protective_mbr(dev_desc) < 0) + goto err; + + /* Generate CRC for the Primary GPT Header */ + calc_crc32 = efi_crc32((const unsigned char *)gpt_e, + le32_to_cpu(gpt_h->num_partition_entries) * + le32_to_cpu(gpt_h->sizeof_partition_entry)); + gpt_h->partition_entry_array_crc32 = cpu_to_le32(calc_crc32); + + calc_crc32 = efi_crc32((const unsigned char *)gpt_h, + le32_to_cpu(gpt_h->header_size)); + gpt_h->header_crc32 = cpu_to_le32(calc_crc32); + + /* Write the First GPT to the block right after the Legacy MBR */ + if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1) + goto err; + + if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e) + != pte_blk_num) + goto err; + + /* recalculate the values for the Second GPT Header*/ + val = le64_to_cpu(gpt_h->my_lba); + gpt_h->my_lba = gpt_h->alternate_lba; + gpt_h->alternate_lba = cpu_to_le64(val); + gpt_h->header_crc32 = 0; + + calc_crc32 = efi_crc32((const unsigned char *)gpt_h, + le32_to_cpu(gpt_h->header_size)); + gpt_h->header_crc32 = cpu_to_le32(calc_crc32); + + /* Write the Second GPT that is located at the end of the disk */ + if (dev_desc->block_write(dev_desc->dev, + le32_to_cpu(gpt_h->last_usable_lba + 1), + pte_blk_num, gpt_e) != pte_blk_num) + goto err; + + if (dev_desc->block_write(dev_desc->dev, + le32_to_cpu(gpt_h->my_lba), 1, gpt_h) != 1) + goto err; + + puts("GPT successfully written to block device!\n"); + return 0; + + err: + printf("** Can't write to device %d **\n", + dev_desc->dev); + return -1; +} #endif diff --git a/include/part.h b/include/part.h index e1478f4..fc34ed2 100644 --- a/include/part.h +++ b/include/part.h @@ -157,10 +157,13 @@ int test_part_amiga (block_dev_desc_t *dev_desc); #endif #ifdef CONFIG_EFI_PARTITION +#include /* disk/part_efi.c */ int get_partition_info_efi (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); void print_part_efi (block_dev_desc_t *dev_desc); int test_part_efi (block_dev_desc_t *dev_desc); +int set_gpt_table(block_dev_desc_t *dev_desc, + gpt_header *gpt_h, gpt_entry *gpt_e); #endif #endif /* _PART_H */