blob: ccf73184607558b1aaa561e7114a31d262d6bee0 [file] [log] [blame]
Bill Richardsonf1372d92010-06-11 09:15:55 -07001/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Utility for ChromeOS-specific GPT partitions, Please see corresponding .c
6 * files for more details.
7 */
8
Bill Richardsonf1372d92010-06-11 09:15:55 -07009#include <stdio.h>
10#include <string.h>
11#include <unistd.h>
Jay Srinivasan5fac7572012-02-23 10:59:01 -080012#include <uuid/uuid.h>
Bill Richardsonf1372d92010-06-11 09:15:55 -070013
Bill Richardson0c3ba242013-03-29 11:09:30 -070014#include "cgpt.h"
15#include "vboot_host.h"
16
Bill Richardsonf1372d92010-06-11 09:15:55 -070017const char* progname;
Bill Richardson4cb54972014-06-20 14:33:00 -070018
19int GenerateGuid(Guid *newguid)
20{
21 /* From libuuid */
22 uuid_generate(newguid->u.raw);
23 return CGPT_OK;
24}
Bill Richardsonf1372d92010-06-11 09:15:55 -070025
26struct {
27 const char *name;
28 int (*fp)(int argc, char *argv[]);
29 const char *comment;
30} cmds[] = {
31 {"create", cmd_create, "Create or reset GPT headers and tables"},
32 {"add", cmd_add, "Add, edit or remove a partition entry"},
33 {"show", cmd_show, "Show partition table and entries"},
34 {"repair", cmd_repair, "Repair damaged GPT headers and tables"},
35 {"boot", cmd_boot, "Edit the PMBR sector for legacy BIOSes"},
Bill Richardson4a209312010-07-02 11:34:38 -070036 {"find", cmd_find, "Locate a partition by its GUID"},
Bill Richardson3430b322010-11-29 14:24:51 -080037 {"prioritize", cmd_prioritize,
38 "Reorder the priority of all kernel partitions"},
Stefan Reinauerb7b865c2012-08-23 15:06:25 -070039 {"legacy", cmd_legacy, "Switch between GPT and Legacy GPT"},
Bill Richardsonf1372d92010-06-11 09:15:55 -070040};
41
Bill Richardsonf1372d92010-06-11 09:15:55 -070042void Usage(void) {
43 int i;
44
Bill Richardson3430b322010-11-29 14:24:51 -080045 printf("\nUsage: %s COMMAND [OPTIONS] DRIVE\n\n"
Bill Richardsonf1372d92010-06-11 09:15:55 -070046 "Supported COMMANDs:\n\n",
47 progname);
48
49 for (i = 0; i < sizeof(cmds)/sizeof(cmds[0]); ++i) {
Bill Richardson3430b322010-11-29 14:24:51 -080050 printf(" %-15s %s\n", cmds[i].name, cmds[i].comment);
Bill Richardsonf1372d92010-06-11 09:15:55 -070051 }
52 printf("\nFor more detailed usage, use %s COMMAND -h\n\n", progname);
53}
54
Albert Chaulka75071c2013-03-29 15:02:38 -070055static int is_pow2(size_t v) {
56 return v && (v & (v - 1)) == 0;
57}
Bill Richardsonf1372d92010-06-11 09:15:55 -070058
Albert Chaulka75071c2013-03-29 15:02:38 -070059static int parse_nand_option(const char *arg) {
Albert Chaulkd41000e2013-07-19 11:12:42 -070060 int bytes_per_page, pages_per_block, fts_block_offset, fts_block_size;
61
Albert Chaulka75071c2013-03-29 15:02:38 -070062 if ('=' != arg[0])
63 return -1;
64
65 arg++;
Albert Chaulkd41000e2013-07-19 11:12:42 -070066 bytes_per_page = atoi(arg);
Albert Chaulka75071c2013-03-29 15:02:38 -070067 arg = strchr(arg, ',');
68 if (!arg)
69 return -1;
70
71 arg++;
Albert Chaulkd41000e2013-07-19 11:12:42 -070072 pages_per_block = atoi(arg);
Albert Chaulka75071c2013-03-29 15:02:38 -070073 arg = strchr(arg, ',');
74 if (!arg)
75 return -1;
76
77 arg++;
Albert Chaulkd41000e2013-07-19 11:12:42 -070078 fts_block_offset = atoi(arg);
Albert Chaulka75071c2013-03-29 15:02:38 -070079 arg = strchr(arg, ',');
80 if (!arg)
81 return -1;
82
83 arg++;
Albert Chaulkd41000e2013-07-19 11:12:42 -070084 fts_block_size = atoi(arg);
85 if (fts_block_size == 0 || !is_pow2(pages_per_block) ||
86 !is_pow2(bytes_per_page) || bytes_per_page < 512) {
Albert Chaulka75071c2013-03-29 15:02:38 -070087 return -1;
88 }
Albert Chaulkd41000e2013-07-19 11:12:42 -070089 EnableNandImage(bytes_per_page, pages_per_block, fts_block_offset,
90 fts_block_size);
Albert Chaulka75071c2013-03-29 15:02:38 -070091 return 0;
92}
Bill Richardsonf1372d92010-06-11 09:15:55 -070093
94int main(int argc, char *argv[]) {
95 int i;
Bill Richardson3430b322010-11-29 14:24:51 -080096 int match_count = 0;
97 int match_index = 0;
Bill Richardson4cb54972014-06-20 14:33:00 -070098 char* command;
Jay Srinivasan5fac7572012-02-23 10:59:01 -080099
Bill Richardsonf1372d92010-06-11 09:15:55 -0700100 progname = strrchr(argv[0], '/');
101 if (progname)
102 progname++;
103 else
104 progname = argv[0];
105
Albert Chaulka75071c2013-03-29 15:02:38 -0700106
Albert Chaulka75071c2013-03-29 15:02:38 -0700107 for (i = 1; i < argc; ++i) {
108 if (0 == strncmp(argv[i], "-N", 2)) {
109 if (!parse_nand_option(argv[i] + 2)) {
110 int j;
Albert Chaulka75071c2013-03-29 15:02:38 -0700111
112 // Remove it form the list.
113 for (j = i; j < argc - 1; j++)
114 argv[j] = argv[j + 1];
115 argc--;
116 break;
117 }
118 // Bad nand config.
119 printf("Nand option must fit: -N=<bytes_per_page>,<pages_per_block>,"
120 "<block_offset_of_partition>,<block_size_of_partition>\n");
121 return CGPT_FAILED;
122 }
123 }
124
Bill Richardsonf1372d92010-06-11 09:15:55 -0700125 if (argc < 2) {
126 Usage();
127 return CGPT_FAILED;
128 }
129
130 // increment optind now, so that getopt skips argv[0] in command function
131 command = argv[optind++];
132
133 // Find the command to invoke.
134 for (i = 0; command && i < sizeof(cmds)/sizeof(cmds[0]); ++i) {
Bill Richardson3430b322010-11-29 14:24:51 -0800135 // exact match?
Bill Richardsonf1372d92010-06-11 09:15:55 -0700136 if (0 == strcmp(cmds[i].name, command)) {
Bill Richardson3430b322010-11-29 14:24:51 -0800137 match_index = i;
138 match_count = 1;
139 break;
140 }
141 // unique match?
142 else if (0 == strncmp(cmds[i].name, command, strlen(command))) {
143 match_index = i;
144 match_count++;
Bill Richardsonf1372d92010-06-11 09:15:55 -0700145 }
146 }
147
Bill Richardson3430b322010-11-29 14:24:51 -0800148 if (match_count == 1)
149 return cmds[match_index].fp(argc, argv);
150
151 // Couldn't find a single matching command.
Bill Richardsonf1372d92010-06-11 09:15:55 -0700152 Usage();
153
154 return CGPT_FAILED;
155}