summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2023-05-21 17:29:34 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2023-05-21 17:29:34 +0000
commit782effe6b7240dfb2d2858e647caeac58399df6b (patch)
treedb0874af8d68e38356043d34b6fce1ed6559b487 /sbin
parent12d50c5d63fa279e4b56e78135a4e27545ee3526 (diff)
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!
Diffstat (limited to 'sbin')
-rw-r--r--sbin/fdisk/part.c48
-rw-r--r--sbin/fdisk/part.h8
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 *);