aboutsummaryrefslogtreecommitdiff
path: root/stand
diff options
context:
space:
mode:
authorToomas Soome <tsoome@FreeBSD.org>2019-04-30 17:45:22 +0000
committerToomas Soome <tsoome@FreeBSD.org>2019-04-30 17:45:22 +0000
commit3a1f80e2d770426ab1f121d9925244314c10d897 (patch)
treeff2eb08f31eb8f86a4d87319c8b5338aae1c617a /stand
parentbe1ef9be42309016259a0e72926123663346d505 (diff)
downloadsrc-3a1f80e2d770426ab1f121d9925244314c10d897.tar.gz
src-3a1f80e2d770426ab1f121d9925244314c10d897.zip
zfsboot: to detect disk size, use GPT information first
If we do have GPT on disk, read the disk size from it and do not call int13. Since int13 does report bogus informatiopn too often, rather trust the partition table. We are using the same strategy with loader. MFC after: 1 month
Notes
Notes: svn path=/head/; revision=346969
Diffstat (limited to 'stand')
-rw-r--r--stand/i386/zfsboot/zfsboot.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/stand/i386/zfsboot/zfsboot.c b/stand/i386/zfsboot/zfsboot.c
index fe3c5d1e6b07..076f96da05f8 100644
--- a/stand/i386/zfsboot/zfsboot.c
+++ b/stand/i386/zfsboot/zfsboot.c
@@ -460,6 +460,33 @@ copy_dsk(struct zfsdsk *zdsk)
}
/*
+ * Get disk size from GPT.
+ */
+static uint64_t
+drvsize_gpt(struct dsk *dskp)
+{
+#ifdef GPT
+ struct gpt_hdr hdr;
+ char *sec;
+
+ sec = dmadat->secbuf;
+ if (drvread(dskp, sec, 1, 1))
+ return (0);
+
+ memcpy(&hdr, sec, sizeof(hdr));
+ if (memcmp(hdr.hdr_sig, GPT_HDR_SIG, sizeof(hdr.hdr_sig)) != 0 ||
+ hdr.hdr_lba_self != 1 || hdr.hdr_revision < 0x00010000 ||
+ hdr.hdr_entsz < sizeof(struct gpt_ent) ||
+ DEV_BSIZE % hdr.hdr_entsz != 0) {
+ return (0);
+ }
+ return (hdr.hdr_lba_alt + 1);
+#else
+ return (0);
+#endif
+}
+
+/*
* Get disk size from eax=0x800 and 0x4800. We need to probe both
* because 0x4800 may not be available and we would like to get more
* or less correct disk size - if it is possible at all.
@@ -475,6 +502,11 @@ drvsize_ext(struct zfsdsk *zdsk)
dskp = &zdsk->dsk;
+ /* Try to read disk size from GPT */
+ size = drvsize_gpt(dskp);
+ if (size != 0)
+ return (size);
+
v86.ctl = V86_FLAGS;
v86.addr = 0x13;
v86.eax = 0x800;