blob: b8b7e8d5cdd1aee66ac2b882387f48170883a7d0 [file] [log] [blame]
Jay Srinivasan250549d2012-02-16 17:40:45 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Bill Richardsonf1372d92010-06-11 09:15:55 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_
6#define VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_
7
Bill Richardson23429d32012-04-30 11:33:13 -07008#include <fcntl.h>
David Riley05987b12015-02-05 19:22:49 -08009#ifndef HAVE_MACOS
Bill Richardsonf1372d92010-06-11 09:15:55 -070010#include <features.h>
David Riley05987b12015-02-05 19:22:49 -080011#endif
Bill Richardsonf1372d92010-06-11 09:15:55 -070012#include <stdint.h>
Bill Richardsonc4e92af2010-10-12 07:33:15 -070013#include <stdio.h>
14#include <stdlib.h>
Bill Richardson4cb54972014-06-20 14:33:00 -070015#include "cgpt_endian.h"
Bill Richardsonf1372d92010-06-11 09:15:55 -070016#include "cgptlib.h"
Bill Richardson4cb54972014-06-20 14:33:00 -070017#include "gpt.h"
Bill Richardsonf1372d92010-06-11 09:15:55 -070018
Bill Richardsonf1372d92010-06-11 09:15:55 -070019struct legacy_partition {
20 uint8_t status;
21 uint8_t f_head;
22 uint8_t f_sect;
23 uint8_t f_cyl;
24 uint8_t type;
25 uint8_t l_head;
26 uint8_t l_sect;
27 uint8_t l_cyl;
28 uint32_t f_lba;
29 uint32_t num_sect;
30} __attribute__((packed));
31
Bill Richardsonf1372d92010-06-11 09:15:55 -070032// syslinux uses this format:
33struct pmbr {
34 uint8_t bootcode[424];
35 Guid boot_guid;
36 uint32_t disk_id;
37 uint8_t magic[2]; // 0x1d, 0x9a
38 struct legacy_partition part[4];
39 uint8_t sig[2]; // 0x55, 0xaa
40} __attribute__((packed));
41
Bill Richardsonc4e92af2010-10-12 07:33:15 -070042void PMBRToStr(struct pmbr *pmbr, char *str, unsigned int buflen);
Bill Richardsonf1372d92010-06-11 09:15:55 -070043
44// Handle to the drive storing the GPT.
45struct drive {
Bill Richardsonf1372d92010-06-11 09:15:55 -070046 uint64_t size; /* total size (in bytes) */
47 GptData gpt;
48 struct pmbr pmbr;
Nam T. Nguyenab899592014-11-13 19:30:46 -080049 int fd; /* file descriptor */
Bill Richardsonf1372d92010-06-11 09:15:55 -070050};
51
Nam T. Nguyen6ee52d92014-10-24 13:20:39 -070052// Opens a block device or file, loads raw GPT data from it.
Nam T. Nguyenab899592014-11-13 19:30:46 -080053// 'mode' should be O_RDONLY or O_RDWR.
54// If 'drive_size' is 0, both the partitions and GPT structs reside on the same
55// 'drive_path'.
56// Otherwise, 'drive_size' is taken as the size of the device that all
57// partitions will reside on, and 'drive_path' is where we store GPT structs.
Nam T. Nguyen6ee52d92014-10-24 13:20:39 -070058//
59// Returns CGPT_FAILED if any error happens.
Nam T. Nguyenab899592014-11-13 19:30:46 -080060// Returns CGPT_OK if success and information are stored in 'drive'. */
61int DriveOpen(const char *drive_path, struct drive *drive, int mode,
62 uint64_t drive_size);
Bill Richardsonf1372d92010-06-11 09:15:55 -070063int DriveClose(struct drive *drive, int update_as_needed);
64int CheckValid(const struct drive *drive);
65
Albert Chaulk534723a2013-03-20 14:46:50 -070066/* Loads sectors from 'drive'.
67 * *buf is pointed to an allocated memory when returned, and should be
68 * freed.
69 *
70 * drive -- open drive.
71 * buf -- pointer to buffer pointer
72 * sector -- offset of starting sector (in sectors)
73 * sector_bytes -- bytes per sector
74 * sector_count -- number of sectors to load
75 *
76 * Returns CGPT_OK for successful. Aborts if any error occurs.
77 */
78int Load(struct drive *drive, uint8_t **buf,
79 const uint64_t sector,
80 const uint64_t sector_bytes,
81 const uint64_t sector_count);
82
83/* Saves sectors to 'drive'.
84 *
85 * drive -- open drive
86 * buf -- pointer to buffer
87 * sector -- starting sector offset
88 * sector_bytes -- bytes per sector
89 * sector_count -- number of sector to save
90 *
91 * Returns CGPT_OK for successful, CGPT_FAILED for failed.
92 */
93int Save(struct drive *drive, const uint8_t *buf,
94 const uint64_t sector,
95 const uint64_t sector_bytes,
96 const uint64_t sector_count);
97
98
99/* GUID conversion functions. Accepted format:
100 *
101 * "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
102 *
103 * At least GUID_STRLEN bytes should be reserved in 'str' (included the tailing
104 * '\0').
105 */
106#define GUID_STRLEN 37
107int StrToGuid(const char *str, Guid *guid);
108void GuidToStr(const Guid *guid, char *str, unsigned int buflen);
109int GuidEqual(const Guid *guid1, const Guid *guid2);
110int IsZero(const Guid *guid);
111
Bill Richardson3430b322010-11-29 14:24:51 -0800112/* Constant global type values to compare against */
Gabe Black93cf15e2011-07-07 16:00:00 -0700113extern const Guid guid_chromeos_firmware;
Bill Richardson3430b322010-11-29 14:24:51 -0800114extern const Guid guid_chromeos_kernel;
115extern const Guid guid_chromeos_rootfs;
116extern const Guid guid_linux_data;
117extern const Guid guid_chromeos_reserved;
118extern const Guid guid_efi;
119extern const Guid guid_unused;
Bill Richardsonf1372d92010-06-11 09:15:55 -0700120
121int ReadPMBR(struct drive *drive);
122int WritePMBR(struct drive *drive);
123
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700124/* Convert possibly unterminated UTF16 string to UTF8.
125 * Caller must prepare enough space for UTF8, which could be up to
Louis Yung-Chieh Lo500b3c22010-11-22 18:19:11 +0800126 * twice the byte length of UTF16 string plus the terminating '\0'.
127 *
128 * Return: CGPT_OK --- all character are converted successfully.
129 * CGPT_FAILED --- convert error, i.e. output buffer is too short.
Bill Richardsonf1372d92010-06-11 09:15:55 -0700130 */
Louis Yung-Chieh Lo500b3c22010-11-22 18:19:11 +0800131int UTF16ToUTF8(const uint16_t *utf16, unsigned int maxinput,
132 uint8_t *utf8, unsigned int maxoutput);
133
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700134/* Convert null-terminated UTF8 string to UTF16.
Louis Yung-Chieh Lo500b3c22010-11-22 18:19:11 +0800135 * Caller must prepare enough space for UTF16, which is the byte length of UTF8
136 * plus the terminating 0x0000.
137 *
138 * Return: CGPT_OK --- all character are converted successfully.
139 * CGPT_FAILED --- convert error, i.e. output buffer is too short.
Bill Richardsonf1372d92010-06-11 09:15:55 -0700140 */
Louis Yung-Chieh Lo500b3c22010-11-22 18:19:11 +0800141int UTF8ToUTF16(const uint8_t *utf8, uint16_t *utf16, unsigned int maxoutput);
Bill Richardsonf1372d92010-06-11 09:15:55 -0700142
143/* Helper functions for supported GPT types. */
144int ResolveType(const Guid *type, char *buf);
145int SupportedType(const char *name, Guid *type);
146void PrintTypes(void);
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700147void EntryDetails(GptEntry *entry, uint32_t index, int raw);
Bill Richardsonf1372d92010-06-11 09:15:55 -0700148
Albert Chaulkfa6b35c2013-03-26 13:43:02 -0700149uint32_t GetNumberOfEntries(const struct drive *drive);
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700150GptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index);
Albert Chaulkb334e652013-03-28 15:25:33 -0700151
Albert Chaulkfa6b35c2013-03-26 13:43:02 -0700152void SetPriority(struct drive *drive, int secondary, uint32_t entry_index,
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700153 int priority);
Albert Chaulkfa6b35c2013-03-26 13:43:02 -0700154int GetPriority(struct drive *drive, int secondary, uint32_t entry_index);
155void SetTries(struct drive *drive, int secondary, uint32_t entry_index,
156 int tries);
157int GetTries(struct drive *drive, int secondary, uint32_t entry_index);
158void SetSuccessful(struct drive *drive, int secondary, uint32_t entry_index,
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700159 int success);
Albert Chaulkfa6b35c2013-03-26 13:43:02 -0700160int GetSuccessful(struct drive *drive, int secondary, uint32_t entry_index);
161
162void SetRaw(struct drive *drive, int secondary, uint32_t entry_index,
163 uint32_t raw);
164
165void UpdateAllEntries(struct drive *drive);
Bill Richardsonf1372d92010-06-11 09:15:55 -0700166
167uint8_t RepairHeader(GptData *gpt, const uint32_t valid_headers);
168uint8_t RepairEntries(GptData *gpt, const uint32_t valid_entries);
169void UpdateCrc(GptData *gpt);
170int IsSynonymous(const GptHeader* a, const GptHeader* b);
171
Albert Chaulkfa6b35c2013-03-26 13:43:02 -0700172int IsUnused(struct drive *drive, int secondary, uint32_t index);
173int IsKernel(struct drive *drive, int secondary, uint32_t index);
174
Bill Richardson4cb54972014-06-20 14:33:00 -0700175// Optional. Applications that need this must provide an implementation.
176//
177// Explanation:
178// Some external utilities need to manipulate the GPT, but don't create new
179// partitions from scratch. The cgpt executable uses libuuid to provide this
180// functionality, but we don't want to have to build or install a separate
181// instance of that library just for the 32-bit static post-install tool,
182// which doesn't need this function.
183int GenerateGuid(Guid *newguid);
Bill Richardsonf1372d92010-06-11 09:15:55 -0700184
Bill Richardson4cb54972014-06-20 14:33:00 -0700185// For usage and error messages.
186void Error(const char *format, ...);
Nam T. Nguyen6ee52d92014-10-24 13:20:39 -0700187void Warning(const char *format, ...);
Bill Richardsonf1372d92010-06-11 09:15:55 -0700188
189// Command functions.
190int cmd_show(int argc, char *argv[]);
191int cmd_repair(int argc, char *argv[]);
192int cmd_create(int argc, char *argv[]);
193int cmd_add(int argc, char *argv[]);
194int cmd_boot(int argc, char *argv[]);
Bill Richardson4a209312010-07-02 11:34:38 -0700195int cmd_find(int argc, char *argv[]);
Bill Richardson3430b322010-11-29 14:24:51 -0800196int cmd_prioritize(int argc, char *argv[]);
Stefan Reinauerb7b865c2012-08-23 15:06:25 -0700197int cmd_legacy(int argc, char *argv[]);
Bill Richardsonf1372d92010-06-11 09:15:55 -0700198
199#define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0]))
200const char *GptError(int errnum);
201
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700202// Size in chars of the GPT Entry's PartitionName field
203#define GPT_PARTNAME_LEN 72
204
205/* The standard "assert" macro goes away when NDEBUG is defined. This doesn't.
206 */
207#define require(A) do { \
208 if (!(A)) { \
209 fprintf(stderr, "condition (%s) failed at %s:%d\n", \
210 #A, __FILE__, __LINE__); \
211 exit(1); } \
212 } while (0)
Bill Richardsonf1372d92010-06-11 09:15:55 -0700213
214#endif // VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_