cgpt.h revision 92f22e7c2a1ca08034ac3ad21b2af60347c1c4fb
1// Copyright (c) 2012 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#ifndef VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_
6#define VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_
7
8#include <fcntl.h>
9#include <features.h>
10#include <stdint.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include "endian.h"
14#include "gpt.h"
15#include "cgptlib.h"
16#include "mtdlib.h"
17
18
19struct 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
32
33// syslinux uses this format:
34struct pmbr {
35  uint8_t                 bootcode[424];
36  Guid                    boot_guid;
37  uint32_t                disk_id;
38  uint8_t                 magic[2];     // 0x1d, 0x9a
39  struct legacy_partition part[4];
40  uint8_t                 sig[2];       // 0x55, 0xaa
41} __attribute__((packed));
42
43void PMBRToStr(struct pmbr *pmbr, char *str, unsigned int buflen);
44
45// Handle to the drive storing the GPT.
46struct drive {
47  int fd;           /* file descriptor */
48  uint64_t size;    /* total size (in bytes) */
49  int is_mtd;
50  GptData gpt;
51  MtdData mtd;
52  struct pmbr pmbr;
53};
54
55struct nand_layout {
56  int enabled;
57  int bytes_per_page, pages_per_block, fts_block_offset, fts_block_size;
58};
59
60
61/* mode should be O_RDONLY or O_RDWR */
62int DriveOpen(const char *drive_path, struct drive *drive, int mode);
63int DriveClose(struct drive *drive, int update_as_needed);
64int CheckValid(const struct drive *drive);
65
66/* 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
112/* Constant global type values to compare against */
113extern const Guid guid_chromeos_firmware;
114extern 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;
120
121int ReadPMBR(struct drive *drive);
122int WritePMBR(struct drive *drive);
123
124/* Convert possibly unterminated UTF16 string to UTF8.
125 * Caller must prepare enough space for UTF8, which could be up to
126 * 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.
130 */
131int UTF16ToUTF8(const uint16_t *utf16, unsigned int maxinput,
132                uint8_t *utf8, unsigned int maxoutput);
133
134/* Convert null-terminated UTF8 string to UTF16.
135 * 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.
140 */
141int UTF8ToUTF16(const uint8_t *utf8, uint16_t *utf16, unsigned int maxoutput);
142
143/* Helper functions for supported GPT types. */
144int ResolveType(const Guid *type, char *buf);
145int SupportedType(const char *name, Guid *type);
146void PrintTypes(void);
147void EntryDetails(GptEntry *entry, uint32_t index, int raw);
148void MtdEntryDetails(MtdDiskPartition *entry, uint32_t index, int raw);
149
150uint32_t GetNumberOfEntries(const struct drive *drive);
151GptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index);
152MtdDiskPartition *MtdGetEntry(MtdData *mtd, int secondary, uint32_t index);
153
154void SetPriority(struct drive *drive, int secondary, uint32_t entry_index,
155                 int priority);
156int GetPriority(struct drive *drive, int secondary, uint32_t entry_index);
157void SetTries(struct drive *drive, int secondary, uint32_t entry_index,
158              int tries);
159int GetTries(struct drive *drive, int secondary, uint32_t entry_index);
160void SetSuccessful(struct drive *drive, int secondary, uint32_t entry_index,
161                   int success);
162int GetSuccessful(struct drive *drive, int secondary, uint32_t entry_index);
163
164void SetRaw(struct drive *drive, int secondary, uint32_t entry_index,
165           uint32_t raw);
166
167void UpdateAllEntries(struct drive *drive);
168
169uint8_t RepairHeader(GptData *gpt, const uint32_t valid_headers);
170uint8_t RepairEntries(GptData *gpt, const uint32_t valid_entries);
171void UpdateCrc(GptData *gpt);
172int IsSynonymous(const GptHeader* a, const GptHeader* b);
173
174int IsUnused(struct drive *drive, int secondary, uint32_t index);
175int IsKernel(struct drive *drive, int secondary, uint32_t index);
176int LookupMtdTypeForGuid(const Guid *type);
177const Guid *LookupGuidForMtdType(int type);
178
179// For usage and error messages.
180extern const char* progname;
181extern const char* command;
182void Error(const char *format, ...);
183
184// The code paths that require uuid_generate are not used currently in
185// libcgpt-cc.a so using this method would create an unnecessary dependency
186// on libuuid which then requires us to build it for 32-bit for the static
187// post-installer. So, we just expose this function pointer which should be
188// set to uuid_generate in case of the cgpt binary and can be null or some
189// no-op method in case of ilbcgpt-cc.a.
190extern void (*uuid_generator)(uint8_t* buffer);
191
192// Command functions.
193int cmd_show(int argc, char *argv[]);
194int cmd_repair(int argc, char *argv[]);
195int cmd_create(int argc, char *argv[]);
196int cmd_add(int argc, char *argv[]);
197int cmd_boot(int argc, char *argv[]);
198int cmd_find(int argc, char *argv[]);
199int cmd_prioritize(int argc, char *argv[]);
200int cmd_legacy(int argc, char *argv[]);
201
202#define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0]))
203const char *GptError(int errnum);
204
205// Size in chars of the GPT Entry's PartitionName field
206#define GPT_PARTNAME_LEN 72
207
208/* The standard "assert" macro goes away when NDEBUG is defined. This doesn't.
209 */
210#define require(A) do { \
211  if (!(A)) { \
212    fprintf(stderr, "condition (%s) failed at %s:%d\n", \
213            #A, __FILE__, __LINE__); \
214    exit(1); } \
215  } while (0)
216
217#endif  // VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_
218