Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Unified Diff: src/platform/vboot_reference/utility/cgpt/cgpt_show.c

Issue 2231002: complete 'cgpt show' and refactor for incoming commands. (Closed) Base URL: ssh://git@chromiumos-git/chromeos
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/platform/vboot_reference/utility/cgpt/cgpt_repair.c ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/platform/vboot_reference/utility/cgpt/cgpt_show.c
diff --git a/src/platform/vboot_reference/utility/cgpt/cgpt_show.c b/src/platform/vboot_reference/utility/cgpt/cgpt_show.c
index c34e793d629f5a63d89dd130882fc0e146d8fb27..59fd46a8704597c77e92cbfe9c52d9de8007002b 100644
--- a/src/platform/vboot_reference/utility/cgpt/cgpt_show.c
+++ b/src/platform/vboot_reference/utility/cgpt/cgpt_show.c
@@ -12,13 +12,14 @@
#include "utility.h"
/* Integers to store parsed argument. */
-static int help, raw;
+static int help, number, verbose;
/* The structure for getopt_long(). When you add/delete any line, please refine
* attribute_comments[] and third parameter of getopt_long() too. */
static struct option show_options[] = {
{.name = "help", .has_arg = no_argument, .flag = 0, .val = 'h'},
- {.name = "raw", .has_arg = no_argument, .flag = 0, .val = 'r'},
+ {.name = "number", .has_arg = no_argument, .flag = 0, .val = 'n'},
+ {.name = "verbose", .has_arg = no_argument, .flag = 0, .val = 'v'},
};
/* Extra information than struct option, please update this structure if you
@@ -29,11 +30,16 @@ static struct option_details show_options_details[] = {
.validator = AssignTrue,
.valid_range = 0,
.parsed = &help},
- /* raw */
- { .comment = "print raw data (byte-by-byte)",
+ /* number */
+ { .comment = "print raw numbers (don't interpret)",
.validator = AssignTrue,
.valid_range = 0,
- .parsed = &raw},
+ .parsed = &number},
+ /* verbose */
+ { .comment = "verbose print",
+ .validator = AssignTrue,
+ .valid_range = 0,
+ .parsed = &verbose},
};
void ShowHelp() {
@@ -44,10 +50,12 @@ void ShowHelp() {
/* Generate output like:
*
- * {AB-CD-EF-01}
+ * [AB-CD-EF-01] for group = 1
+ * [ABCD-EF01] for group = 3 (low byte first)
*
- * Needs (size*3-1+3) bytes of space in 'buf'.
+ * Needs (size*3-1+3) bytes of space in 'buf' (included the tailing '\0').
*/
+#define BUFFER_SIZE(size) (size *3 - 1 + 3)
static short Uint8To2Chars(const uint8_t t) {
int h = t >> 4;
int l = t & 0xf;
@@ -55,25 +63,159 @@ static short Uint8To2Chars(const uint8_t t) {
l = (l >= 0xA) ? l - 0xA + 'A' : l + '0';
return (h << 8) + l;
}
-static void RawDump(const uint8_t *memory, const int size, char *buf) {
- int i;
- buf[0] = '{';
+static void RawDump(const uint8_t *memory, const int size,
+ char *buf, int group) {
+ int i, outlen = 0;
+ buf[outlen++] = '[';
for (i = 0; i < size; ++i) {
short c2 = Uint8To2Chars(memory[i]);
- buf[i * 3 + 1] = c2 >> 8;
- buf[i * 3 + 2] = c2 & 0xff;
- if (i != (size - 1))
- buf[i * 3 + 3] = '-';
+ buf[outlen++] = c2 >> 8;
+ buf[outlen++] = c2 & 0xff;
+ if (i != (size - 1) && ((i + 1) % group) == 0)
+ buf[outlen++] = '-';
}
- buf[i * 3 + 0] = '}';
- buf[i * 3 + 1] = '\0';
+ buf[outlen++] = ']';
+ buf[outlen++] = '\0';
}
-/* Parses all options (and validates them), then opens the drive and sets
- * corresponding bits in GPT entry. */
+/* Outpur formatters */
+#define TITLE_FMT "%10s%10s%8s %s\n"
+#define GPT_FMT "%10d%10d%8s %s\n"
+#define GPT_MORE "%10s%10s%8s ", "", "", ""
+#define PARTITION_FMT "%10d%10d%8d %s\n"
+#define PARTITION_MORE "%10s%10s%8s %s%s\n", "", "", ""
+
+static void HeaderDetails(GptHeader *header, const char *indent) {
+ int i;
+
+ printf("%sSig: ", indent);
+ if (number == NOT_INITED) {
+ printf("[");
+ for (i = 0; i < sizeof(header->signature); ++i)
+ printf("%c", header->signature[i]);
+ printf("]");
+ } else {
+ char buf[BUFFER_SIZE(sizeof(header->signature))];
+ RawDump((uint8_t *)header->signature, sizeof(header->signature), buf, 1);
+ printf("%s", buf);
+ }
+ printf("\n");
+
+ printf("%sRev: 0x%08x\n", indent, header->revision);
+ printf("%sSize: %d\n", indent, header->size);
+ printf("%sHeader CRC: 0x%08x\n", indent, header->header_crc32);
+ printf("%sMy LBA: %lld\n", indent, (long long)header->my_lba);
+ printf("%sAlter LBA: %lld\n", indent, (long long)header->alternate_lba);
+ printf("%sFirst LBA: %lld\n", indent, (long long)header->first_usable_lba);
+ printf("%sLast LBA: %lld\n", indent, (long long)header->last_usable_lba);
+
+ { /* For disk guid */
+ char buf[GUID_STRLEN];
+ GuidToStr(&header->disk_uuid, buf);
+ printf("%sDisk UUID: %s\n", indent, buf);
+ }
+
+ printf("%sEntries LBA: %lld\n", indent, (long long)header->entries_lba);
+ printf("%sNumber of entries: %d\n", indent, header->number_of_entries);
+ printf("%sSize of entry: %d\n", indent, header->size_of_entry);
+ printf("%sEntries CRC: 0x%08x\n", indent, header->entries_crc32);
+}
+
+/* Resolves human-readable GPT type.
+ * Returns CGPT_OK if found.
+ * Returns CGPT_FAILED if no known type found. */
+int ResolveType(const Guid *type, char *buf) {
+ struct {
+ Guid type;
+ char *description;
+ } known[] = {
+ {GPT_ENT_TYPE_UNUSED, "Unused partition"},
+ {GPT_ENT_TYPE_EFI, "EFI partition"},
+ {GPT_ENT_TYPE_CHROMEOS_KERNEL, "ChromeOS kernel"},
+ {GPT_ENT_TYPE_CHROMEOS_ROOTFS, "ChromeOS rootfs"},
+ {GPT_ENT_TYPE_CHROMEOS_RESERVED, "ChromeOS reserved"},
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_COUNT(known); ++i) {
+ if (!Memcmp(type, &known[i].type, sizeof(Guid))) {
+ strcpy(buf, known[i].description);
+ return CGPT_OK;
+ }
+ }
+ return CGPT_FAILED;
+}
+
+void EntriesDetails(GptData *gpt, const int secondary) {
+ int i;
+
+ for (i = 0; i < GetNumberOfEntries(gpt); ++i) {
+ static Guid unused = GPT_ENT_TYPE_UNUSED;
+ char contents[256];
+
+ GptEntry *entry;
+ entry = GetEntry(gpt, secondary, i);
+
+ if (!Memcmp(&unused, &entry->type, sizeof(unused))) continue;
+
+ if (number == NOT_INITED) {
+ uint8_t label[sizeof(entry->name) * 3 / 2];
+ char type[GUID_STRLEN], unique[GUID_STRLEN];;
+
+ UTF16ToUTF8(entry->name, label);
+ snprintf(contents, sizeof(contents), "Label: \"%s\"", label);
+ printf(PARTITION_FMT, (int)entry->starting_lba,
+ (int)(entry->ending_lba - entry->starting_lba + 1),
+ i, contents);
+ if (CGPT_OK == ResolveType(&entry->type, type)) {
+ printf(PARTITION_MORE, "Type: ", type);
+ } else {
+ GuidToStr(&entry->type, type);
+ printf(PARTITION_MORE, "Type: ", type);
+ }
+ GuidToStr(&entry->unique, unique);
+ printf(PARTITION_MORE, "UUID: ", unique);
+ } else {
+ char label[BUFFER_SIZE(sizeof(entry->name))];
+ char type[GUID_STRLEN], unique[GUID_STRLEN],
+ attributes[BUFFER_SIZE(sizeof(uint64_t))];
+
+ RawDump((void*)entry->name, sizeof(entry->name), label, 2);
+ snprintf(contents, sizeof(contents), "Label: %s", label);
+ printf(PARTITION_FMT, (int)entry->starting_lba,
+ (int)(entry->ending_lba - entry->starting_lba + 1),
+ i, contents);
+ GuidToStr(&entry->type, type);
+ printf(PARTITION_MORE, "Type: ", type);
+ GuidToStr(&entry->unique, unique);
+ printf(PARTITION_MORE, "UUID: ", unique);
+ RawDump((uint8_t*)&entry->attributes, 8, attributes, 4);
+ printf(PARTITION_MORE, "Attr: ", attributes);
+ }
+ }
+}
+
+/* Parses all options (and validates them), then opens the drive.
+ * Show GPT information in following order:
+ *
+ * Primary header sector
+ * details (if -v applied)
+ *
+ * Primary table sectors
+ *
+ * 1st partition
+ * details (if -v applied)
+ * :
+ * last partition
+ * details (if -v applied)
+ *
+ * Secondary table sectors
+ *
+ * Secondary header sector
+ * details (if -v applied)
+ */
int CgptShow(int argc, char *argv[]) {
struct drive drive;
- int i;
/* I know this is NOT the perfect place to put code to make options[] and
* details[] are synced. But this is the best place we have right now since C
@@ -81,10 +223,10 @@ int CgptShow(int argc, char *argv[]) {
assert(ARRAY_COUNT(show_options) ==
ARRAY_COUNT(show_options_details));
- help = raw = NOT_INITED;
+ help = number = NOT_INITED;
if (CGPT_OK != HandleOptions(argc, argv,
- "hr",
+ "hnv",
ARRAY_COUNT(show_options),
show_options,
show_options_details))
@@ -97,56 +239,74 @@ int CgptShow(int argc, char *argv[]) {
if (CGPT_OK != OpenDriveInLastArgument(argc, argv, &drive))
return CGPT_FAILED;
- #define TITLE_FMT "%7s%7s%7s %s\n"
- #define GPT_FMT "%7d%7d%7s %s\n"
- #define GPT_MORE "%7s%7s%7s %s\n", "", "", ""
- #define PARTITION_FMT "%7d%7d%7d %s\n"
- #define PARTITION_MORE "%7s%7s%7s %s%s\n", "", "", ""
printf(TITLE_FMT, "start", "size", "index", "contents");
printf(GPT_FMT, 0, GPT_PMBR_SECTOR, "", "PMBR");
- printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
- (int)GPT_HEADER_SECTOR, "", "Pri GPT header");
- printf(GPT_FMT, (int)(GPT_PMBR_SECTOR + GPT_HEADER_SECTOR),
- (int)GPT_ENTRIES_SECTORS, "", "Pri GPT table");
-
- for (i = 0; i < GetNumberOfEntries(&drive.gpt); ++i) {
- static Guid zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}};
- char contents[128];
- GptEntry *entry;
- entry = GetEntry(&drive.gpt, PRIMARY, i);
- if (!Memcmp(&zero, &entry->type, sizeof(zero))) continue;
+ if (drive.gpt.valid_headers & MASK_PRIMARY) {
+ printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
+ (int)GPT_HEADER_SECTOR, "", "Pri GPT header");
+ if (verbose) {
+ GptHeader *header;
+ char indent[64];
- if (raw == NOT_INITED) {
- /* TODO(yjlou): support pretty dump */
- snprintf(contents, sizeof(contents),
- "* Not supported yet *");
- printf(PARTITION_FMT, (int)entry->starting_lba,
- (int)(entry->ending_lba - entry->starting_lba + 1),
- i, contents);
- } else {
- char type[50], unique[50], attributes[26];
-
- snprintf(contents, sizeof(contents),
- "%s", "");
- printf(PARTITION_FMT, (int)entry->starting_lba,
- (int)(entry->ending_lba - entry->starting_lba + 1),
- i, contents);
- RawDump((uint8_t*)&entry->type, 16, type);
- printf(PARTITION_MORE, "type: ", type);
- RawDump((uint8_t*)&entry->unique, 16, unique);
- printf(PARTITION_MORE, "uuid: ", unique);
- RawDump((uint8_t*)&entry->attributes, 8, attributes);
- printf(PARTITION_MORE, "attr: ", attributes);
+ snprintf(indent, sizeof(indent), GPT_MORE);
+ header = (GptHeader*)drive.gpt.primary_header;
+ HeaderDetails(header, indent);
}
+ } else {
+ printf(GPT_FMT, (int)GPT_PMBR_SECTOR,
+ (int)GPT_HEADER_SECTOR, "INVALID", "Pri GPT header");
}
+ printf(GPT_FMT, (int)(GPT_PMBR_SECTOR + GPT_HEADER_SECTOR),
+ (int)GPT_ENTRIES_SECTORS,
+ drive.gpt.valid_entries & MASK_PRIMARY ? "" : "INVALID",
+ "Pri GPT table");
+
+ if (drive.gpt.valid_entries & MASK_PRIMARY)
+ EntriesDetails(&drive.gpt, PRIMARY);
+
printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR -
GPT_ENTRIES_SECTORS),
- (int)GPT_ENTRIES_SECTORS, "", "Sec GPT table");
- printf(GPT_FMT, (int)(drive.gpt.drive_sectors - GPT_HEADER_SECTOR),
- (int)GPT_HEADER_SECTOR, "", "Sec GPT header");
+ (int)GPT_ENTRIES_SECTORS,
+ drive.gpt.valid_entries & MASK_SECONDARY ? "" : "INVALID",
+ "Sec GPT table");
+ /* We show secondary table details if any of following is true.
+ * 1. only secondary is valid.
+ * 2. secondary is not identical to promary.
+ */
+ if ((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.gpt, SECONDARY);
+ }
+
+ 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,
+ (int)GPT_HEADER_SECTOR, "INVALID", "Sec GPT header");
+ /* We show secondary header if any of following is true:
+ * 1. only secondary is valid.
+ * 2. secondary is not synonymous to primary.
+ */
+ if ((drive.gpt.valid_headers & MASK_SECONDARY) &&
+ (!(drive.gpt.valid_headers & MASK_PRIMARY) ||
+ !IsSynonymous((GptHeader*)drive.gpt.primary_header,
+ (GptHeader*)drive.gpt.secondary_header))) {
+ if (verbose) {
+ GptHeader *header;
+ char indent[64];
+
+ snprintf(indent, sizeof(indent), GPT_MORE);
+ header = (GptHeader*)drive.gpt.secondary_header;
+ HeaderDetails(header, indent);
+ }
+ }
+ CheckValid(&drive);
DriveClose(&drive);
return CGPT_OK;
« no previous file with comments | « src/platform/vboot_reference/utility/cgpt/cgpt_repair.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698