summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Chaulk <achaulk@chromium.org>2013-04-02 14:35:39 -0700
committerChromeBot <chrome-bot@google.com>2013-06-24 19:57:27 -0700
commit1c568bccc442afd91ea7ee5367668ba9ebc06a40 (patch)
treefc61614d01be73283cd4370a75c7ea393ad82a37
parent92f22e7c2a1ca08034ac3ad21b2af60347c1c4fb (diff)
downloadvboot-stabilize-daisy-4319.96.B.tar.gz
MTD search commands: show & findstabilize-daisy-4319.96.Brelease-R29-4319.B
BUG=chromium:221745 TEST=MTD version of run_cgpt_tests.sh passes BRANCH=none Change-Id: I8a5c1afab238eb10f38d865405ea2828715685d8 Original-Change-Id: I3d72fecbb3ef95252aa35d56885288340537b1c5 Reviewed-on: https://gerrit.chromium.org/gerrit/47175 Reviewed-by: Randall Spangler <rspangler@chromium.org> Commit-Queue: Albert Chaulk <achaulk@chromium.org> Tested-by: Albert Chaulk <achaulk@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/49794 Reviewed-by: Albert Chaulk <achaulk@chromium.org>
-rw-r--r--cgpt/cgpt_find.c113
-rw-r--r--cgpt/cgpt_show.c231
2 files changed, 284 insertions, 60 deletions
diff --git a/cgpt/cgpt_find.c b/cgpt/cgpt_find.c
index a8d31863..df6c4d39 100644
--- a/cgpt/cgpt_find.c
+++ b/cgpt/cgpt_find.c
@@ -83,27 +83,37 @@ static void showmatch(CgptFindParams *params, char *filename,
EntryDetails(entry, partnum - 1, params->numeric);
}
+// This needs to handle /dev/mmcblk0 -> /dev/mmcblk0p3, /dev/sda -> /dev/sda3
+static void mtd_showmatch(CgptFindParams *params, char *filename,
+ int partnum, MtdDiskPartition *entry) {
+ char * format = "%s%d\n";
+ if (strncmp("/dev/mmcblk", filename, 11) == 0)
+ format = "%sp%d\n";
+ if (params->numeric)
+ printf("%d\n", partnum);
+ else
+ printf(format, filename, partnum);
+ if (params->verbose > 0)
+ MtdEntryDetails(entry, partnum - 1, params->numeric);
+}
+
// This returns true if a GPT partition matches the search criteria. If a match
// isn't found (or if the file doesn't contain a GPT), it returns false. The
// filename and partition number that matched is left in a global, since we
// could have multiple hits.
-static int do_search(CgptFindParams *params, char *fileName) {
- int retval = 0;
+static int gpt_search(CgptFindParams *params, struct drive *drive,
+ char *filename) {
int i;
- struct drive drive;
GptEntry *entry;
+ int retval = 0;
char partlabel[GPT_PARTNAME_LEN];
- if (CGPT_OK != DriveOpen(fileName, &drive, O_RDONLY))
- return 0;
-
- if (GPT_SUCCESS != GptSanityCheck(&drive.gpt)) {
- (void) DriveClose(&drive, 0);
+ if (GPT_SUCCESS != GptSanityCheck(&drive->gpt)) {
return 0;
}
- for (i = 0; i < GetNumberOfEntries(&drive); ++i) {
- entry = GetEntry(&drive.gpt, ANY_VALID, i);
+ for (i = 0; i < GetNumberOfEntries(drive); ++i) {
+ entry = GetEntry(&drive->gpt, ANY_VALID, i);
if (GuidIsZero(&entry->type))
continue;
@@ -122,15 +132,94 @@ static int do_search(CgptFindParams *params, char *fileName) {
if (!strncmp(params->label, partlabel, sizeof(partlabel)))
found = 1;
}
- if (found && match_content(params, &drive, entry)) {
+ if (found && match_content(params, drive, entry)) {
params->hits++;
retval++;
- showmatch(params, fileName, i+1, entry);
+ showmatch(params, filename, i+1, entry);
if (!params->match_partnum)
params->match_partnum = i+1;
}
}
+ return retval;
+}
+
+static int mtd_match_type_to_guid(const MtdDiskPartition *e, const Guid *guid) {
+ return LookupMtdTypeForGuid(guid) == MtdGetEntryType(e);
+}
+
+static int mtd_match_content(CgptFindParams *params, struct drive *drive,
+ MtdDiskPartition *entry) {
+ uint64_t part_size;
+
+ if (!params->matchlen)
+ return 1;
+
+ // Ensure that the region we want to match against is inside the partition.
+ part_size = LBA_SIZE * (entry->ending_lba - entry->starting_lba + 1);
+ if (params->matchoffset + params->matchlen > part_size) {
+ return 0;
+ }
+
+ // Read the partition data.
+ if (!FillBuffer(params,
+ drive->fd,
+ (LBA_SIZE * entry->starting_lba) + params->matchoffset,
+ params->matchlen)) {
+ Error("unable to read partition data\n");
+ return 0;
+ }
+
+ // Compare it
+ if (0 == memcmp(params->matchbuf, params->comparebuf, params->matchlen)) {
+ return 1;
+ }
+
+ // Nope.
+ return 0;
+}
+
+static int mtd_search(CgptFindParams *params, struct drive *drive,
+ char *filename) {
+ int i;
+ int retval = 0;
+ for (i = 0; i < GetNumberOfEntries(drive); ++i) {
+ MtdDiskPartition *e = MtdGetEntry(&drive->mtd, ANY_VALID, i);
+
+ if (IsUnused(drive, ANY_VALID, i))
+ continue;
+
+ int found = 0;
+
+ // Only searches by type are possible right now
+ if (params->set_type && mtd_match_type_to_guid(e, &params->type_guid)) {
+ found = 1;
+ }
+
+ if (found && mtd_match_content(params, drive, e)) {
+ params->hits++;
+ retval++;
+ mtd_showmatch(params, filename, i+1, e);
+ if (!params->match_partnum)
+ params->match_partnum = i+1;
+ }
+ }
+ return retval;
+}
+
+static int do_search(CgptFindParams *params, char *fileName) {
+ int retval;
+ struct drive drive;
+
+ if (CGPT_OK != DriveOpen(fileName, &drive, O_RDONLY))
+ return 0;
+
+ if (drive.is_mtd) {
+ retval = mtd_search(params, &drive, fileName);
+ } else {
+ retval = gpt_search(params, &drive, fileName);
+ }
+
(void) DriveClose(&drive, 0);
return retval;
diff --git a/cgpt/cgpt_show.c b/cgpt/cgpt_show.c
index e80567c3..c3c222eb 100644
--- a/cgpt/cgpt_show.c
+++ b/cgpt/cgpt_show.c
@@ -49,22 +49,37 @@ static void RawDump(const uint8_t *memory, const int size,
#define PARTITION_FMT "%12d%12d%8d %s\n"
#define PARTITION_MORE "%12s%12s%8s %s%s\n", "", "", ""
-static void HeaderDetails(GptHeader *header, GptEntry *entries,
- const char *indent, int raw) {
- int i;
-
+void PrintSignature(const char *indent, const char *sig, size_t n, int raw) {
+ size_t i;
printf("%sSig: ", indent);
if (!raw) {
printf("[");
- for (i = 0; i < sizeof(header->signature); ++i)
- printf("%c", header->signature[i]);
+ for (i = 0; i < n; ++i)
+ printf("%c", sig[i]);
printf("]");
} else {
- char buf[BUFFER_SIZE(sizeof(header->signature))];
- RawDump((uint8_t *)header->signature, sizeof(header->signature), buf, 1);
+ char *buf = malloc(BUFFER_SIZE(n));
+ RawDump((uint8_t *)sig, n, buf, 1);
printf("%s", buf);
+ free(buf);
}
printf("\n");
+}
+
+void MtdHeaderDetails(MtdDiskLayout *header, const char *indent, int raw) {
+ PrintSignature(indent, (char*)header->signature, sizeof(header->signature),
+ raw);
+
+ printf("%sSize: %d\n", indent, header->size);
+ printf("%sCRC: 0x%08x %s\n", indent, header->crc32,
+ (MtdHeaderCrc(header) != header->crc32) ? "(INVALID)" : "");
+ printf("%sFirst LBA: %u\n", indent, header->first_lba);
+ printf("%sLast LBA: %u\n", indent, header->last_lba);
+}
+
+static void HeaderDetails(GptHeader *header, GptEntry *entries,
+ const char *indent, int raw) {
+ PrintSignature(indent, header->signature, sizeof(header->signature), raw);
printf("%sRev: 0x%08x\n", indent, header->revision);
printf("%sSize: %d\n", indent, header->size);
@@ -92,6 +107,26 @@ static void HeaderDetails(GptHeader *header, GptEntry *entries,
);
}
+void MtdEntryDetails(MtdDiskPartition *entry, uint32_t index, int raw) {
+ const Guid *guid = LookupGuidForMtdType(MtdGetEntryType(entry));
+ char buf[256]; // scratch buffer for formatting output
+ if (guid) {
+ ResolveType(guid, buf);
+ } else {
+ snprintf(buf, sizeof(buf), "MTD partition type %d", MtdGetEntryType(entry));
+ }
+
+ if (!raw) {
+ printf(PARTITION_FMT, (int)entry->starting_lba,
+ (int)(entry->ending_lba - entry->starting_lba + 1),
+ index+1, buf);
+ } else {
+ printf(PARTITION_FMT, (int)entry->starting_lba,
+ (int)(entry->ending_lba - entry->starting_lba + 1),
+ index+1, buf);
+ }
+}
+
void EntryDetails(GptEntry *entry, uint32_t index, int raw) {
char contents[256]; // scratch buffer for formatting output
uint8_t label[GPT_PARTNAME_LEN];
@@ -149,6 +184,17 @@ void EntryDetails(GptEntry *entry, uint32_t index, int raw) {
}
}
+void MtdEntriesDetails(struct drive *drive, int secondary, int raw) {
+ uint32_t i;
+
+ for (i = 0; i < GetNumberOfEntries(drive); ++i) {
+ MtdDiskPartition *entry;
+ entry = MtdGetEntry(&drive->mtd, secondary, i);
+ if (IsUnused(drive, secondary, i))
+ continue;
+ MtdEntryDetails(entry, i, raw);
+ }
+}
void EntriesDetails(struct drive *drive, const int secondary, int raw) {
uint32_t i;
@@ -200,17 +246,86 @@ done:
return retval;
}
-int CgptShow(CgptShowParams *params) {
- struct drive drive;
- int gpt_retval;
+int MtdShow(struct drive *drive, CgptShowParams *params) {
+ if (params->partition) { // show single partition
+ if (params->partition > GetNumberOfEntries(drive)) {
+ Error("invalid partition number: %d\n", params->partition);
+ return CGPT_FAILED;
+ }
- if (params == NULL)
- return CGPT_FAILED;
+ uint32_t index = params->partition - 1;
+ MtdDiskPartition *entry = MtdGetEntry(&drive->mtd, ANY_VALID, index);
+ char buf[256]; // scratch buffer for string conversion
+ const Guid *guid;
- if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDONLY))
- return CGPT_FAILED;
+ if (params->single_item) {
+ switch(params->single_item) {
+ case 'b':
+ printf("%u\n", entry->starting_lba);
+ break;
+ case 's':
+ printf("%u\n", entry->ending_lba - entry->starting_lba + 1);
+ break;
+ case 't':
+ guid = LookupGuidForMtdType(MtdGetEntryType(entry));
+ GuidToStr(guid, buf, sizeof(buf));
+ printf("%s\n", buf);
+ break;
+ case 'S':
+ printf("%d\n", GetSuccessful(drive, ANY_VALID, index));
+ break;
+ case 'T':
+ printf("%d\n", GetTries(drive, ANY_VALID, index));
+ break;
+ case 'P':
+ printf("%d\n", GetPriority(drive, ANY_VALID, index));
+ break;
+ case 'A':
+ printf("0x%x\n", entry->flags);
+ break;
+ }
+ } else {
+ printf(TITLE_FMT, "start", "size", "part", "contents");
+ MtdEntryDetails(entry, index, params->numeric);
+ }
+ } else if (params->quick) { // show all partitions, quickly
+ uint32_t i;
+ char type[GUID_STRLEN];
- if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) {
+ for (i = 0; i < GetNumberOfEntries(drive); ++i) {
+ MtdDiskPartition *entry = MtdGetEntry(&drive->mtd, ANY_VALID, i);
+ const Guid *guid = LookupGuidForMtdType(MtdGetEntryType(entry));
+
+ if (IsUnused(drive, ANY_VALID, i))
+ continue;
+
+ if (!params->numeric && guid) {
+ ResolveType(guid, type);
+ } else {
+ snprintf(type, sizeof(type), "MTD partition type %d",
+ MtdGetEntryType(entry));
+ }
+ printf(PARTITION_FMT, (int)entry->starting_lba,
+ (int)(entry->ending_lba - entry->starting_lba + 1),
+ i+1, type);
+ }
+ } else { // show all partitions
+ if (params->debug || params->verbose) {
+ char indent[64];
+
+ require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent));
+ MtdHeaderDetails(&drive->mtd.primary, indent, 0);
+ }
+
+ MtdEntriesDetails(drive, PRIMARY, params->numeric);
+ }
+
+ return CGPT_OK;
+}
+
+int GptShow(struct drive *drive, CgptShowParams *params) {
+ int gpt_retval;
+ if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive->gpt))) {
Error("GptSanityCheck() returned %d: %s\n",
gpt_retval, GptError(gpt_retval));
return CGPT_FAILED;
@@ -218,13 +333,13 @@ int CgptShow(CgptShowParams *params) {
if (params->partition) { // show single partition
- if (params->partition > GetNumberOfEntries(&drive)) {
+ if (params->partition > GetNumberOfEntries(drive)) {
Error("invalid partition number: %d\n", params->partition);
return CGPT_FAILED;
}
uint32_t index = params->partition - 1;
- GptEntry *entry = GetEntry(&drive.gpt, ANY_VALID, index);
+ GptEntry *entry = GetEntry(&drive->gpt, ANY_VALID, index);
char buf[256]; // scratch buffer for string conversion
if (params->single_item) {
@@ -254,13 +369,13 @@ int CgptShow(CgptShowParams *params) {
printf("%s\n", buf);
break;
case 'S':
- printf("%d\n", GetSuccessful(&drive, ANY_VALID, index));
+ printf("%d\n", GetSuccessful(drive, ANY_VALID, index));
break;
case 'T':
- printf("%d\n", GetTries(&drive, ANY_VALID, index));
+ printf("%d\n", GetTries(drive, ANY_VALID, index));
break;
case 'P':
- printf("%d\n", GetPriority(&drive, ANY_VALID, index));
+ printf("%d\n", GetPriority(drive, ANY_VALID, index));
break;
case 'A':
printf("0x%x\n", entry->attrs.fields.gpt_att);
@@ -276,8 +391,8 @@ int CgptShow(CgptShowParams *params) {
GptEntry *entry;
char type[GUID_STRLEN];
- for (i = 0; i < GetNumberOfEntries(&drive); ++i) {
- entry = GetEntry(&drive.gpt, ANY_VALID, i);
+ for (i = 0; i < GetNumberOfEntries(drive); ++i) {
+ entry = GetEntry(&drive->gpt, ANY_VALID, i);
if (GuidIsZero(&entry->type))
continue;
@@ -293,17 +408,17 @@ int CgptShow(CgptShowParams *params) {
} else { // show all partitions
GptEntry *entries;
- if (CGPT_OK != ReadPMBR(&drive)) {
+ if (CGPT_OK != ReadPMBR(drive)) {
Error("Unable to read PMBR\n");
return CGPT_FAILED;
}
printf(TITLE_FMT, "start", "size", "part", "contents");
char buf[256]; // buffer for formatted PMBR content
- PMBRToStr(&drive.pmbr, buf, sizeof(buf)); // will exit if buf is too small
+ PMBRToStr(&drive->pmbr, buf, sizeof(buf)); // will exit if buf is too small
printf(GPT_FMT, 0, GPT_PMBR_SECTOR, "", buf);
- if (drive.gpt.valid_headers & MASK_PRIMARY) {
+ if (drive->gpt.valid_headers & MASK_PRIMARY) {
printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
(int)GPT_HEADER_SECTOR, "", "Pri GPT header");
} else {
@@ -312,30 +427,30 @@ int CgptShow(CgptShowParams *params) {
}
if (params->debug ||
- ((drive.gpt.valid_headers & MASK_PRIMARY) && params->verbose)) {
+ ((drive->gpt.valid_headers & MASK_PRIMARY) && params->verbose)) {
GptHeader *header;
char indent[64];
require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent));
- header = (GptHeader*)drive.gpt.primary_header;
- entries = (GptEntry*)drive.gpt.primary_entries;
+ header = (GptHeader*)drive->gpt.primary_header;
+ entries = (GptEntry*)drive->gpt.primary_entries;
HeaderDetails(header, entries, indent, params->numeric);
}
printf(GPT_FMT, (int)(GPT_PMBR_SECTOR + GPT_HEADER_SECTOR),
(int)GPT_ENTRIES_SECTORS,
- drive.gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID",
+ drive->gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID",
"Pri GPT table");
if (params->debug ||
- (drive.gpt.valid_entries & MASK_PRIMARY))
- EntriesDetails(&drive, PRIMARY, params->numeric);
+ (drive->gpt.valid_entries & MASK_PRIMARY))
+ EntriesDetails(drive, PRIMARY, params->numeric);
/****************************** Secondary *************************/
- printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR -
+ printf(GPT_FMT, (int)(drive->gpt.drive_sectors - GPT_HEADER_SECTOR -
GPT_ENTRIES_SECTORS),
(int)GPT_ENTRIES_SECTORS,
- drive.gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID",
+ drive->gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID",
"Sec GPT table");
/* We show secondary table details if any of following is true.
* 1. in debug mode.
@@ -343,15 +458,15 @@ int CgptShow(CgptShowParams *params) {
* 3. secondary is not identical to promary.
*/
if (params->debug ||
- ((drive.gpt.valid_entries & MASK_SECONDARY) &&
- (!(drive.gpt.valid_entries & MASK_PRIMARY) ||
- memcmp(drive.gpt.primary_entries, drive.gpt.secondary_entries,
+ ((drive->gpt.valid_entries & MASK_SECONDARY) &&
+ (!(drive->gpt.valid_entries & MASK_PRIMARY) ||
+ memcmp(drive->gpt.primary_entries, drive->gpt.secondary_entries,
TOTAL_ENTRIES_SIZE)))) {
- EntriesDetails(&drive, SECONDARY, params->numeric);
+ EntriesDetails(drive, SECONDARY, params->numeric);
}
- if (drive.gpt.valid_headers & MASK_SECONDARY)
- printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR),
+ if (drive->gpt.valid_headers & MASK_SECONDARY)
+ printf(GPT_FMT, (int)(drive->gpt.drive_sectors - GPT_HEADER_SECTOR),
(int)GPT_HEADER_SECTOR, "", "Sec GPT header");
else
printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
@@ -362,23 +477,43 @@ int CgptShow(CgptShowParams *params) {
* 3. secondary is not synonymous to primary.
*/
if (params->debug ||
- ((drive.gpt.valid_headers & MASK_SECONDARY) &&
- (!(drive.gpt.valid_headers & MASK_PRIMARY) ||
- !IsSynonymous((GptHeader*)drive.gpt.primary_header,
- (GptHeader*)drive.gpt.secondary_header)) &&
+ ((drive->gpt.valid_headers & MASK_SECONDARY) &&
+ (!(drive->gpt.valid_headers & MASK_PRIMARY) ||
+ !IsSynonymous((GptHeader*)drive->gpt.primary_header,
+ (GptHeader*)drive->gpt.secondary_header)) &&
params->verbose)) {
GptHeader *header;
char indent[64];
require(snprintf(indent, sizeof(indent), GPT_MORE) < sizeof(indent));
- header = (GptHeader*)drive.gpt.secondary_header;
- entries = (GptEntry*)drive.gpt.secondary_entries;
+ header = (GptHeader*)drive->gpt.secondary_header;
+ entries = (GptEntry*)drive->gpt.secondary_entries;
HeaderDetails(header, entries, indent, params->numeric);
}
}
- CheckValid(&drive);
- DriveClose(&drive, 0);
+ CheckValid(drive);
+
+ return CGPT_OK;
+}
+
+int CgptShow(CgptShowParams *params) {
+ struct drive drive;
+
+ if (params == NULL)
+ return CGPT_FAILED;
+
+ if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDONLY))
+ return CGPT_FAILED;
+ if (drive.is_mtd) {
+ if (MtdShow(&drive, params))
+ return CGPT_FAILED;
+ } else {
+ if (GptShow(&drive, params))
+ return CGPT_FAILED;
+ }
+
+ DriveClose(&drive, 0);
return CGPT_OK;
}