cgpt: Support non-standard (smaller) entries table

The standard says that entries table must be at least 16384 bytes. On
some of our devices, the NOR section is only 8 KiB and used to store
both primary and secondary tables. On this device, we can only store 24
entries.

Therefore, this CL adds support for non-standard entry table. It adjusts
the MIN_NUMBER_OF_ENTRIES to 16, and replaces GPT_ENTRIES_SECTORS with
CalculateEntriesSectors.

BUG=chromium:441812
BRANCH=none
TEST=unittest

Change-Id: I6b85b35ce5612c7abb22142f8252bd0d45b676c5
Reviewed-on: https://chromium-review.googlesource.com/234996
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Commit-Queue: Nam Nguyen <namnguyen@chromium.org>
Tested-by: Nam Nguyen <namnguyen@chromium.org>
This commit is contained in:
Nam T. Nguyen
2014-12-12 09:38:35 -08:00
committed by chrome-internal-fetch
parent 32a999d2c0
commit 3200401242
8 changed files with 89 additions and 48 deletions

View File

@@ -176,7 +176,8 @@ static int GptLoad(struct drive *drive, uint32_t sector_bytes) {
drive->gpt.flags) == 0) { drive->gpt.flags) == 0) {
if (CGPT_OK != Load(drive, &drive->gpt.primary_entries, if (CGPT_OK != Load(drive, &drive->gpt.primary_entries,
primary_header->entries_lba, primary_header->entries_lba,
drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) { drive->gpt.sector_bytes,
CalculateEntriesSectors(primary_header))) {
Error("Cannot read primary partition entry array\n"); Error("Cannot read primary partition entry array\n");
return -1; return -1;
} }
@@ -189,7 +190,8 @@ static int GptLoad(struct drive *drive, uint32_t sector_bytes) {
drive->gpt.flags) == 0) { drive->gpt.flags) == 0) {
if (CGPT_OK != Load(drive, &drive->gpt.secondary_entries, if (CGPT_OK != Load(drive, &drive->gpt.secondary_entries,
secondary_header->entries_lba, secondary_header->entries_lba,
drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) { drive->gpt.sector_bytes,
CalculateEntriesSectors(secondary_header))) {
Error("Cannot read secondary partition entry array\n"); Error("Cannot read secondary partition entry array\n");
return -1; return -1;
} }
@@ -222,7 +224,8 @@ static int GptSave(struct drive *drive) {
if (drive->gpt.modified & GPT_MODIFIED_ENTRIES1) { if (drive->gpt.modified & GPT_MODIFIED_ENTRIES1) {
if (CGPT_OK != Save(drive, drive->gpt.primary_entries, if (CGPT_OK != Save(drive, drive->gpt.primary_entries,
primary_header->entries_lba, primary_header->entries_lba,
drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) { drive->gpt.sector_bytes,
CalculateEntriesSectors(primary_header))) {
errors++; errors++;
Error("Cannot write primary entries: %s\n", strerror(errno)); Error("Cannot write primary entries: %s\n", strerror(errno));
} }
@@ -231,7 +234,8 @@ static int GptSave(struct drive *drive) {
if (drive->gpt.modified & GPT_MODIFIED_ENTRIES2) { if (drive->gpt.modified & GPT_MODIFIED_ENTRIES2) {
if (CGPT_OK != Save(drive, drive->gpt.secondary_entries, if (CGPT_OK != Save(drive, drive->gpt.secondary_entries,
secondary_header->entries_lba, secondary_header->entries_lba,
drive->gpt.sector_bytes, GPT_ENTRIES_SECTORS)) { drive->gpt.sector_bytes,
CalculateEntriesSectors(secondary_header))) {
errors++; errors++;
Error("Cannot write secondary entries: %s\n", strerror(errno)); Error("Cannot write secondary entries: %s\n", strerror(errno));
} }
@@ -808,12 +812,16 @@ void UpdateCrc(GptData *gpt) {
if (gpt->modified & GPT_MODIFIED_ENTRIES1 && if (gpt->modified & GPT_MODIFIED_ENTRIES1 &&
memcmp(primary_header, GPT_HEADER_SIGNATURE2, memcmp(primary_header, GPT_HEADER_SIGNATURE2,
GPT_HEADER_SIGNATURE_SIZE)) { GPT_HEADER_SIGNATURE_SIZE)) {
size_t entries_size = primary_header->size_of_entry *
primary_header->number_of_entries;
primary_header->entries_crc32 = primary_header->entries_crc32 =
Crc32(gpt->primary_entries, TOTAL_ENTRIES_SIZE); Crc32(gpt->primary_entries, entries_size);
} }
if (gpt->modified & GPT_MODIFIED_ENTRIES2) { if (gpt->modified & GPT_MODIFIED_ENTRIES2) {
size_t entries_size = secondary_header->size_of_entry *
secondary_header->number_of_entries;
secondary_header->entries_crc32 = secondary_header->entries_crc32 =
Crc32(gpt->secondary_entries, TOTAL_ENTRIES_SIZE); Crc32(gpt->secondary_entries, entries_size);
} }
if (gpt->modified & GPT_MODIFIED_HEADER1) { if (gpt->modified & GPT_MODIFIED_HEADER1) {
primary_header->header_crc32 = 0; primary_header->header_crc32 = 0;
@@ -867,17 +875,26 @@ uint8_t RepairEntries(GptData *gpt, const uint32_t valid_entries) {
if (!memcmp(h->signature, GPT_HEADER_SIGNATURE2, GPT_HEADER_SIGNATURE_SIZE)) if (!memcmp(h->signature, GPT_HEADER_SIGNATURE2, GPT_HEADER_SIGNATURE_SIZE))
return 0; return 0;
if (gpt->valid_headers & MASK_PRIMARY) {
h = (GptHeader*)gpt->primary_header;
} else if (gpt->valid_headers & MASK_SECONDARY) {
h = (GptHeader*)gpt->secondary_header;
} else {
/* We cannot trust any header, don't update entries. */
return 0;
}
size_t entries_size = h->number_of_entries * h->size_of_entry;
if (valid_entries == MASK_BOTH) { if (valid_entries == MASK_BOTH) {
if (memcmp(gpt->primary_entries, gpt->secondary_entries, if (memcmp(gpt->primary_entries, gpt->secondary_entries, entries_size)) {
TOTAL_ENTRIES_SIZE)) { memcpy(gpt->secondary_entries, gpt->primary_entries, entries_size);
memcpy(gpt->secondary_entries, gpt->primary_entries, TOTAL_ENTRIES_SIZE);
return GPT_MODIFIED_ENTRIES2; return GPT_MODIFIED_ENTRIES2;
} }
} else if (valid_entries == MASK_PRIMARY) { } else if (valid_entries == MASK_PRIMARY) {
memcpy(gpt->secondary_entries, gpt->primary_entries, TOTAL_ENTRIES_SIZE); memcpy(gpt->secondary_entries, gpt->primary_entries, entries_size);
return GPT_MODIFIED_ENTRIES2; return GPT_MODIFIED_ENTRIES2;
} else if (valid_entries == MASK_SECONDARY) { } else if (valid_entries == MASK_SECONDARY) {
memcpy(gpt->primary_entries, gpt->secondary_entries, TOTAL_ENTRIES_SIZE); memcpy(gpt->primary_entries, gpt->secondary_entries, entries_size);
return GPT_MODIFIED_ENTRIES1; return GPT_MODIFIED_ENTRIES1;
} }
@@ -922,7 +939,7 @@ uint8_t RepairHeader(GptData *gpt, const uint32_t valid_headers) {
secondary_header->my_lba = gpt->gpt_drive_sectors - 1; /* the last sector */ secondary_header->my_lba = gpt->gpt_drive_sectors - 1; /* the last sector */
secondary_header->alternate_lba = primary_header->my_lba; secondary_header->alternate_lba = primary_header->my_lba;
secondary_header->entries_lba = secondary_header->my_lba - secondary_header->entries_lba = secondary_header->my_lba -
GPT_ENTRIES_SECTORS; CalculateEntriesSectors(primary_header);
return GPT_MODIFIED_HEADER2; return GPT_MODIFIED_HEADER2;
} else if (valid_headers == MASK_SECONDARY) { } else if (valid_headers == MASK_SECONDARY) {
memcpy(primary_header, secondary_header, sizeof(GptHeader)); memcpy(primary_header, secondary_header, sizeof(GptHeader));

View File

@@ -29,10 +29,6 @@ static int GptCreate(struct drive *drive, CgptCreateParams *params) {
drive->gpt.sector_bytes * GPT_HEADER_SECTORS); drive->gpt.sector_bytes * GPT_HEADER_SECTORS);
AllocAndClear(&drive->gpt.secondary_header, AllocAndClear(&drive->gpt.secondary_header,
drive->gpt.sector_bytes * GPT_HEADER_SECTORS); drive->gpt.sector_bytes * GPT_HEADER_SECTORS);
AllocAndClear(&drive->gpt.primary_entries,
drive->gpt.sector_bytes * GPT_ENTRIES_SECTORS);
AllocAndClear(&drive->gpt.secondary_entries,
drive->gpt.sector_bytes * GPT_ENTRIES_SECTORS);
drive->gpt.modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 | drive->gpt.modified |= (GPT_MODIFIED_HEADER1 | GPT_MODIFIED_ENTRIES1 |
GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2); GPT_MODIFIED_HEADER2 | GPT_MODIFIED_ENTRIES2);
@@ -45,21 +41,12 @@ static int GptCreate(struct drive *drive, CgptCreateParams *params) {
h->size = sizeof(GptHeader); h->size = sizeof(GptHeader);
h->my_lba = GPT_PMBR_SECTORS; /* The second sector on drive. */ h->my_lba = GPT_PMBR_SECTORS; /* The second sector on drive. */
h->alternate_lba = drive->gpt.gpt_drive_sectors - GPT_HEADER_SECTORS; h->alternate_lba = drive->gpt.gpt_drive_sectors - GPT_HEADER_SECTORS;
h->entries_lba = h->my_lba + GPT_HEADER_SECTORS;
if (!(drive->gpt.flags & GPT_FLAG_EXTERNAL)) {
h->entries_lba += params->padding;
h->first_usable_lba = h->entries_lba + GPT_ENTRIES_SECTORS;
h->last_usable_lba = (drive->gpt.streaming_drive_sectors -
GPT_HEADER_SECTORS -
GPT_ENTRIES_SECTORS - 1);
} else {
h->first_usable_lba = params->padding;
h->last_usable_lba = (drive->gpt.streaming_drive_sectors - 1);
}
if (CGPT_OK != GenerateGuid(&h->disk_uuid)) { if (CGPT_OK != GenerateGuid(&h->disk_uuid)) {
Error("Unable to generate new GUID.\n"); Error("Unable to generate new GUID.\n");
return -1; return -1;
} }
/* Calculate number of entries */
h->size_of_entry = sizeof(GptEntry); h->size_of_entry = sizeof(GptEntry);
h->number_of_entries = TOTAL_ENTRIES_SIZE / h->size_of_entry; h->number_of_entries = TOTAL_ENTRIES_SIZE / h->size_of_entry;
if (drive->gpt.flags & GPT_FLAG_EXTERNAL) { if (drive->gpt.flags & GPT_FLAG_EXTERNAL) {
@@ -69,7 +56,7 @@ static int GptCreate(struct drive *drive, CgptCreateParams *params) {
Error("Not enough space for a GPT header.\n"); Error("Not enough space for a GPT header.\n");
return -1; return -1;
} }
half_size_sectors -= GPT_HEADER_SECTORS; half_size_sectors -= (GPT_HEADER_SECTORS + GPT_PMBR_SECTORS);
size_t half_size = half_size_sectors * drive->gpt.sector_bytes; size_t half_size = half_size_sectors * drive->gpt.sector_bytes;
if (half_size < (MIN_NUMBER_OF_ENTRIES * h->size_of_entry)) { if (half_size < (MIN_NUMBER_OF_ENTRIES * h->size_of_entry)) {
Error("Not enough space for minimum number of entries.\n"); Error("Not enough space for minimum number of entries.\n");
@@ -80,6 +67,22 @@ static int GptCreate(struct drive *drive, CgptCreateParams *params) {
} }
} }
/* Then use number of entries to calculate entries_lba. */
h->entries_lba = h->my_lba + GPT_HEADER_SECTORS;
if (!(drive->gpt.flags & GPT_FLAG_EXTERNAL)) {
h->entries_lba += params->padding;
h->first_usable_lba = h->entries_lba + CalculateEntriesSectors(h);
h->last_usable_lba = (drive->gpt.streaming_drive_sectors - GPT_HEADER_SECTORS -
CalculateEntriesSectors(h) - 1);
} else {
h->first_usable_lba = params->padding;
h->last_usable_lba = (drive->gpt.streaming_drive_sectors - 1);
}
size_t entries_size = h->number_of_entries * h->size_of_entry;
AllocAndClear(&drive->gpt.primary_entries, entries_size);
AllocAndClear(&drive->gpt.secondary_entries, entries_size);
// Copy to secondary // Copy to secondary
RepairHeader(&drive->gpt, MASK_PRIMARY); RepairHeader(&drive->gpt, MASK_PRIMARY);

View File

@@ -271,7 +271,7 @@ static int GptShow(struct drive *drive, CgptShowParams *params) {
GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header; GptHeader* primary_header = (GptHeader*)drive->gpt.primary_header;
printf(GPT_FMT, (int)primary_header->entries_lba, printf(GPT_FMT, (int)primary_header->entries_lba,
(int)GPT_ENTRIES_SECTORS, (int)CalculateEntriesSectors(primary_header),
drive->gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID", drive->gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID",
"Pri GPT table"); "Pri GPT table");
@@ -282,7 +282,7 @@ static int GptShow(struct drive *drive, CgptShowParams *params) {
/****************************** Secondary *************************/ /****************************** Secondary *************************/
GptHeader* secondary_header = (GptHeader*)drive->gpt.secondary_header; GptHeader* secondary_header = (GptHeader*)drive->gpt.secondary_header;
printf(GPT_FMT, (int)secondary_header->entries_lba, printf(GPT_FMT, (int)secondary_header->entries_lba,
(int)GPT_ENTRIES_SECTORS, (int)CalculateEntriesSectors(secondary_header),
drive->gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID", drive->gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID",
"Sec GPT table"); "Sec GPT table");
/* We show secondary table details if any of following is true. /* We show secondary table details if any of following is true.
@@ -294,7 +294,8 @@ static int GptShow(struct drive *drive, CgptShowParams *params) {
((drive->gpt.valid_entries & MASK_SECONDARY) && ((drive->gpt.valid_entries & MASK_SECONDARY) &&
(!(drive->gpt.valid_entries & MASK_PRIMARY) || (!(drive->gpt.valid_entries & MASK_PRIMARY) ||
memcmp(drive->gpt.primary_entries, drive->gpt.secondary_entries, memcmp(drive->gpt.primary_entries, drive->gpt.secondary_entries,
TOTAL_ENTRIES_SIZE)))) { secondary_header->number_of_entries *
secondary_header->size_of_entry)))) {
EntriesDetails(drive, SECONDARY, params->numeric); EntriesDetails(drive, SECONDARY, params->numeric);
} }

View File

@@ -12,11 +12,18 @@
#include "gpt_misc.h" #include "gpt_misc.h"
#include "utility.h" #include "utility.h"
const static int SECTOR_SIZE = 512;
size_t CalculateEntriesSectors(GptHeader* h) {
size_t bytes = h->number_of_entries * h->size_of_entry;
size_t ret = (bytes + SECTOR_SIZE - 1) / SECTOR_SIZE;
return ret;
}
int CheckParameters(GptData *gpt) int CheckParameters(GptData *gpt)
{ {
/* Currently, we only support 512-byte sectors. */ /* Currently, we only support 512-byte sectors. */
if (gpt->sector_bytes != 512) if (gpt->sector_bytes != SECTOR_SIZE)
return GPT_ERROR_INVALID_SECTOR_SIZE; return GPT_ERROR_INVALID_SECTOR_SIZE;
/* /*
@@ -33,9 +40,11 @@ int CheckParameters(GptData *gpt)
/* /*
* Sector count of a drive should be reasonable. If the given value is * Sector count of a drive should be reasonable. If the given value is
* too small to contain basic GPT structure (PMBR + Headers + Entries), * too small to contain basic GPT structure (PMBR + Headers + Entries),
* the value is wrong. * the value is wrong. Entries size is hard coded to TOTAL_ENTRIES_SIZE (see
* cgpt_create.c). This check is only applicable when GPT is stored on device.
*/ */
if (gpt->gpt_drive_sectors < (1 + 2 * (1 + GPT_ENTRIES_SECTORS))) if (!(gpt->flags & GPT_FLAG_EXTERNAL) &&
gpt->gpt_drive_sectors < (1 + 2 * (1 + TOTAL_ENTRIES_SIZE / SECTOR_SIZE)))
return GPT_ERROR_INVALID_SECTOR_NUMBER; return GPT_ERROR_INVALID_SECTOR_NUMBER;
return GPT_SUCCESS; return GPT_SUCCESS;
@@ -105,7 +114,7 @@ int CheckHeader(GptHeader *h, int is_secondary,
if (is_secondary) { if (is_secondary) {
if (h->my_lba != gpt_drive_sectors - GPT_HEADER_SECTORS) if (h->my_lba != gpt_drive_sectors - GPT_HEADER_SECTORS)
return 1; return 1;
if (h->entries_lba != h->my_lba - GPT_ENTRIES_SECTORS) if (h->entries_lba != h->my_lba - CalculateEntriesSectors(h))
return 1; return 1;
} else { } else {
if (h->my_lba != GPT_PMBR_SECTORS) if (h->my_lba != GPT_PMBR_SECTORS)
@@ -131,10 +140,10 @@ int CheckHeader(GptHeader *h, int is_secondary,
* array. * array.
*/ */
/* TODO(namnguyen): Also check for padding between header & entries. */ /* TODO(namnguyen): Also check for padding between header & entries. */
if (h->first_usable_lba < 2 + GPT_ENTRIES_SECTORS) if (h->first_usable_lba < 2 + CalculateEntriesSectors(h))
return 1; return 1;
if (h->last_usable_lba >= if (h->last_usable_lba >=
streaming_drive_sectors - 1 - GPT_ENTRIES_SECTORS) streaming_drive_sectors - 1 - CalculateEntriesSectors(h))
return 1; return 1;
/* Success */ /* Success */
@@ -321,7 +330,7 @@ void GptRepair(GptData *gpt)
Memcpy(header2, header1, sizeof(GptHeader)); Memcpy(header2, header1, sizeof(GptHeader));
header2->my_lba = gpt->gpt_drive_sectors - GPT_HEADER_SECTORS; header2->my_lba = gpt->gpt_drive_sectors - GPT_HEADER_SECTORS;
header2->alternate_lba = GPT_PMBR_SECTORS; /* Second sector. */ header2->alternate_lba = GPT_PMBR_SECTORS; /* Second sector. */
header2->entries_lba = header2->my_lba - GPT_ENTRIES_SECTORS; header2->entries_lba = header2->my_lba - CalculateEntriesSectors(header1);
header2->header_crc32 = HeaderCrc(header2); header2->header_crc32 = HeaderCrc(header2);
gpt->modified |= GPT_MODIFIED_HEADER2; gpt->modified |= GPT_MODIFIED_HEADER2;
} }

View File

@@ -51,17 +51,12 @@
#define MIN_SIZE_OF_ENTRY 128 #define MIN_SIZE_OF_ENTRY 128
#define MAX_SIZE_OF_ENTRY 512 #define MAX_SIZE_OF_ENTRY 512
#define SIZE_OF_ENTRY_MULTIPLE 8 #define SIZE_OF_ENTRY_MULTIPLE 8
#define MIN_NUMBER_OF_ENTRIES 32 #define MIN_NUMBER_OF_ENTRIES 16
#define MAX_NUMBER_OF_ENTRIES 512 #define MAX_NUMBER_OF_ENTRIES 512
/* Defines GPT sizes */ /* Defines GPT sizes */
#define GPT_PMBR_SECTORS 1 /* size (in sectors) of PMBR */ #define GPT_PMBR_SECTORS 1 /* size (in sectors) of PMBR */
#define GPT_HEADER_SECTORS 1 #define GPT_HEADER_SECTORS 1
/*
* Entries sectors assumes sector size if 512 bytes; then (TOTAL_ENTRIES_SIZE /
* 512) = 32
*/
#define GPT_ENTRIES_SECTORS 32
/* /*
* Alias name of index in internal array for primary and secondary header and * Alias name of index in internal array for primary and secondary header and
@@ -163,4 +158,9 @@ void GetCurrentKernelUniqueGuid(GptData *gpt, void *dest);
*/ */
const char *GptErrorText(int error_code); const char *GptErrorText(int error_code);
/**
* Return number of 512-byte sectors required to store the entries table.
*/
size_t CalculateEntriesSectors(GptHeader* h);
#endif /* VBOOT_REFERENCE_CGPTLIB_INTERNAL_H_ */ #endif /* VBOOT_REFERENCE_CGPTLIB_INTERNAL_H_ */

View File

@@ -247,7 +247,7 @@ static int ParameterTests(void)
{512, 0, GPT_ERROR_INVALID_SECTOR_NUMBER}, {512, 0, GPT_ERROR_INVALID_SECTOR_NUMBER},
{512, 66, GPT_ERROR_INVALID_SECTOR_NUMBER}, {512, 66, GPT_ERROR_INVALID_SECTOR_NUMBER},
{512, GPT_PMBR_SECTORS + GPT_HEADER_SECTORS * 2 + {512, GPT_PMBR_SECTORS + GPT_HEADER_SECTORS * 2 +
GPT_ENTRIES_SECTORS * 2, GPT_SUCCESS}, TOTAL_ENTRIES_SIZE / DEFAULT_SECTOR_SIZE * 2, GPT_SUCCESS},
{4096, DEFAULT_DRIVE_SECTORS, GPT_ERROR_INVALID_SECTOR_SIZE}, {4096, DEFAULT_DRIVE_SECTORS, GPT_ERROR_INVALID_SECTOR_SIZE},
}; };
int i; int i;
@@ -537,6 +537,8 @@ static int NumberOfPartitionEntriesTest(void)
BuildTestGptData(gpt); BuildTestGptData(gpt);
h1->number_of_entries--; h1->number_of_entries--;
h2->number_of_entries /= 2; h2->number_of_entries /= 2;
/* Because we halved h2 entries, its entries_lba is going to change. */
h2->entries_lba = h2->my_lba - CalculateEntriesSectors(h2);
RefreshCrc32(gpt); RefreshCrc32(gpt);
EXPECT(1 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); EXPECT(1 == CheckHeader(h1, 0, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0));
EXPECT(1 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0)); EXPECT(1 == CheckHeader(h2, 1, gpt->streaming_drive_sectors, gpt->gpt_drive_sectors, 0));
@@ -1460,6 +1462,9 @@ static int CheckHeaderOffDevice()
BuildTestGptData(gpt); BuildTestGptData(gpt);
secondary_header->number_of_entries = 100; secondary_header->number_of_entries = 100;
/* Because we change number of entries, we need to also update entrie_lba. */
secondary_header->entries_lba = secondary_header->my_lba -
CalculateEntriesSectors(secondary_header);
RefreshCrc32(gpt); RefreshCrc32(gpt);
EXPECT(1 == CheckHeader(secondary_header, 1, gpt->streaming_drive_sectors, EXPECT(1 == CheckHeader(secondary_header, 1, gpt->streaming_drive_sectors,
gpt->gpt_drive_sectors, 0)); gpt->gpt_drive_sectors, 0));

View File

@@ -291,12 +291,17 @@ $CGPT find $MTD -t kernel ${DEV} >/dev/null
# Enable write access again to test boundary in off device storage # Enable write access again to test boundary in off device storage
chmod 600 ${DEV} chmod 600 ${DEV}
# Create a small 8K file to simulate Flash NOR section
dd if=/dev/zero of=${DEV} bs=8K count=1
# Drive size is not multiple of 512 # Drive size is not multiple of 512
assert_fail $CGPT create -D 511 ${DEV} assert_fail $CGPT create -D 511 ${DEV}
assert_fail $CGPT create -D 513 ${DEV} assert_fail $CGPT create -D 513 ${DEV}
MTD="-D 1024" MTD="-D 1024"
# Create a GPT table for a device of 1024 bytes (2 sectors) # Create a GPT table for a device of 1024 bytes (2 sectors)
$CGPT create $MTD ${DEV} $CGPT create $MTD ${DEV}
# Make sure number of entries is reasonable for 8KiB GPT
X=$($CGPT show -D 1024 -d ${DEV} | grep -c "Number of entries: 24")
[ "$X" = "2" ] || error
# This fails because header verification is off due to different drive size # This fails because header verification is off due to different drive size
assert_fail $CGPT show ${DEV} assert_fail $CGPT show ${DEV}
# But this passes because we pass in correct drive size # But this passes because we pass in correct drive size
@@ -306,6 +311,7 @@ assert_fail $CGPT add $MTD -b 2 -s 1 -t data ${DEV}
# This fails because partition size is over the size of the device # This fails because partition size is over the size of the device
assert_fail $CGPT add $MTD -b 0 -s 3 -t data ${DEV} assert_fail $CGPT add $MTD -b 0 -s 3 -t data ${DEV}
echo "Done." echo "Done."
happy "All tests passed." happy "All tests passed."

View File

@@ -87,14 +87,14 @@ static void SetupGptHeader(GptHeader *h, int is_secondary)
/* Set LBA pointers for primary or secondary header */ /* Set LBA pointers for primary or secondary header */
if (is_secondary) { if (is_secondary) {
h->my_lba = MOCK_SECTOR_COUNT - GPT_HEADER_SECTORS; h->my_lba = MOCK_SECTOR_COUNT - GPT_HEADER_SECTORS;
h->entries_lba = h->my_lba - GPT_ENTRIES_SECTORS; h->entries_lba = h->my_lba - CalculateEntriesSectors(h);
} else { } else {
h->my_lba = GPT_PMBR_SECTORS; h->my_lba = GPT_PMBR_SECTORS;
h->entries_lba = h->my_lba + 1; h->entries_lba = h->my_lba + 1;
} }
h->first_usable_lba = 2 + GPT_ENTRIES_SECTORS; h->first_usable_lba = 2 + CalculateEntriesSectors(h);
h->last_usable_lba = MOCK_SECTOR_COUNT - 2 - GPT_ENTRIES_SECTORS; h->last_usable_lba = MOCK_SECTOR_COUNT - 2 - CalculateEntriesSectors(h);
h->header_crc32 = HeaderCrc(h); h->header_crc32 = HeaderCrc(h);
} }