blob: 89c357e862a870bd7451e5e4ab148bb4e2f622c3 [file] [log] [blame]
Joel Kitching9adf2aa2019-08-20 17:43:50 +08001/* 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 */
Bill Richardsonf1372d92010-06-11 09:15:55 -07005
Joel Kitching9adf2aa2019-08-20 17:43:50 +08006#ifndef VBOOT_REFERENCE_CGPT_H_
7#define VBOOT_REFERENCE_CGPT_H_
Bill Richardsonf1372d92010-06-11 09:15:55 -07008
Bill Richardson23429d32012-04-30 11:33:13 -07009#include <fcntl.h>
Idwer Volleringb384db32021-05-10 21:15:45 +020010#if !defined(HAVE_MACOS) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
Bill Richardsonf1372d92010-06-11 09:15:55 -070011#include <features.h>
David Riley05987b12015-02-05 19:22:49 -080012#endif
Bill Richardsonf1372d92010-06-11 09:15:55 -070013#include <stdint.h>
Bill Richardsonc4e92af2010-10-12 07:33:15 -070014#include <stdio.h>
15#include <stdlib.h>
Bill Richardson4cb54972014-06-20 14:33:00 -070016#include "cgpt_endian.h"
Bill Richardsonf1372d92010-06-11 09:15:55 -070017#include "cgptlib.h"
Bill Richardson4cb54972014-06-20 14:33:00 -070018#include "gpt.h"
Bill Richardsonf1372d92010-06-11 09:15:55 -070019
Bill Richardsonf1372d92010-06-11 09:15:55 -070020struct 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
Bill Richardsonf1372d92010-06-11 09:15:55 -070033// 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
Bill Richardsonc4e92af2010-10-12 07:33:15 -070043void PMBRToStr(struct pmbr *pmbr, char *str, unsigned int buflen);
Bill Richardsonf1372d92010-06-11 09:15:55 -070044
45// Handle to the drive storing the GPT.
46struct drive {
Bill Richardsonf1372d92010-06-11 09:15:55 -070047 uint64_t size; /* total size (in bytes) */
48 GptData gpt;
49 struct pmbr pmbr;
Nam T. Nguyenab899592014-11-13 19:30:46 -080050 int fd; /* file descriptor */
Bill Richardsonf1372d92010-06-11 09:15:55 -070051};
52
Nam T. Nguyen6ee52d92014-10-24 13:20:39 -070053// Opens a block device or file, loads raw GPT data from it.
Nam T. Nguyenab899592014-11-13 19:30:46 -080054// '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.
Nam T. Nguyen6ee52d92014-10-24 13:20:39 -070059//
60// Returns CGPT_FAILED if any error happens.
Nam T. Nguyenab899592014-11-13 19:30:46 -080061// Returns CGPT_OK if success and information are stored in 'drive'. */
62int DriveOpen(const char *drive_path, struct drive *drive, int mode,
63 uint64_t drive_size);
Bill Richardsonf1372d92010-06-11 09:15:55 -070064int DriveClose(struct drive *drive, int update_as_needed);
65int CheckValid(const struct drive *drive);
66
Albert Chaulk534723a2013-03-20 14:46:50 -070067/* Loads sectors from 'drive'.
Albert Chaulk534723a2013-03-20 14:46:50 -070068 *
69 * drive -- open drive.
Julius Werner8e8f4b92019-10-28 16:26:18 -070070 * buf -- pointer to buffer of at least (sector_bytes * sector_count) size
Albert Chaulk534723a2013-03-20 14:46:50 -070071 * 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 */
Julius Werner8e8f4b92019-10-28 16:26:18 -070077int Load(struct drive *drive, uint8_t *buf,
Albert Chaulk534723a2013-03-20 14:46:50 -070078 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 */
92int 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
Bill Richardson3430b322010-11-29 14:24:51 -080098/* Constant global type values to compare against */
Gabe Black93cf15e2011-07-07 16:00:00 -070099extern const Guid guid_chromeos_firmware;
Bill Richardson3430b322010-11-29 14:24:51 -0800100extern const Guid guid_chromeos_kernel;
101extern const Guid guid_chromeos_rootfs;
102extern const Guid guid_linux_data;
103extern const Guid guid_chromeos_reserved;
104extern const Guid guid_efi;
105extern const Guid guid_unused;
Bill Richardsonf1372d92010-06-11 09:15:55 -0700106
107int ReadPMBR(struct drive *drive);
108int WritePMBR(struct drive *drive);
109
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700110/* Convert possibly unterminated UTF16 string to UTF8.
111 * Caller must prepare enough space for UTF8, which could be up to
Louis Yung-Chieh Lo500b3c22010-11-22 18:19:11 +0800112 * 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.
Bill Richardsonf1372d92010-06-11 09:15:55 -0700116 */
Louis Yung-Chieh Lo500b3c22010-11-22 18:19:11 +0800117int UTF16ToUTF8(const uint16_t *utf16, unsigned int maxinput,
118 uint8_t *utf8, unsigned int maxoutput);
119
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700120/* Convert null-terminated UTF8 string to UTF16.
Louis Yung-Chieh Lo500b3c22010-11-22 18:19:11 +0800121 * 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.
Bill Richardsonf1372d92010-06-11 09:15:55 -0700126 */
Louis Yung-Chieh Lo500b3c22010-11-22 18:19:11 +0800127int UTF8ToUTF16(const uint8_t *utf8, uint16_t *utf16, unsigned int maxoutput);
Bill Richardsonf1372d92010-06-11 09:15:55 -0700128
129/* Helper functions for supported GPT types. */
130int ResolveType(const Guid *type, char *buf);
131int SupportedType(const char *name, Guid *type);
132void PrintTypes(void);
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700133void EntryDetails(GptEntry *entry, uint32_t index, int raw);
Bill Richardsonf1372d92010-06-11 09:15:55 -0700134
Albert Chaulkfa6b35c2013-03-26 13:43:02 -0700135uint32_t GetNumberOfEntries(const struct drive *drive);
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700136GptEntry *GetEntry(GptData *gpt, int secondary, uint32_t entry_index);
Albert Chaulkb334e652013-03-28 15:25:33 -0700137
Ben Chana4a8c022018-01-31 11:39:14 -0800138void SetRequired(struct drive *drive, int secondary, uint32_t entry_index,
139 int required);
140int GetRequired(struct drive *drive, int secondary, uint32_t entry_index);
Mike Frysinger6c18af52016-09-07 16:45:48 -0400141void SetLegacyBoot(struct drive *drive, int secondary, uint32_t entry_index,
142 int legacy_boot);
143int GetLegacyBoot(struct drive *drive, int secondary, uint32_t entry_index);
Albert Chaulkfa6b35c2013-03-26 13:43:02 -0700144void SetPriority(struct drive *drive, int secondary, uint32_t entry_index,
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700145 int priority);
Albert Chaulkfa6b35c2013-03-26 13:43:02 -0700146int GetPriority(struct drive *drive, int secondary, uint32_t entry_index);
147void SetTries(struct drive *drive, int secondary, uint32_t entry_index,
148 int tries);
149int GetTries(struct drive *drive, int secondary, uint32_t entry_index);
150void SetSuccessful(struct drive *drive, int secondary, uint32_t entry_index,
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700151 int success);
Albert Chaulkfa6b35c2013-03-26 13:43:02 -0700152int GetSuccessful(struct drive *drive, int secondary, uint32_t entry_index);
153
154void SetRaw(struct drive *drive, int secondary, uint32_t entry_index,
155 uint32_t raw);
156
157void UpdateAllEntries(struct drive *drive);
Bill Richardsonf1372d92010-06-11 09:15:55 -0700158
159uint8_t RepairHeader(GptData *gpt, const uint32_t valid_headers);
160uint8_t RepairEntries(GptData *gpt, const uint32_t valid_entries);
161void UpdateCrc(GptData *gpt);
162int IsSynonymous(const GptHeader* a, const GptHeader* b);
163
Albert Chaulkfa6b35c2013-03-26 13:43:02 -0700164int IsUnused(struct drive *drive, int secondary, uint32_t index);
165int IsKernel(struct drive *drive, int secondary, uint32_t index);
166
Bill Richardson4cb54972014-06-20 14:33:00 -0700167// Optional. Applications that need this must provide an implementation.
168//
169// Explanation:
170// Some external utilities need to manipulate the GPT, but don't create new
171// partitions from scratch. The cgpt executable uses libuuid to provide this
172// functionality, but we don't want to have to build or install a separate
173// instance of that library just for the 32-bit static post-install tool,
174// which doesn't need this function.
175int GenerateGuid(Guid *newguid);
Bill Richardsonf1372d92010-06-11 09:15:55 -0700176
Bill Richardson4cb54972014-06-20 14:33:00 -0700177// For usage and error messages.
178void Error(const char *format, ...);
Nam T. Nguyen6ee52d92014-10-24 13:20:39 -0700179void Warning(const char *format, ...);
Bill Richardsonf1372d92010-06-11 09:15:55 -0700180
181// Command functions.
Mike Frysingerc60eb7e2016-09-07 20:23:46 -0400182int check_int_parse(char option, const char *buf);
183int check_int_limit(char option, int val, int low, int high);
Bill Richardsonf1372d92010-06-11 09:15:55 -0700184int cmd_show(int argc, char *argv[]);
185int cmd_repair(int argc, char *argv[]);
186int cmd_create(int argc, char *argv[]);
187int cmd_add(int argc, char *argv[]);
188int cmd_boot(int argc, char *argv[]);
Bill Richardson4a209312010-07-02 11:34:38 -0700189int cmd_find(int argc, char *argv[]);
Matt Delco0c274a92018-08-02 11:50:06 -0700190int cmd_edit(int argc, char *argv[]);
Bill Richardson3430b322010-11-29 14:24:51 -0800191int cmd_prioritize(int argc, char *argv[]);
Stefan Reinauerb7b865c2012-08-23 15:06:25 -0700192int cmd_legacy(int argc, char *argv[]);
Bill Richardsonf1372d92010-06-11 09:15:55 -0700193
194#define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0]))
195const char *GptError(int errnum);
196
Bill Richardsonc4e92af2010-10-12 07:33:15 -0700197// Size in chars of the GPT Entry's PartitionName field
198#define GPT_PARTNAME_LEN 72
199
200/* The standard "assert" macro goes away when NDEBUG is defined. This doesn't.
201 */
202#define require(A) do { \
203 if (!(A)) { \
204 fprintf(stderr, "condition (%s) failed at %s:%d\n", \
205 #A, __FILE__, __LINE__); \
206 exit(1); } \
207 } while (0)
Bill Richardsonf1372d92010-06-11 09:15:55 -0700208
Joel Kitching9adf2aa2019-08-20 17:43:50 +0800209#endif /* VBOOT_REFERENCE_CGPT_H_ */