| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716 |
- /* Copyright Statement:
- *
- * This software/firmware and related documentation ("MediaTek Software") are
- * protected under relevant copyright laws. The information contained herein
- * is confidential and proprietary to MediaTek Inc. and/or its licensors.
- * Without the prior written permission of MediaTek inc. and/or its licensors,
- * any reproduction, modification, use or disclosure of MediaTek Software,
- * and information contained herein, in whole or in part, shall be strictly prohibited.
- */
- /* MediaTek Inc. (C) 2015. All rights reserved.
- *
- * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
- * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
- * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
- * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
- * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
- * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
- * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
- * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
- * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
- * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
- * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
- * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
- * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
- * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
- * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
- * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
- */
- #include <printf.h>
- #include <malloc.h>
- #include <string.h>
- #include <lib/crc.h>
- #include <platform/mt_typedefs.h>
- #include <platform/partition.h>
- #include <efi.h>
- #include <part_interface.h>
- #include <block_generic_interface.h>
- #include <pal_log.h>
- #ifndef min
- #define min(x, y) (x < y ? x : y)
- #endif
- extern bool cmdline_append(const char *append_string);
- static part_t *g_part_ptr = NULL;
- u32 sgpt_partition_lba_size;
- static u64 g_gpt_entry_cnt = 0;
- /*
- ********** Definition of Debug Macro **********
- */
- #define TAG "[GPT_LK]"
- #define LEVEL_ERR (0x0001)
- #define LEVEL_INFO (0x0004)
- #define DEBUG_LEVEL (LEVEL_ERR | LEVEL_INFO)
- #define efi_err(fmt, args...) \
- do { \
- if (DEBUG_LEVEL & LEVEL_ERR) { \
- pal_log_err(fmt, ##args); \
- } \
- } while (0)
- #define efi_critical(fmt, args...) \
- do { \
- if (DEBUG_LEVEL & LEVEL_INFO) { \
- pal_log_err(fmt, ##args); \
- } \
- } while (0)
- /*
- ********** Definition of GPT buffer **********
- */
- static u32 efi_crc32(u8 *p, u32 len)
- {
- return (crc32_no_comp(~0L, p, len) ^ ~0L); /* from zlib */
- }
- static void w2s(u8 *dst, int dst_max, u16 *src, int src_max)
- {
- int i = 0;
- int len = min(src_max, dst_max - 1);
- while (i < len) {
- if (!src[i]) {
- break;
- }
- dst[i] = src[i] & 0xFF;
- i++;
- }
- dst[i] = 0;
- return;
- }
- u64 get_entry_count()
- {
- return g_gpt_entry_cnt;
- }
- extern u64 g_emmc_user_size;
- u64 last_lba(u32 part_id)
- {
- part_dev_t *dev;
- dev = mt_part_get_device();
- if (!dev) {
- efi_err("%s%s, err(no dev)\n", TAG, __func__);
- return 1;
- }
- /* Only support USER region now */
- #if (defined(MTK_EMMC_SUPPORT) || defined(MTK_UFS_SUPPORT))
- if (dev->blkdev->type == BOOTDEV_SDMMC) {
- return g_emmc_user_size / dev->blkdev->blksz - 1;
- } else if (dev->blkdev->type == BOOTDEV_UFS) {
- u64 bytes;
- bytes = dev->get_part_size(dev, part_id);
- if (bytes)
- return bytes / dev->blkdev->blksz - 1;
- else
- return 0;
- }
- #endif
- return 0;
- }
- static void set_spgt_partition_lba_size(u32 size)
- {
- sgpt_partition_lba_size = size;
- }
- static u32 get_spgt_partition_lba_size()
- {
- return sgpt_partition_lba_size;
- }
- static u64 get_gpt_header_last_usable_lba()
- {
- part_dev_t *dev = mt_part_get_device();
- return (last_lba(dev->blkdev->part_user)-get_spgt_partition_lba_size());
- }
- static u32 entries_crc32;
- static void set_entries_crc32(u32 crc32)
- {
- entries_crc32 = crc32;
- }
- static u32 get_entries_crc32(void)
- {
- return entries_crc32;
- }
- static int read_data(u8 *buf, u32 part_id, u64 lba, u64 size)
- {
- int err;
- part_dev_t *dev;
- dev = mt_part_get_device();
- if (!dev) {
- efi_err("%sread data, err(no dev)\n", TAG);
- return 1;
- }
- err = dev->read(dev, lba * dev->blkdev->blksz, buf, (int)size, part_id);
- if (err != (int)size) {
- efi_err("%sread data, err(%d)\n", TAG, err);
- return err;
- }
- return 0;
- }
- static int write_data(u64 lba, u8 *buf, u64 size, u32 part_id)
- {
- int err;
- part_dev_t *dev;
- dev = mt_part_get_device();
- if (!dev) {
- efi_err("%swrite data, err(no dev)\n", TAG);
- return 1;
- }
- err = dev->write(dev, buf, lba * dev->blkdev->blksz, (int)size, part_id);
- if (err != (int)size) {
- efi_err("%s write data, err(%d)\n", TAG, err);
- return err;
- }
- return 0;
- }
- const char hex_asc[] = "0123456789abcdef";
- #define hex_asc_lo(x) hex_asc[((x)&0x0f)];
- #define hex_asc_hi(x) hex_asc[((x)&0xf0)>>4];
- static inline char *hex_byte_pack(char *buf, u8 byte)
- {
- *buf++ = hex_asc_hi(byte);
- *buf++ = hex_asc_lo(byte);
- return buf;
- }
- static u8 *string(u8 *buf, u8 *end, const char *s)
- {
- int len, i;
- len = strnlen(s, PART_META_INFO_UUIDLEN);
- for (i = 0; i < len; ++i) {
- if (buf < end)
- *buf = *s;
- ++buf;
- ++s;
- }
- if (buf < end)
- *buf = 0;
- return buf;
- }
- static u8 *uuid_string(u8 *buf, u8 *args)
- {
- /* uuid format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx, which contains 16*2 + 4('-') + 1 ('\0') = 37 bytes*/
- char uuid[PART_META_INFO_UUIDLEN];
- char *p = uuid;
- int i;
- static const u8 index[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15};
- u8 *end;
- end = buf + PART_META_INFO_UUIDLEN;
- for (i = 0; i < 16; i++) {
- p = hex_byte_pack(p, args[index[i]]);
- switch(i) {
- case 3:
- case 5:
- case 7:
- case 9:
- *p++ = '-';
- break;
- default:
- break;
- }
- }
- *p = 0;
- return string(buf, end, uuid);
- }
- static inline u8 *efi_guid_unparse(efi_guid_t *guid, u8 *out)
- {
- if (NULL == uuid_string(out, guid->b)) {
- efi_err("parse uuid string format fail!\n");
- return NULL;
- }
- return out;
- }
- static int parse_gpt_header(u32 part_id, u64 header_lba, u8 *header_buf, u8 *entries_buf)
- {
- int i;
- int err;
- u32 calc_crc, orig_header_crc;
- u64 entries_real_size, entries_read_size, num_block_entry;
- part_dev_t *dev = mt_part_get_device();
- gpt_header *header = (gpt_header *)header_buf;
- gpt_entry *entries = (gpt_entry *)entries_buf;
- struct part_meta_info *info;
- if (!dev) {
- efi_err("%s%s, err(no dev)\n", TAG, __func__);
- return 1;
- }
- if (g_part_ptr == NULL) {
- efi_err("%sg_part_ptr is NULL, partition table was not initialized\n", TAG);
- return 1;
- }
- if (header_buf == NULL) {
- efi_err("%sheader_buf is NULL\n", TAG);
- return 1;
- }
- if (entries_buf == NULL) {
- efi_err("%sentries_buf is NULL\n", TAG);
- return 1;
- }
- err = read_data(header_buf, part_id, header_lba, dev->blkdev->blksz);
- if (err) {
- efi_err("%sread header(part_id=%d,lba=%llx), err(%d)\n",
- TAG, part_id, header_lba, err);
- return err;
- }
- if (header->signature != GPT_HEADER_SIGNATURE) {
- efi_err("%scheck header, err(signature 0x%llx!=0x%llx)\n",
- TAG, header->signature, GPT_HEADER_SIGNATURE);
- return 1;
- }
- orig_header_crc = header->header_crc32;
- header->header_crc32 = 0;
- calc_crc = efi_crc32((u8 *)header, header->header_size);
- if (orig_header_crc != calc_crc) {
- efi_err("%scheck header, err(crc 0x%x!=0x%x(calc))\n",
- TAG, orig_header_crc, calc_crc);
- return 1;
- }
- header->header_crc32 = orig_header_crc;
- if (header->my_lba != header_lba) {
- efi_err("%scheck header, err(my_lba 0x%llx!=0x%llx)\n",
- TAG, header->my_lba, header_lba);
- return 1;
- }
- entries_real_size = (u64)header->num_partition_entries * header->sizeof_partition_entry;
- num_block_entry = (u64)(dev->blkdev->blksz / header->sizeof_partition_entry);
- entries_read_size = (u64)((header->num_partition_entries + (num_block_entry -1)) / num_block_entry) * dev->blkdev->blksz;
- err = read_data(entries_buf, part_id, header->partition_entry_lba, entries_read_size);
- if (err) {
- efi_err("%sread entries(part_id=%d,lba=%llx), err(%d)\n",
- TAG, part_id, header->partition_entry_lba, err);
- return err;
- }
- calc_crc = efi_crc32((u8 *)entries, (u32)entries_real_size);
- if (header->partition_entry_array_crc32 != calc_crc) {
- efi_err("%scheck header, err(entries crc 0x%x!=0x%x(calc))\n",
- TAG, header->partition_entry_array_crc32, calc_crc);
- return 1;
- }
- efi_critical("%s user part id = %d\n", TAG, dev->blkdev->part_user);
- for (i = 0; (u32)i < header->num_partition_entries; i++) {
- /* break if the partition entry is empty */
- if (!entries[i].starting_lba) {
- break;
- }
- g_part_ptr[i].start_sect = (unsigned long)entries[i].starting_lba;
- g_part_ptr[i].nr_sects = (unsigned long)(entries[i].ending_lba - entries[i].starting_lba + 1);
- g_part_ptr[i].part_attr = (unsigned long)entries[i].attributes;
- g_part_ptr[i].part_id = dev->blkdev->part_user;
- info = malloc(sizeof(*info));
- if (!info) {
- continue;
- }
- g_part_ptr[i].info = info;
- if ((entries[i].partition_name[0] & 0xFF00) == 0) {
- w2s(g_part_ptr[i].info->name, PART_META_INFO_NAMELEN, entries[i].partition_name, GPT_ENTRY_NAME_LEN);
- } else {
- memcpy(g_part_ptr[i].info->name, entries[i].partition_name, 64);
- }
- if (NULL == efi_guid_unparse(&entries[i].unique_partition_guid, g_part_ptr[i].info->uuid)) {
- efi_err("efi parse uuid string fail!\n");
- return 1;
- }
- efi_critical("%s[%d]name=%s, start_sect=0x%lx, nr_sects=0x%lx, uuid=%s\n", TAG, i,
- g_part_ptr[i].info ? (char *)g_part_ptr[i].info->name : "unknown",
- g_part_ptr[i].start_sect, g_part_ptr[i].nr_sects,
- g_part_ptr[i].info ? (char *)g_part_ptr[i].info->uuid : "");
- }
- // record the total entry count
- g_gpt_entry_cnt = i;
- return 0;
- }
- int read_gpt(part_t *part)
- {
- int err;
- u64 lba;
- u8 *pgpt_header, *pgpt_entries;
- u8 *sgpt_header, *sgpt_entries;
- u32 part_id, gpt_entries_size;
- part_dev_t *dev = mt_part_get_device();
- if (!dev) {
- efi_err("%s%s, err(no dev)\n", TAG, __func__);
- return 1;
- }
- part_id = dev->blkdev->part_user;
- gpt_entries_size = sizeof(gpt_entry) * PART_MAX_COUNT;
- g_part_ptr = part;
- efi_critical("%sParsing Primary GPT now...\n", TAG);
- pgpt_header = (u8 *)malloc(dev->blkdev->blksz);
- if (!pgpt_header) {
- efi_err("%smalloc memory(pgpt header), err\n", TAG);
- goto next_try;
- }
- memset(pgpt_header, 0, dev->blkdev->blksz);
- pgpt_entries = (u8 *)malloc(gpt_entries_size);
- if (!pgpt_entries) {
- free(pgpt_header);
- efi_err("%smalloc memory(pgpt entries), err\n", TAG);
- goto next_try;
- }
- memset(pgpt_entries, 0, gpt_entries_size);
- err = parse_gpt_header(part_id, 1, pgpt_header, pgpt_entries);
- /* Free pgpt buffers after using it */
- free(pgpt_header);
- free(pgpt_entries);
- if (!err) {
- goto find;
- }
- next_try:
- efi_critical("%sParsing Secondary GPT now...\n", TAG);
- sgpt_header = (u8 *)malloc(dev->blkdev->blksz);
- if (!sgpt_header) {
- efi_err("%smalloc memory(sgpt header), err\n", TAG);
- return 1;
- }
- memset(sgpt_header, 0, dev->blkdev->blksz);
- sgpt_entries = (u8 *)malloc(gpt_entries_size);
- if (!sgpt_entries) {
- free(sgpt_header);
- efi_err("%smalloc memory(sgpt entries), err\n", TAG);
- return 1;
- }
- memset(sgpt_entries, 0, gpt_entries_size);
- lba = last_lba(part_id);
- if (!lba) {
- free(sgpt_header);
- free(sgpt_entries);
- efi_err("%sFailure to find last lba.\n", TAG);
- return 1;
- }
- err = parse_gpt_header(part_id, lba, sgpt_header, sgpt_entries);
- /* Free sgpt buffers after using it */
- free(sgpt_header);
- free(sgpt_entries);
- if (!err) {
- goto find;
- }
- efi_err("%sFailure to find valid GPT.\n", TAG);
- return err;
- find:
- efi_critical("%sSuccess to find valid GPT.\n", TAG);
- return 0;
- }
- static void pack_pmbr_data(void *ptr)
- {
- pmbr *mbr = (pmbr *)ptr;
- u64 nr_sects;
- u16 nr_sects_split[2];
- u16 *nr_sects_split_ptr;
- part_dev_t *dev = mt_part_get_device();
- if (!dev) {
- efi_err("%s%s, err(no dev)\n", TAG, __func__);
- return;
- }
- nr_sects = last_lba(dev->blkdev->part_user) + 1;
- mbr->partition_record[0].sys_ind = GPT_PROTECTIVE_MBR;
- mbr->partition_record[0].start_sector = 0x1;
- /* Suffer from mbr->partition_record[0].nr_sects address not 4-byte aligned(data abort will occur if directly write u32 data), split it into two 2-byte */
- nr_sects_split[0] = ((nr_sects < 0xFFFFFFFF) ? (nr_sects - 1) : 0xFFFFFFFF) & 0xFFFF;
- nr_sects_split[1] = (((nr_sects < 0xFFFFFFFF) ? (nr_sects - 1) : 0xFFFFFFFF) >> 16) & 0xFFFF;
- nr_sects_split_ptr = (u16 *)(&((mbr->partition_record[0].nr_sects)));
- *nr_sects_split_ptr = nr_sects_split[0];
- *(nr_sects_split_ptr +1) = nr_sects_split[1];
- mbr->signature = 0xAA55;
- }
- static void pack_pheader_data(void *data)
- {
- part_dev_t *dev = mt_part_get_device();
- if (!dev) {
- efi_err("%s%s, err(no dev)\n", TAG, __func__);
- return;
- }
- gpt_header *header = (gpt_header *)data;
- header->reserved = 0;
- header->alternate_lba = last_lba(dev->blkdev->part_user);
- header->last_usable_lba = get_gpt_header_last_usable_lba();
- header->partition_entry_array_crc32 = get_entries_crc32();
- header->header_crc32 = 0;
- header->header_crc32 = efi_crc32(data, sizeof(gpt_header));
- }
- static void pack_entries_data(void *data)
- {
- int i;
- int nr_parts = 0;
- part_dev_t *dev = mt_part_get_device();
- gpt_entry *entries = (gpt_entry *)data;
- if (!dev) {
- efi_err("%s%s, err(no dev)\n", TAG, __func__);
- return;
- }
- //calculate how many partitions
- for (i = 0; i < PART_MAX_COUNT; i++) {
- if (!entries[i].partition_name[0]) {
- nr_parts = i;
- break;
- }
- }
- efi_err("%snumber of partitions: %d.\n", TAG, nr_parts);
- /* Update gpt entries */
- for (i = nr_parts-1; i >= 0; i--) {
- /* it's last partition (do not have reserved partition ex: no flashinfo, otp), only need to update last partition */
- /* may not go to here unless customer remove flashinfo partition */
- if (i == nr_parts-1 && !entries[i].starting_lba && !entries[i].ending_lba) {
- entries[i].ending_lba = last_lba(dev->blkdev->part_user) - get_spgt_partition_lba_size() ;
- entries[i].starting_lba = entries[i-1].ending_lba + 1;
- break;
- }
- /* Process reserved partitions(flashinfo, otp) and last partition before reserved partition(ex: userdata or intsd) */
- /* Reserved partition size is stored in ending_lba, sgpt partition size can be retrived from get_spgt_partition_size()(stored in header->reserved)*/
- if (!entries[i].starting_lba) {
- /* it's a reserved partition and it's last partition, entries[i].ending_lba not empty(partition size is here) */
- if (i == nr_parts-1 && entries[i].ending_lba) {
- entries[i].starting_lba = last_lba(dev->blkdev->part_user) - get_spgt_partition_lba_size() - entries[i].ending_lba + 1;
- entries[i].ending_lba = last_lba(dev->blkdev->part_user) - get_spgt_partition_lba_size() ;
- }
- /* reserved parttiion but not last one */
- /* may not go to here uless there exists more than one reserved partitions (ex: otp + flashinfo)*/
- else if (entries[i].ending_lba) {
- entries[i].starting_lba = entries[i+1].starting_lba - entries[i].ending_lba;
- entries[i].ending_lba = entries[i+1].starting_lba - 1;
- }
- /* userdata or intsed */
- else {
- entries[i].starting_lba = entries[i-1].ending_lba + 1;
- entries[i].ending_lba = entries[i+1].starting_lba - 1;
- }
- }
- }
- set_entries_crc32(efi_crc32(data, PART_MAX_COUNT * sizeof(gpt_entry)));
- }
- static void pack_sheader_data(void *data)
- {
- gpt_header *header = (gpt_header *)data;
- header->header_crc32 = 0;
- header->my_lba = header->alternate_lba;
- header->alternate_lba = 1;
- header->partition_entry_lba = get_gpt_header_last_usable_lba() + 1;
- header->partition_entry_array_crc32 = get_entries_crc32();
- header->header_crc32 = efi_crc32(data, sizeof(gpt_header));
- }
- int write_primary_gpt(void *data, unsigned sz)
- {
- int err, part_entries_cnt_per_block;
- u64 pentries_write_size;
- gpt_header *header;
- gpt_entry *entries;
- pmbr *mbr;
- int with_pmbr; /* 0: data is without pmbr, 1: data is with pmbr*/
- part_dev_t *dev = mt_part_get_device();
- if (!dev) {
- efi_err("%s%s, err(no dev)\n", TAG, __func__);
- return -1;
- }
- /* fastboot PGPT image check */
- if (sz == (PART_MAX_COUNT*sizeof(gpt_entry)+dev->blkdev->blksz)) {
- with_pmbr = 0;
- mbr = NULL;
- header = (gpt_header *)data;
- entries = (gpt_entry *)(data + dev->blkdev->blksz);
- } else if (sz == (PART_MAX_COUNT*sizeof(gpt_entry)+dev->blkdev->blksz * 2)) {
- with_pmbr = 1;
- mbr = (pmbr *)data;
- header = (gpt_header *)(data + dev->blkdev->blksz);
- entries = (gpt_entry *)(data + dev->blkdev->blksz * 2);
- } else {
- err = -1;
- efi_err("[GPT_Update]PGPT size not correct, err(%d), expect: 0x%lx read: 0x%x\n", err, (PART_MAX_COUNT*sizeof(gpt_entry)+dev->blkdev->blksz), sz);
- return err;
- }
- if (header->signature != GPT_HEADER_SIGNATURE) {
- err = -1;
- efi_err("[GPT_Update] %scheck header, err(signature 0x%llx!=0x%llx)\n",
- TAG, header->signature, GPT_HEADER_SIGNATURE);
- return err;
- }
- if (!with_pmbr) {
- mbr = (pmbr *)malloc(dev->blkdev->blksz);
- if (!mbr) {
- err = -1;
- efi_err("%s malloc memory(pmbr header), err\n", TAG);
- return err;
- }
- memset(mbr, 0, dev->blkdev->blksz);
- }
- if (header->alternate_lba != last_lba(dev->blkdev->part_user)) {
- set_spgt_partition_lba_size(header->alternate_lba); //sgpt partition size is hrere
- } else {
- set_spgt_partition_lba_size(last_lba(dev->blkdev->part_user) - header->last_usable_lba);
- }
- pack_entries_data((void *)entries); //move to gpt entries
- pack_pheader_data((void *)header); //update pheader
- pack_pmbr_data((void *)mbr);
- /* Write pmbr */
- err = write_data(0, (u8 *)mbr, (u64)dev->blkdev->blksz, dev->blkdev->part_user);
- if (!with_pmbr)
- free(mbr); /* Free pmbr after use it */
- if (err) {
- efi_err("[GPT_Update]write pmbr, err(%d)\n", err);
- return err;
- }
- /* Write pheader */
- err = write_data(1, (u8 *)header, (u64)dev->blkdev->blksz, dev->blkdev->part_user);
- if (err) {
- efi_err("[GPT_Update]write pheader, err(%d)\n", err);
- return err;
- }
- /* Write gpt entries */
- part_entries_cnt_per_block = dev->blkdev->blksz / header->sizeof_partition_entry;
- pentries_write_size = (u64)((PART_MAX_COUNT + part_entries_cnt_per_block - 1) / part_entries_cnt_per_block) * dev->blkdev->blksz;
- err = write_data(2, (u8 *)entries, pentries_write_size, dev->blkdev->part_user);
- if (err) {
- efi_err("[GPT_Update]write pentries, err(%d)\n", err);
- return err;
- }
- return 0;
- }
- int write_secondary_gpt(void *data, unsigned sz)
- {
- int err, part_entries_cnt_per_block;
- u64 pentries_write_size;
- u64 sentries_start_lba;
- gpt_header *header;
- gpt_entry *entries;
- part_dev_t *dev = mt_part_get_device();
- if (!dev) {
- efi_err("%s%s, err(no dev)\n", TAG, __func__);
- return -1;
- }
- /* fastboot PGPT image check */
- if (sz == (PART_MAX_COUNT*sizeof(gpt_entry)+dev->blkdev->blksz)) {
- header = (gpt_header *)data;
- entries = (gpt_entry *)(data + dev->blkdev->blksz);
- } else if (sz == (PART_MAX_COUNT*sizeof(gpt_entry)+dev->blkdev->blksz * 2)) {
- header = (gpt_header *)(data + dev->blkdev->blksz);
- entries = (gpt_entry *)(data + dev->blkdev->blksz * 2);
- } else {
- err = -1;
- efi_err("[GPT_Update]SGPT size not correct, err(%d), expect: 0x%lx read: 0x%x\n", err, (PART_MAX_COUNT*sizeof(gpt_entry)+dev->blkdev->blksz), sz);
- return err;
- }
- if (header->signature != GPT_HEADER_SIGNATURE) {
- err = -1;
- efi_err("[GPT_Update] %s check header, err(signature 0x%llx!=0x%llx)\n",
- TAG, header->signature, GPT_HEADER_SIGNATURE);
- return err;
- }
- pack_sheader_data(header); //update sheader
- /* Write sheader */
- err = write_data(last_lba(dev->blkdev->part_user), (u8 *)header, (u64)dev->blkdev->blksz, dev->blkdev->part_user);
- if (err) {
- efi_err("[GPT_Update]write sheader, err(%d)\n", err);
- return err;
- }
- /* Write gpt entries */
- sentries_start_lba = get_gpt_header_last_usable_lba() + 1;
- part_entries_cnt_per_block = dev->blkdev->blksz / header->sizeof_partition_entry;
- pentries_write_size = (u64)((PART_MAX_COUNT + part_entries_cnt_per_block - 1) / part_entries_cnt_per_block) * dev->blkdev->blksz;
- err = write_data(sentries_start_lba, (u8 *)entries, pentries_write_size, dev->blkdev->part_user);
- if (err) {
- efi_err("[GPT_Update]write pentries, err(%d)\n", err);
- return err;
- }
- return 0;
- }
- unsigned int *target_commandline_force_gpt(char *cmd)
- {
- cmdline_append("gpt=1");
- return 0;
- }
|