cgpt.h revision 4464354b7805b7d81667d79624275f525b5a8b11
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 use_host_ioctl; /* Use ioctl() on /dev/fts to read/write. */
58  int bytes_per_page, pages_per_block, fts_block_offset, fts_block_size;
59};
60
61
62/* mode should be O_RDONLY or O_RDWR */
63int DriveOpen(const char *drive_path, struct drive *drive, int mode);
64int DriveClose(struct drive *drive, int update_as_needed);
65int CheckValid(const struct drive *drive);
66
67void TryInitMtd(void);
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// For usage and error messages.
183extern const char* progname;
184extern const char* command;
185void Error(const char *format, ...);
186
187// The code paths that require uuid_generate are not used currently in
188// libcgpt-cc.a so using this method would create an unnecessary dependency
189// on libuuid which then requires us to build it for 32-bit for the static
190// post-installer. So, we just expose this function pointer which should be
191// set to uuid_generate in case of the cgpt binary and can be null or some
192// no-op method in case of ilbcgpt-cc.a.
193extern void (*uuid_generator)(uint8_t* buffer);
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