mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 18:25:10 +00:00
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:
committed by
chrome-internal-fetch
parent
32a999d2c0
commit
3200401242
@@ -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));
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_ */
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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."
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user