From 2a661dcac5d8b6c609259338ed0c069264208082 Mon Sep 17 00:00:00 2001 From: krw Date: Sun, 21 May 2023 17:29:33 +0000 Subject: [PATCH] If an MBR partition start or end can be represented by CHS, set both CHS and LBA values in the MBR partition. Restores pre-7.0 initialization of MBR partition start/end, using slightly less opaque code that retains the slightly different initialization required by GPT protective MBR's. Fixes booting from disks >8G on systems where the BIOS uses CHS. Encountered by Paul de Weerd on his Alix.2 using BIOS 0.99. Much diagnosis and testing by Paul of various iterations. Thanks! --- sbin/fdisk/part.c | 48 +++++++++++++++++++++++++++-------------------- sbin/fdisk/part.h | 8 ++++---- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/sbin/fdisk/part.c b/sbin/fdisk/part.c index ba0b9d46f37..d925b703a56 100644 --- a/sbin/fdisk/part.c +++ b/sbin/fdisk/part.c @@ -1,4 +1,4 @@ -/* $OpenBSD: part.c,v 1.162 2023/05/17 12:59:37 krw Exp $ */ +/* $OpenBSD: part.c,v 1.163 2023/05/21 17:29:33 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -731,6 +731,8 @@ const struct menu_item menu_items[] = { { 0xFF, 0xFF, "Xenix BBT", NULL }, }; +void chs_to_dp(const unsigned char, const struct chs *, + uint8_t *, uint8_t *, uint8_t *); const struct gpt_type *find_gpt_type(const struct uuid *); const struct menu_item *find_gpt_menuitem(const struct gpt_type *); const char *find_gpt_desc(const struct gpt_type *); @@ -746,6 +748,26 @@ void print_menu(int (*)(const unsigned int), int nth_menu_item(int (*)(const unsigned int), const unsigned int, unsigned int); +void +chs_to_dp(const unsigned char prt_id, const struct chs *chs, uint8_t *dp_cyl, + uint8_t *dp_hd, uint8_t *dp_sect) +{ + uint64_t cyl = chs->chs_cyl; + uint32_t head = chs->chs_head; + uint32_t sect = chs->chs_sect; + + if (head > 254 || sect > 63 || cyl > 1023) { + /* Set max values to trigger LBA. */ + head = (prt_id == DOSPTYP_EFI) ? 255 : 254; + sect = 63; + cyl = 1023; + } + + *dp_hd = head & 0xFF; + *dp_sect = (sect & 0x3F) | ((cyl & 0x300) >> 2); + *dp_cyl = cyl & 0xFF; +} + const struct gpt_type * find_gpt_type(const struct uuid *uuid) { @@ -990,16 +1012,9 @@ PRT_prt_to_dp(const struct prt *prt, const uint64_t lba_self, else off = lba_self; - if (PRT_lba_to_chs(prt, &start, &end) == 0) { - dp->dp_shd = start.chs_head & 0xFF; - dp->dp_ssect = (start.chs_sect & 0x3F) | ((start.chs_cyl & 0x300) >> 2); - dp->dp_scyl = start.chs_cyl & 0xFF; - dp->dp_ehd = end.chs_head & 0xFF; - dp->dp_esect = (end.chs_sect & 0x3F) | ((end.chs_cyl & 0x300) >> 2); - dp->dp_ecyl = end.chs_cyl & 0xFF; - } else { - memset(dp, 0xFF, sizeof(*dp)); - } + PRT_lba_to_chs(prt, &start, &end); + chs_to_dp(prt->prt_id, &start, &dp->dp_scyl, &dp->dp_shd, &dp->dp_ssect); + chs_to_dp(prt->prt_id, &end, &dp->dp_ecyl, &dp->dp_ehd, &dp->dp_esect); dp->dp_flag = prt->prt_flag & 0xFF; dp->dp_typ = prt->prt_id & 0xFF; @@ -1052,7 +1067,7 @@ PRT_print_part(const int num, const struct prt *prt, const char *units) disk.dk_name); } -int +void PRT_lba_to_chs(const struct prt *prt, struct chs *start, struct chs *end) { uint64_t lba; @@ -1060,7 +1075,7 @@ PRT_lba_to_chs(const struct prt *prt, struct chs *start, struct chs *end) if (prt->prt_ns == 0 || prt->prt_id == DOSPTYP_UNUSED) { memset(start, 0, sizeof(*start)); memset(end, 0, sizeof(*end)); - return -1; + return; } /* @@ -1078,13 +1093,6 @@ PRT_lba_to_chs(const struct prt *prt, struct chs *start, struct chs *end) end->chs_cyl = lba / (disk.dk_sectors * disk.dk_heads); end->chs_head = (lba / disk.dk_sectors) % disk.dk_heads; end->chs_sect = (lba % disk.dk_sectors) + 1; - - if (start->chs_head > 255 || end->chs_head > 255 || - start->chs_sect > 63 || end->chs_sect > 63 || - start->chs_cyl > 1023 || end->chs_cyl > 1023) - return -1; - - return 0; } const char * diff --git a/sbin/fdisk/part.h b/sbin/fdisk/part.h index f4fb574de2f..b413e659c99 100644 --- a/sbin/fdisk/part.h +++ b/sbin/fdisk/part.h @@ -1,4 +1,4 @@ -/* $OpenBSD: part.h,v 1.46 2023/05/17 12:59:37 krw Exp $ */ +/* $OpenBSD: part.h,v 1.47 2023/05/21 17:29:33 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -33,12 +33,12 @@ void PRT_print_mbrmenu(char *, size_t); void PRT_print_gptmenu(char *, size_t); void PRT_dp_to_prt(const struct dos_partition *, const uint64_t, const uint64_t, struct prt *); -void PRT_prt_to_dp(const struct prt *,const uint64_t, const uint64_t, - struct dos_partition *); +void PRT_prt_to_dp(const struct prt *,const uint64_t, + const uint64_t, struct dos_partition *); void PRT_print_part(const int, const struct prt *, const char *); void PRT_print_parthdr(void); const char *PRT_uuid_to_desc(const struct uuid *); char *PRT_uuid_to_menudflt(const struct uuid *); const char *PRT_menuid_to_guid(const int); int PRT_protected_uuid(const struct uuid *); -int PRT_lba_to_chs(const struct prt*, struct chs *, struct chs*); +void PRT_lba_to_chs(const struct prt *, struct chs *, struct chs *); -- 2.20.1