xref: /aosp_15_r20/external/vboot_reference/cgpt/cgpt.h (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1 /* Copyright 2012 The ChromiumOS Authors
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  */
5 
6 #ifndef VBOOT_REFERENCE_CGPT_H_
7 #define VBOOT_REFERENCE_CGPT_H_
8 
9 #include <fcntl.h>
10 #if !defined(HAVE_MACOS) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
11 #include <features.h>
12 #endif
13 #include <stdint.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include "cgpt_endian.h"
17 #include "cgptlib.h"
18 #include "gpt.h"
19 
20 struct legacy_partition {
21   uint8_t  status;
22   uint8_t  f_head;
23   uint8_t  f_sect;
24   uint8_t  f_cyl;
25   uint8_t  type;
26   uint8_t  l_head;
27   uint8_t  l_sect;
28   uint8_t  l_cyl;
29   uint32_t f_lba;
30   uint32_t num_sect;
31 } __attribute__((packed));
32 
33 // syslinux uses this format:
34 struct 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 
43 void PMBRToStr(struct pmbr *pmbr, char *str, unsigned int buflen);
44 
45 // Handle to the drive storing the GPT.
46 struct drive {
47   uint64_t size;    /* total size (in bytes) */
48   GptData gpt;
49   struct pmbr pmbr;
50   int fd;       /* file descriptor */
51 };
52 
53 // Opens a block device or file, loads raw GPT data from it.
54 // 'mode' should be O_RDONLY or O_RDWR.
55 // If 'drive_size' is 0, both the partitions and GPT structs reside on the same
56 // 'drive_path'.
57 // Otherwise, 'drive_size' is taken as the size of the device that all
58 // partitions will reside on, and 'drive_path' is where we store GPT structs.
59 //
60 // Returns CGPT_FAILED if any error happens.
61 // Returns CGPT_OK if success and information are stored in 'drive'. */
62 int DriveOpen(const char *drive_path, struct drive *drive, int mode,
63               uint64_t drive_size);
64 int DriveClose(struct drive *drive, int update_as_needed);
65 int CheckValid(const struct drive *drive);
66 
67 /* Loads sectors from 'drive'.
68  *
69  *   drive -- open drive.
70  *   buf -- pointer to buffer of at least (sector_bytes * sector_count) size
71  *   sector -- offset of starting sector (in sectors)
72  *   sector_bytes -- bytes per sector
73  *   sector_count -- number of sectors to load
74  *
75  * Returns CGPT_OK for successful. Aborts if any error occurs.
76  */
77 int Load(struct drive *drive, uint8_t *buf,
78                 const uint64_t sector,
79                 const uint64_t sector_bytes,
80                 const uint64_t sector_count);
81 
82 /* Saves sectors to 'drive'.
83  *
84  *   drive -- open drive
85  *   buf -- pointer to buffer
86  *   sector -- starting sector offset
87  *   sector_bytes -- bytes per sector
88  *   sector_count -- number of sector to save
89  *
90  * Returns CGPT_OK for successful, CGPT_FAILED for failed.
91  */
92 int Save(struct drive *drive, const uint8_t *buf,
93                 const uint64_t sector,
94                 const uint64_t sector_bytes,
95                 const uint64_t sector_count);
96 
97 
98 /* Constant global type values to compare against */
99 extern const Guid guid_chromeos_firmware;
100 extern const Guid guid_chromeos_kernel;
101 extern const Guid guid_chromeos_rootfs;
102 extern const Guid guid_linux_data;
103 extern const Guid guid_chromeos_reserved;
104 extern const Guid guid_efi;
105 extern const Guid guid_unused;
106 
107 int ReadPMBR(struct drive *drive);
108 int WritePMBR(struct drive *drive);
109 
110 /* Convert possibly unterminated UTF16 string to UTF8.
111  * Caller must prepare enough space for UTF8, which could be up to
112  * twice the byte length of UTF16 string plus the terminating '\0'.
113  *
114  * Return: CGPT_OK --- all character are converted successfully.
115  *         CGPT_FAILED --- convert error, i.e. output buffer is too short.
116  */
117 int UTF16ToUTF8(const uint16_t *utf16, unsigned int maxinput,
118                 uint8_t *utf8, unsigned int maxoutput);
119 
120 /* Convert null-terminated UTF8 string to UTF16.
121  * Caller must prepare enough space for UTF16, which is the byte length of UTF8
122  * plus the terminating 0x0000.
123  *
124  * Return: CGPT_OK --- all character are converted successfully.
125  *         CGPT_FAILED --- convert error, i.e. output buffer is too short.
126  */
127 int UTF8ToUTF16(const uint8_t *utf8, uint16_t *utf16, unsigned int maxoutput);
128 
129 /* Helper functions for supported GPT types. */
130 int ResolveType(const Guid *type, char *buf);
131 int SupportedType(const char *name, Guid *type);
132 void PrintTypes(void);
133 void EntryDetails(GptEntry *entry, uint32_t index, int raw);
134 
135 uint32_t GetNumberOfEntries(const struct drive *drive);
136 GptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index);
137 
138 void SetRequired(struct drive *drive, int secondary, uint32_t entry_index,
139                  int required);
140 int GetRequired(struct drive *drive, int secondary, uint32_t entry_index);
141 void SetLegacyBoot(struct drive *drive, int secondary, uint32_t entry_index,
142                    int legacy_boot);
143 int GetLegacyBoot(struct drive *drive, int secondary, uint32_t entry_index);
144 void SetPriority(struct drive *drive, int secondary, uint32_t entry_index,
145                  int priority);
146 int GetPriority(struct drive *drive, int secondary, uint32_t entry_index);
147 void SetTries(struct drive *drive, int secondary, uint32_t entry_index,
148               int tries);
149 int GetTries(struct drive *drive, int secondary, uint32_t entry_index);
150 void SetSuccessful(struct drive *drive, int secondary, uint32_t entry_index,
151                    int success);
152 int GetSuccessful(struct drive *drive, int secondary, uint32_t entry_index);
153 void SetErrorCounter(struct drive *drive, int secondary, uint32_t entry_index,
154                      int error_counter);
155 int GetErrorCounter(struct drive *drive, int secondary, uint32_t entry_index);
156 
157 void SetRaw(struct drive *drive, int secondary, uint32_t entry_index,
158            uint32_t raw);
159 
160 void UpdateAllEntries(struct drive *drive);
161 
162 uint8_t RepairHeader(GptData *gpt, const uint32_t valid_headers);
163 uint8_t RepairEntries(GptData *gpt, const uint32_t valid_entries);
164 void UpdateCrc(GptData *gpt);
165 int IsSynonymous(const GptHeader* a, const GptHeader* b);
166 
167 int IsUnused(struct drive *drive, int secondary, uint32_t index);
168 int IsKernel(struct drive *drive, int secondary, uint32_t index);
169 
170 // Optional. Applications that need this must provide an implementation.
171 //
172 // Explanation:
173 //   Some external utilities need to manipulate the GPT, but don't create new
174 //   partitions from scratch. The cgpt executable uses libuuid to provide this
175 //   functionality, but we don't want to have to build or install a separate
176 //   instance of that library just for the 32-bit static post-install tool,
177 //   which doesn't need this function.
178 int GenerateGuid(Guid *newguid);
179 
180 // For usage and error messages.
181 void Error(const char *format, ...);
182 void Warning(const char *format, ...);
183 
184 // Command functions.
185 int check_int_parse(char option, const char *buf);
186 int check_int_limit(char option, int val, int low, int high);
187 int cmd_show(int argc, char *argv[]);
188 int cmd_repair(int argc, char *argv[]);
189 int cmd_create(int argc, char *argv[]);
190 int cmd_add(int argc, char *argv[]);
191 int cmd_boot(int argc, char *argv[]);
192 int cmd_find(int argc, char *argv[]);
193 int cmd_edit(int argc, char *argv[]);
194 int cmd_prioritize(int argc, char *argv[]);
195 int cmd_legacy(int argc, char *argv[]);
196 
197 #define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0]))
198 const char *GptError(int errnum);
199 
200 // Size in chars of the GPT Entry's PartitionName field
201 #define GPT_PARTNAME_LEN 72
202 
203 /* The standard "assert" macro goes away when NDEBUG is defined. This doesn't.
204  */
205 #define require(A) do { \
206   if (!(A)) { \
207     fprintf(stderr, "condition (%s) failed at %s:%d\n", \
208             #A, __FILE__, __LINE__); \
209     exit(1); } \
210   } while (0)
211 
212 #endif  /* VBOOT_REFERENCE_CGPT_H_ */
213