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