cgpt.h revision 4cb5497984642b8cbd592c14cb1912a787b2d4d7
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 "cgpt_endian.h"
14#include "cgptlib.h"
15#include "gpt.h"
16#include "mtdlib.h"
17
18struct legacy_partition {
19  uint8_t  status;
20  uint8_t  f_head;
21  uint8_t  f_sect;
22  uint8_t  f_cyl;
23  uint8_t  type;
24  uint8_t  l_head;
25  uint8_t  l_sect;
26  uint8_t  l_cyl;
27  uint32_t f_lba;
28  uint32_t num_sect;
29} __attribute__((packed));
30
31
32// 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
42void PMBRToStr(struct pmbr *pmbr, char *str, unsigned int buflen);
43
44// Handle to the drive storing the GPT.
45struct drive {
46  int fd;           /* file descriptor */
47  uint64_t size;    /* total size (in bytes) */
48  int is_mtd;
49  GptData gpt;
50  MtdData mtd;
51  struct pmbr pmbr;
52};
53
54struct nand_layout {
55  int enabled;
56  int use_host_ioctl; /* Use ioctl() on /dev/fts to read/write. */
57  int bytes_per_page, pages_per_block, fts_block_offset, fts_block_size;
58};
59
60/* Write a NAND/MTD image instead of GPT. */
61void EnableNandImage(int bytes_per_page, int pages_per_block,
62                     int fts_block_offset, int fts_block_size);
63
64/* mode should be O_RDONLY or O_RDWR */
65int DriveOpen(const char *drive_path, struct drive *drive, int mode);
66int DriveClose(struct drive *drive, int update_as_needed);
67int CheckValid(const struct drive *drive);
68
69/* Loads sectors from 'drive'.
70 * *buf is pointed to an allocated memory when returned, and should be
71 * freed.
72 *
73 *   drive -- open drive.
74 *   buf -- pointer to buffer pointer
75 *   sector -- offset of starting sector (in sectors)
76 *   sector_bytes -- bytes per sector
77 *   sector_count -- number of sectors to load
78 *
79 * Returns CGPT_OK for successful. Aborts if any error occurs.
80 */
81int Load(struct drive *drive, uint8_t **buf,
82                const uint64_t sector,
83                const uint64_t sector_bytes,
84                const uint64_t sector_count);
85
86/* Saves sectors to 'drive'.
87 *
88 *   drive -- open drive
89 *   buf -- pointer to buffer
90 *   sector -- starting sector offset
91 *   sector_bytes -- bytes per sector
92 *   sector_count -- number of sector to save
93 *
94 * Returns CGPT_OK for successful, CGPT_FAILED for failed.
95 */
96int Save(struct drive *drive, const uint8_t *buf,
97                const uint64_t sector,
98                const uint64_t sector_bytes,
99                const uint64_t sector_count);
100
101
102/* GUID conversion functions. Accepted format:
103 *
104 *   "C12A7328-F81F-11D2-BA4B-00A0C93EC93B"
105 *
106 * At least GUID_STRLEN bytes should be reserved in 'str' (included the tailing
107 * '\0').
108 */
109#define GUID_STRLEN 37
110int StrToGuid(const char *str, Guid *guid);
111void GuidToStr(const Guid *guid, char *str, unsigned int buflen);
112int GuidEqual(const Guid *guid1, const Guid *guid2);
113int IsZero(const Guid *guid);
114
115/* Constant global type values to compare against */
116extern const Guid guid_chromeos_firmware;
117extern const Guid guid_chromeos_kernel;
118extern const Guid guid_chromeos_rootfs;
119extern const Guid guid_linux_data;
120extern const Guid guid_chromeos_reserved;
121extern const Guid guid_efi;
122extern const Guid guid_unused;
123
124int ReadPMBR(struct drive *drive);
125int WritePMBR(struct drive *drive);
126
127/* Convert possibly unterminated UTF16 string to UTF8.
128 * Caller must prepare enough space for UTF8, which could be up to
129 * twice the byte length of UTF16 string plus the terminating '\0'.
130 *
131 * Return: CGPT_OK --- all character are converted successfully.
132 *         CGPT_FAILED --- convert error, i.e. output buffer is too short.
133 */
134int UTF16ToUTF8(const uint16_t *utf16, unsigned int maxinput,
135                uint8_t *utf8, unsigned int maxoutput);
136
137/* Convert null-terminated UTF8 string to UTF16.
138 * Caller must prepare enough space for UTF16, which is the byte length of UTF8
139 * plus the terminating 0x0000.
140 *
141 * Return: CGPT_OK --- all character are converted successfully.
142 *         CGPT_FAILED --- convert error, i.e. output buffer is too short.
143 */
144int UTF8ToUTF16(const uint8_t *utf8, uint16_t *utf16, unsigned int maxoutput);
145
146/* Helper functions for supported GPT types. */
147int ResolveType(const Guid *type, char *buf);
148int SupportedType(const char *name, Guid *type);
149void PrintTypes(void);
150void EntryDetails(GptEntry *entry, uint32_t index, int raw);
151void MtdEntryDetails(MtdDiskPartition *entry, uint32_t index, int raw);
152
153uint32_t GetNumberOfEntries(const struct drive *drive);
154GptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index);
155MtdDiskPartition *MtdGetEntry(MtdData *mtd, int secondary, uint32_t index);
156
157void SetPriority(struct drive *drive, int secondary, uint32_t entry_index,
158                 int priority);
159int GetPriority(struct drive *drive, int secondary, uint32_t entry_index);
160void SetTries(struct drive *drive, int secondary, uint32_t entry_index,
161              int tries);
162int GetTries(struct drive *drive, int secondary, uint32_t entry_index);
163void SetSuccessful(struct drive *drive, int secondary, uint32_t entry_index,
164                   int success);
165int GetSuccessful(struct drive *drive, int secondary, uint32_t entry_index);
166
167void SetRaw(struct drive *drive, int secondary, uint32_t entry_index,
168           uint32_t raw);
169
170void UpdateAllEntries(struct drive *drive);
171
172uint8_t RepairHeader(GptData *gpt, const uint32_t valid_headers);
173uint8_t RepairEntries(GptData *gpt, const uint32_t valid_entries);
174void UpdateCrc(GptData *gpt);
175int IsSynonymous(const GptHeader* a, const GptHeader* b);
176
177int IsUnused(struct drive *drive, int secondary, uint32_t index);
178int IsKernel(struct drive *drive, int secondary, uint32_t index);
179int LookupMtdTypeForGuid(const Guid *type);
180const Guid *LookupGuidForMtdType(int type);
181
182// Optional. Applications that need this must provide an implementation.
183//
184// Explanation:
185//   Some external utilities need to manipulate the GPT, but don't create new
186//   partitions from scratch. The cgpt executable uses libuuid to provide this
187//   functionality, but we don't want to have to build or install a separate
188//   instance of that library just for the 32-bit static post-install tool,
189//   which doesn't need this function.
190int GenerateGuid(Guid *newguid);
191
192// For usage and error messages.
193void Error(const char *format, ...);
194
195// Command functions.
196int cmd_show(int argc, char *argv[]);
197int cmd_repair(int argc, char *argv[]);
198int cmd_create(int argc, char *argv[]);
199int cmd_add(int argc, char *argv[]);
200int cmd_boot(int argc, char *argv[]);
201int cmd_find(int argc, char *argv[]);
202int cmd_prioritize(int argc, char *argv[]);
203int cmd_legacy(int argc, char *argv[]);
204
205#define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0]))
206const char *GptError(int errnum);
207
208// Size in chars of the GPT Entry's PartitionName field
209#define GPT_PARTNAME_LEN 72
210
211/* The standard "assert" macro goes away when NDEBUG is defined. This doesn't.
212 */
213#define require(A) do { \
214  if (!(A)) { \
215    fprintf(stderr, "condition (%s) failed at %s:%d\n", \
216            #A, __FILE__, __LINE__); \
217    exit(1); } \
218  } while (0)
219
220#endif  // VBOOT_REFERENCE_UTILITY_CGPT_CGPT_H_
221