From 81000dd00128ef90469a32a272e81b9b710e5c82 Mon Sep 17 00:00:00 2001 From: Kenneth R Westerback Date: Fri, 11 Mar 2022 22:29:56 +0000 Subject: Simple hack to preserve the EFI System partition when auto-allocating the space on a disk whose GPT contains any of the magic Apple partitions. One step towards saving the firmware files on Apple M1 machines when installing OpenBSD. Tested & ok kettenis@ --- sbin/fdisk/fdisk.8 | 17 +++++++++++++++-- sbin/fdisk/fdisk.c | 8 +++++--- sbin/fdisk/gpt.c | 35 ++++++++++++++++++++++++++++++++--- sbin/fdisk/part.c | 36 ++++++++++++++++++++++++++++++------ 4 files changed, 82 insertions(+), 14 deletions(-) (limited to 'sbin/fdisk') diff --git a/sbin/fdisk/fdisk.8 b/sbin/fdisk/fdisk.8 index b3ca9c5ec01..11083f06a55 100644 --- a/sbin/fdisk/fdisk.8 +++ b/sbin/fdisk/fdisk.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: fdisk.8,v 1.109 2022/02/03 13:24:04 visa Exp $ +.\" $OpenBSD: fdisk.8,v 1.110 2022/03/11 22:29:55 krw Exp $ .\" .\" .\" Copyright (c) 1997 Tobias Weingartner @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: February 3 2022 $ +.Dd $Mdocdate: March 11 2022 $ .Dt FDISK 8 .Os .Sh NAME @@ -69,6 +69,19 @@ all existing partitions except the boot partitions .Sq HiFive FSBL and .Sq HiFive BBL . +.Pp +If one of +.Sq APFS ISC , +.Sq APFS , +.Sq APFS Recovry +is detected then any existing +.Sq EFI system +will also be preserved. +If the preserved +.Sq EFI system +partition has fewer blocks than the number requested with +.Fl b +the modification of the GPT is aborted. .It Fl b Ar blocks Ns Op @ Ns Ar offset Ns Op : Ns Ar type Configures a special boot partition of the specified number of blocks, offset and type. diff --git a/sbin/fdisk/fdisk.c b/sbin/fdisk/fdisk.c index 6df24f5a2d6..0a68b197e29 100644 --- a/sbin/fdisk/fdisk.c +++ b/sbin/fdisk/fdisk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fdisk.c,v 1.142 2022/02/04 23:32:17 krw Exp $ */ +/* $OpenBSD: fdisk.c,v 1.143 2022/03/11 22:29:55 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -167,14 +167,16 @@ main(int argc, char *argv[]) switch (init) { case INIT_GPT: - GPT_init(GHANDGP); + if (GPT_init(GHANDGP)) + errx(1, "-g could not create valid GPT"); if (ask_yn("Do you wish to write new GPT?")) Xwrite(NULL, &gmbr); break; case INIT_GPTPARTITIONS: if (GPT_read(ANYGPT)) errx(1, "-A requires a valid GPT"); - GPT_init(GPONLY); + if (GPT_init(GPONLY)) + errx(1, "-A could not create valid GPT"); if (ask_yn("Do you wish to write new GPT?")) Xwrite(NULL, &gmbr); break; diff --git a/sbin/fdisk/gpt.c b/sbin/fdisk/gpt.c index 1cb681ae6f0..61f2d6fd1ca 100644 --- a/sbin/fdisk/gpt.c +++ b/sbin/fdisk/gpt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gpt.c,v 1.58 2022/02/04 23:32:17 krw Exp $ */ +/* $OpenBSD: gpt.c,v 1.59 2022/03/11 22:29:55 krw Exp $ */ /* * Copyright (c) 2015 Markus Muller * Copyright (c) 2015 Kenneth R Westerback @@ -49,6 +49,7 @@ struct gpt_partition **sort_gpt(void); int lba_start_cmp(const void *e1, const void *e2); int lba_free(uint64_t *, uint64_t *); int add_partition(const uint8_t *, const char *, uint64_t); +int find_partition(const uint8_t *); int get_header(const uint64_t); int get_partition_table(void); int init_gh(void); @@ -413,6 +414,23 @@ GPT_print_part(const int n, const char *units, const int verbosity) } } +int +find_partition(const uint8_t *beuuid) +{ + struct uuid uuid, gp_type; + unsigned int pn, pncnt; + + uuid_dec_be(beuuid, &uuid); + uuid_enc_le(&gp_type, &uuid); + + pncnt = letoh32(gh.gh_part_num); + for (pn = 0; pn < pncnt; pn++) { + if (uuid_compare(&gp[pn].gp_type, &gp_type, NULL) == 0) + return pn; + } + return -1; +} + int add_partition(const uint8_t *beuuid, const char *name, uint64_t sectors) { @@ -529,6 +547,7 @@ init_gp(const int how) struct gpt_partition oldgp[NGPTPARTITIONS]; const uint8_t gpt_uuid_efi_system[] = GPT_UUID_EFI_SYSTEM; const uint8_t gpt_uuid_openbsd[] = GPT_UUID_OPENBSD; + uint64_t prt_ns; int pn, rslt; memcpy(&oldgp, &gp, sizeof(oldgp)); @@ -544,8 +563,18 @@ init_gp(const int how) rslt = 0; if (disk.dk_bootprt.prt_ns > 0) { - rslt = add_partition(gpt_uuid_efi_system, "EFI System Area", - disk.dk_bootprt.prt_ns); + pn = find_partition(gpt_uuid_efi_system); + if (pn == -1) { + rslt = add_partition(gpt_uuid_efi_system, + "EFI System Area", disk.dk_bootprt.prt_ns); + } else { + prt_ns = gp[pn].gp_lba_end - gp[pn].gp_lba_start + 1; + if (prt_ns < disk.dk_bootprt.prt_ns) { + printf("EFI System Area < %llu sectors\n", + disk.dk_bootprt.prt_ns); + rslt = -1; + } + } } if (rslt == 0) rslt = add_partition(gpt_uuid_openbsd, "OpenBSD Area", 0); diff --git a/sbin/fdisk/part.c b/sbin/fdisk/part.c index cc10cda98af..32348cc551b 100644 --- a/sbin/fdisk/part.c +++ b/sbin/fdisk/part.c @@ -1,4 +1,4 @@ -/* $OpenBSD: part.c,v 1.116 2022/02/04 23:32:17 krw Exp $ */ +/* $OpenBSD: part.c,v 1.117 2022/03/11 22:29:55 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -29,6 +29,7 @@ #include "part.h" #include "disk.h" #include "misc.h" +#include "gpt.h" const char *ascii_id(const int); @@ -183,26 +184,49 @@ const struct gpt_type gpt_types[] = { int PRT_protected_guid(const struct uuid *uuid) { - char *str = NULL; + const uint8_t gpt_uuid_efi_system[] = GPT_UUID_EFI_SYSTEM; + struct uuid uuid_efi_system; + char *efistr = NULL, *str = NULL; + char *typename; int rslt = 0; unsigned int i; uint32_t status; + uuid_dec_be(gpt_uuid_efi_system, &uuid_efi_system); + + uuid_to_string(&uuid_efi_system, &efistr, &status); + if (status != uuid_s_ok) { + rslt = -1; + goto done; + } uuid_to_string(uuid, &str, &status); if (status != uuid_s_ok) { rslt = -1; goto done; } - for(i = 0; i < nitems(gpt_types); i++) { - if (strncmp(str, gpt_types[i].gt_guid, UUID_STR_LEN) == 0) { - if (gpt_types[i].gt_protected) - rslt = -1; + if (strncmp(str, efistr, UUID_STR_LEN) == 0) { + /* Look for partitions indicating a need to preserve EFI Sys */ + for (i = 0; i < NGPTPARTITIONS; i++) { + typename = PRT_uuid_to_typename(&gp[i].gp_type); + if (strncmp(typename, "APFS ", 5)) + continue; + rslt = -1; break; } + } else { + for(i = 0; i < nitems(gpt_types); i++) { + if (strncmp(str, gpt_types[i].gt_guid, UUID_STR_LEN)) + continue; + if (gpt_types[i].gt_protected) { + rslt = -1; + break; + } + } } done: + free(efistr); free(str); return rslt; } -- cgit v1.2.3