-/* $OpenBSD: cmd.c,v 1.133 2021/07/19 19:23:50 krw Exp $ */
+/* $OpenBSD: cmd.c,v 1.134 2021/07/21 12:22:54 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
MBR_parse(&dos_mbr, mbr->mbr_lba_self, mbr->mbr_lba_firstembr, mbr);
if (dogpt) {
- MBR_init_GPT(mbr);
GPT_init(GHANDGP);
GPT_print("s", TERSE);
} else {
int
Xprint(char *args, struct mbr *mbr)
{
- int efi;
-
- efi = MBR_protective_mbr(mbr);
- if (efi != -1 && letoh64(gh.gh_sig) == GPTSIGNATURE)
+ if (letoh64(gh.gh_sig) == GPTSIGNATURE)
GPT_print(args, VERBOSE);
else
MBR_print(mbr, args);
int
Xwrite(char *args, struct mbr *mbr)
{
- int efi, i, n;
+ int i, n;
for (i = 0, n = 0; i < NDOSPART; i++)
if (mbr->mbr_prt[i].prt_id == 0xA6)
return CMD_CONT;
}
- printf("Writing MBR at offset %lld.\n", (long long)mbr->mbr_lba_self);
- if (MBR_write(mbr) == -1) {
- warn("error writing MBR");
- return CMD_CONT;
- }
-
if (letoh64(gh.gh_sig) == GPTSIGNATURE) {
printf("Writing GPT.\n");
- efi = MBR_protective_mbr(mbr);
- if (efi == -1 || GPT_write() == -1) {
+ if (GPT_write() == -1) {
warn("error writing GPT");
return CMD_CONT;
}
} else {
+ printf("Writing MBR at offset %lld.\n", (long long)mbr->mbr_lba_self);
+ if (MBR_write(mbr) == -1) {
+ warn("error writing MBR");
+ return CMD_CONT;
+ }
GPT_zap_headers();
}
-/* $OpenBSD: fdisk.c,v 1.127 2021/07/19 19:46:20 krw Exp $ */
+/* $OpenBSD: fdisk.c,v 1.128 2021/07/21 12:22:54 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
err(1, "pledge");
get_default_mbr(mbrfile, &initial_mbr);
- error = MBR_read(0, 0, &mbr);
- if (error)
- errx(1, "Can't read MBR!");
query = NULL;
if (A_flag) {
if (GPT_read(ANYGPT))
errx(1, "-A requires a valid GPT");
else {
- initial_mbr = mbr; /* Keep current MBR. */
GPT_init(GPONLY);
query = "Do you wish to write new GPT?";
}
} else if (i_flag) {
if (g_flag) {
- MBR_init_GPT(&initial_mbr);
GPT_init(GHANDGP);
query = "Do you wish to write new GPT?";
} else {
"partition table?";
}
} else if (u_flag) {
+ error = MBR_read(0, 0, &mbr);
+ if (error)
+ errx(1, "Can't read MBR!");
memcpy(initial_mbr.mbr_prt, mbr.mbr_prt,
sizeof(initial_mbr.mbr_prt));
query = "Do you wish to write new MBR?";
-/* $OpenBSD: gpt.c,v 1.46 2021/07/18 15:28:37 krw Exp $ */
+/* $OpenBSD: gpt.c,v 1.47 2021/07/21 12:22:54 krw Exp $ */
/*
* Copyright (c) 2015 Markus Muller <mmu@grummel.net>
* Copyright (c) 2015 Kenneth R Westerback <krw@openbsd.org>
#include <errno.h>
#include <stdio.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define DPRINTF(x...)
#endif
+struct mbr gmbr;
struct gpt_header gh;
struct gpt_partition gp[NGPTPARTITIONS];
int init_gh(void);
int init_gp(const int);
uint32_t crc32(const u_char *, const uint32_t);
+int protective_mbr(const struct mbr *);
+int gpt_chk_mbr(struct dos_partition *, uint64_t);
+
+/*
+ * Return the index into dp[] of the EFI GPT (0xEE) partition, or -1 if no such
+ * partition exists.
+ *
+ * Taken from kern/subr_disk.c.
+ *
+ */
+int
+gpt_chk_mbr(struct dos_partition *dp, u_int64_t dsize)
+{
+ struct dos_partition *dp2;
+ int efi, eficnt, found, i;
+ uint32_t psize;
+
+ found = efi = eficnt = 0;
+ for (dp2 = dp, i = 0; i < NDOSPART; i++, dp2++) {
+ if (dp2->dp_typ == DOSPTYP_UNUSED)
+ continue;
+ found++;
+ if (dp2->dp_typ != DOSPTYP_EFI)
+ continue;
+ if (letoh32(dp2->dp_start) != GPTSECTOR)
+ continue;
+ psize = letoh32(dp2->dp_size);
+ if (psize <= (dsize - GPTSECTOR) || psize == UINT32_MAX) {
+ efi = i;
+ eficnt++;
+ }
+ }
+ if (found == 1 && eficnt == 1)
+ return efi;
+
+ return -1;
+}
+
+int
+protective_mbr(const struct mbr *mbr)
+{
+ struct dos_partition dp[NDOSPART], dos_partition;
+ int i;
+
+ if (mbr->mbr_lba_self != 0)
+ return -1;
+
+ for (i = 0; i < NDOSPART; i++) {
+ PRT_make(&mbr->mbr_prt[i], mbr->mbr_lba_self, mbr->mbr_lba_firstembr,
+ &dos_partition);
+ memcpy(&dp[i], &dos_partition, sizeof(dp[i]));
+ }
+
+ return gpt_chk_mbr(dp, DL_GETDSIZE(&dl));
+}
int
get_header(const uint64_t sector)
int
GPT_read(const int which)
{
- struct mbr mbr;
int error;
- error = MBR_read(0, 0, &mbr);
+ error = MBR_read(0, 0, &gmbr);
if (error == 0)
- error = MBR_protective_mbr(&mbr);
+ error = protective_mbr(&gmbr);
if (error)
goto done;
done:
if (error != 0) {
/* No valid GPT found. Zap any artifacts. */
+ memset(&gmbr, 0, sizeof(gmbr));
memset(&gh, 0, sizeof(gh));
memset(&gp, 0, sizeof(gp));
}
memcpy(&oldgh, &gh, sizeof(oldgh));
memset(&gh, 0, sizeof(gh));
+ memset(&gmbr, 0, sizeof(gmbr));
+
+ /* XXX Do we need the boot code? UEFI spec & Apple says no. */
+ memcpy(gmbr.mbr_code, initial_mbr.mbr_code, sizeof(gmbr.mbr_code));
+ gmbr.mbr_prt[0].prt_id = DOSPTYP_EFI;
+ gmbr.mbr_prt[0].prt_bs = 1;
+ gmbr.mbr_prt[0].prt_ns = UINT32_MAX;
+ PRT_fix_CHS(&gmbr.mbr_prt[0]);
+ gmbr.mbr_signature = DOSMBR_SIGNATURE;
needed = sizeof(gp) / secsize + 2;
const int secsize = unit_types[SECTORS].ut_conversion;
uint64_t altgh, altgp, prigh, prigp, gpbytes;
+ MBR_write(&gmbr);
+
/*
* XXX Assume size of gp is multiple of sector size.
*/
-/* $OpenBSD: gpt.h,v 1.17 2021/07/18 15:28:37 krw Exp $ */
+/* $OpenBSD: gpt.h,v 1.18 2021/07/21 12:22:54 krw Exp $ */
/*
* Copyright (c) 2015 Markus Muller <mmu@grummel.net>
* Copyright (c) 2015 Kenneth R Westerback <krw@openbsd.org>
void GPT_print_part(const int, const char *, const int);
void GPT_print_parthdr(const int);
+extern struct mbr gmbr;
extern struct gpt_header gh;
extern struct gpt_partition gp[NGPTPARTITIONS];
-/* $OpenBSD: mbr.c,v 1.93 2021/07/19 23:24:54 krw Exp $ */
+/* $OpenBSD: mbr.c,v 1.94 2021/07/21 12:22:54 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
struct mbr initial_mbr;
-static int gpt_chk_mbr(struct dos_partition *, uint64_t);
-
-int
-MBR_protective_mbr(const struct mbr *mbr)
-{
- struct dos_partition dp[NDOSPART], dos_partition;
- int i;
-
- if (mbr->mbr_lba_self != 0)
- return -1;
-
- for (i = 0; i < NDOSPART; i++) {
- PRT_make(&mbr->mbr_prt[i], mbr->mbr_lba_self, mbr->mbr_lba_firstembr,
- &dos_partition);
- memcpy(&dp[i], &dos_partition, sizeof(dp[i]));
- }
-
- return gpt_chk_mbr(dp, DL_GETDSIZE(&dl));
-}
-
-void
-MBR_init_GPT(struct mbr *mbr)
-{
- memset(&mbr->mbr_prt, 0, sizeof(mbr->mbr_prt));
-
- /* Use whole disk, starting after MBR.
- *
- * Always set the partition size to UINT32_MAX (as MS does). EFI
- * firmware has been encountered that lies in unpredictable ways
- * about the size of the disk, thus making it impossible to boot
- * such devices.
- */
- mbr->mbr_prt[0].prt_id = DOSPTYP_EFI;
- mbr->mbr_prt[0].prt_bs = 1;
- mbr->mbr_prt[0].prt_ns = UINT32_MAX;
-
- /* Fix up start/length fields. */
- PRT_fix_CHS(&mbr->mbr_prt[0]);
-}
-
void
MBR_init(struct mbr *mbr)
{
uint64_t adj;
daddr_t daddr;
+ memset(&gmbr, 0, sizeof(gmbr));
memset(&gh, 0, sizeof(gh));
memset(&gp, 0, sizeof(gp));
return 0;
}
-
-/*
- * Return the index into dp[] of the EFI GPT (0xEE) partition, or -1 if no such
- * partition exists.
- *
- * Taken from kern/subr_disk.c.
- *
- */
-int
-gpt_chk_mbr(struct dos_partition *dp, u_int64_t dsize)
-{
- struct dos_partition *dp2;
- int efi, eficnt, found, i;
- uint32_t psize;
-
- found = efi = eficnt = 0;
- for (dp2 = dp, i = 0; i < NDOSPART; i++, dp2++) {
- if (dp2->dp_typ == DOSPTYP_UNUSED)
- continue;
- found++;
- if (dp2->dp_typ != DOSPTYP_EFI)
- continue;
- if (letoh32(dp2->dp_start) != GPTSECTOR)
- continue;
- psize = letoh32(dp2->dp_size);
- if (psize <= (dsize - GPTSECTOR) || psize == UINT32_MAX) {
- efi = i;
- eficnt++;
- }
- }
- if (found == 1 && eficnt == 1)
- return efi;
-
- return -1;
-}
-/* $OpenBSD: mbr.h,v 1.39 2021/07/19 19:30:35 krw Exp $ */
+/* $OpenBSD: mbr.h,v 1.40 2021/07/21 12:22:54 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
const uint64_t, struct mbr *);
void MBR_make(const struct mbr *, struct dos_mbr *);
void MBR_init(struct mbr *);
-void MBR_init_GPT(struct mbr *);
int MBR_read(const uint64_t, const uint64_t, struct mbr *);
int MBR_write(const struct mbr *);
-int MBR_protective_mbr(const struct mbr *);
#endif /* _MBR_H */
-/* $OpenBSD: user.c,v 1.66 2021/07/19 23:24:54 krw Exp $ */
+/* $OpenBSD: user.c,v 1.67 2021/07/21 12:22:54 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
{
struct mbr mbr;
char *cmd, *args;
- int i, st, efi, error;
+ int i, st, error;
static int editlevel;
/* One level deeper */