Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F135202949
D10591.id27992.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D10591.id27992.diff
View Options
Index: sys/boot/i386/zfsboot/zfsboot.c
===================================================================
--- sys/boot/i386/zfsboot/zfsboot.c
+++ sys/boot/i386/zfsboot/zfsboot.c
@@ -39,6 +39,7 @@
#include "lib.h"
#include "rbx.h"
#include "drv.h"
+#include "edd.h"
#include "util.h"
#include "cons.h"
#include "bootargs.h"
@@ -125,6 +126,7 @@
static void bios_getmem(void);
void *malloc(size_t n);
void free(void *ptr);
+int main(void);
void *
malloc(size_t n)
@@ -469,6 +471,56 @@
}
/*
+ * 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.
+ * Note we do not really want to touch drv.c because that code is shared
+ * with boot2 and we can not afford to grow that code.
+ */
+static uint64_t
+drvsize_ext(struct dsk *dskp)
+{
+ uint64_t size, tmp;
+ int cyl, hds, sec;
+
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x800;
+ v86.edx = dskp->drive;
+ v86int();
+
+ /* Don't error out if we get bad sector number, try EDD as well */
+ if (V86_CY(v86.efl) || /* carry set */
+ (v86.edx & 0xff) <= (unsigned)(dskp->drive & 0x7f)) /* unit # bad */
+ return (0);
+
+ cyl = ((v86.ecx & 0xc0) << 2) + ((v86.ecx & 0xff00) >> 8) + 1;
+ /* Convert max head # -> # of heads */
+ hds = ((v86.edx & 0xff00) >> 8) + 1;
+ sec = v86.ecx & 0x3f;
+
+ size = (uint64_t)cyl * hds * sec;
+
+ /* Determine if we can use EDD with this device. */
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x4100;
+ v86.edx = dskp->drive;
+ v86.ebx = 0x55aa;
+ v86int();
+ if (V86_CY(v86.efl) || /* carry set */
+ (v86.ebx & 0xffff) != 0xaa55 || /* signature */
+ (v86.ecx & EDD_INTERFACE_FIXED_DISK) == 0)
+ return (size);
+
+ tmp = drvsize(dskp);
+ if (tmp > size)
+ size = tmp;
+
+ return (size);
+}
+
+/*
* The "layered" ioctl to read disk/partition size. Unfortunately
* the zfsboot case is hardest, because we do not have full software
* stack available, so we need to do some manual work here.
@@ -480,7 +532,7 @@
uint64_t size = dskp->size;
if (dskp->start == 0)
- size = drvsize(dskp);
+ size = drvsize_ext(dskp);
return (size * DEV_BSIZE);
}
@@ -515,7 +567,7 @@
* out the partition table and probe each slice/partition
* in turn for a vdev or GELI encrypted vdev.
*/
- elba = drvsize(dsk);
+ elba = drvsize_ext(dsk);
if (elba > 0) {
elba--;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 8, 11:18 AM (9 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25036512
Default Alt Text
D10591.id27992.diff (2 KB)
Attached To
Mode
D10591: zfsboot: drvsize() may be unusable on some systems
Attached
Detach File
Event Timeline
Log In to Comment