aboutsummaryrefslogtreecommitdiff
path: root/sys/boot/i386/loader
diff options
context:
space:
mode:
Diffstat (limited to 'sys/boot/i386/loader')
-rw-r--r--sys/boot/i386/loader/Makefile10
-rw-r--r--sys/boot/i386/loader/conf.c14
-rw-r--r--sys/boot/i386/loader/main.c51
3 files changed, 62 insertions, 13 deletions
diff --git a/sys/boot/i386/loader/Makefile b/sys/boot/i386/loader/Makefile
index df2ccc0f15ad..79aceca277c6 100644
--- a/sys/boot/i386/loader/Makefile
+++ b/sys/boot/i386/loader/Makefile
@@ -17,6 +17,12 @@ CFLAGS+= -DLOADER_FIREWIRE_SUPPORT
LIBFIREWIRE= ${.OBJDIR}/../libfirewire/libfirewire.a
.endif
+# Put LOADER_ZFS_SUPPORT=yes in /etc/make.conf for ZFS support
+.if defined(LOADER_ZFS_SUPPORT)
+CFLAGS+= -DLOADER_ZFS_SUPPORT
+LIBZFS= ${.OBJDIR}/../../zfs/libzfsboot.a
+.endif
+
# Enable PXE TFTP or NFS support, not both.
.if defined(LOADER_TFTP_SUPPORT)
CFLAGS+= -DLOADER_TFTP_SUPPORT
@@ -98,8 +104,8 @@ FILES+= loader.rc
# XXX crt0.o needs to be first for pxeboot(8) to work
OBJS= ${BTXCRT}
-DPADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBI386} ${LIBSTAND}
-LDADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBI386} -lstand
+DPADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFS} ${LIBI386} ${LIBSTAND}
+LDADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFS} ${LIBI386} -lstand
.include <bsd.prog.mk>
diff --git a/sys/boot/i386/loader/conf.c b/sys/boot/i386/loader/conf.c
index 245f960ed210..05c9a9e95f3c 100644
--- a/sys/boot/i386/loader/conf.c
+++ b/sys/boot/i386/loader/conf.c
@@ -50,6 +50,10 @@ __FBSDID("$FreeBSD$");
extern struct devsw fwohci;
#endif
+#if defined(LOADER_ZFS_SUPPORT)
+extern struct devsw zfs_dev;
+#endif
+
/* Exported for libstand */
struct devsw *devsw[] = {
&bioscd,
@@ -60,15 +64,25 @@ struct devsw *devsw[] = {
#if defined(LOADER_FIREWIRE_SUPPORT)
&fwohci,
#endif
+#if defined(LOADER_ZFS_SUPPORT)
+ &zfs_dev,
+#endif
NULL
};
+#if defined(LOADER_ZFS_SUPPORT)
+extern struct fs_ops zfs_fsops;
+#endif
+
struct fs_ops *file_system[] = {
&ufs_fsops,
&ext2fs_fsops,
&dosfs_fsops,
&cd9660_fsops,
&splitfs_fsops,
+#if defined(LOADER_ZFS_SUPPORT)
+ &zfs_fsops,
+#endif
#ifdef LOADER_GZIP_SUPPORT
&gzipfs_fsops,
#endif
diff --git a/sys/boot/i386/loader/main.c b/sys/boot/i386/loader/main.c
index 5b23670d12d0..cac28aef9763 100644
--- a/sys/boot/i386/loader/main.c
+++ b/sys/boot/i386/loader/main.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#define KARGS_FLAGS_CD 0x1
#define KARGS_FLAGS_PXE 0x2
+#define KARGS_FLAGS_ZFS 0x4
/* Arguments passed in from the boot1/boot2 loader */
static struct
@@ -51,8 +52,13 @@ static struct
u_int32_t howto;
u_int32_t bootdev;
u_int32_t bootflags;
- u_int32_t pxeinfo;
- u_int32_t res2;
+ union {
+ struct {
+ u_int32_t pxeinfo;
+ u_int32_t res2;
+ };
+ uint64_t zfspool;
+ };
u_int32_t bootinfo;
} *kargs;
@@ -96,7 +102,7 @@ main(void)
*/
bios_getmem();
-#if defined(LOADER_BZIP2_SUPPORT) || defined(LOADER_FIREWIRE_SUPPORT)
+#if defined(LOADER_BZIP2_SUPPORT) || defined(LOADER_FIREWIRE_SUPPORT) || defined(LOADER_ZFS_SUPPORT)
heap_top = PTOV(memtop_copyin);
memtop_copyin -= 0x300000;
heap_bottom = PTOV(memtop_copyin);
@@ -145,6 +151,14 @@ main(void)
bc_add(initial_bootdev);
}
+ archsw.arch_autoload = i386_autoload;
+ archsw.arch_getdev = i386_getdev;
+ archsw.arch_copyin = i386_copyin;
+ archsw.arch_copyout = i386_copyout;
+ archsw.arch_readin = i386_readin;
+ archsw.arch_isainb = isa_inb;
+ archsw.arch_isaoutb = isa_outb;
+
/*
* March through the device switch probing for things.
*/
@@ -172,14 +186,6 @@ main(void)
bios_getsmap();
- archsw.arch_autoload = i386_autoload;
- archsw.arch_getdev = i386_getdev;
- archsw.arch_copyin = i386_copyin;
- archsw.arch_copyout = i386_copyout;
- archsw.arch_readin = i386_readin;
- archsw.arch_isainb = isa_inb;
- archsw.arch_isaoutb = isa_outb;
-
interact(); /* doesn't return */
/* if we ever get here, it is an error */
@@ -252,6 +258,29 @@ extract_currdev(void)
i386_setcurrdev, env_nounset);
env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset,
env_nounset);
+
+#ifdef LOADER_ZFS_SUPPORT
+ /*
+ * If we were started from a ZFS-aware boot2, we can work out
+ * which ZFS pool we are booting from.
+ */
+ if (kargs->bootflags & KARGS_FLAGS_ZFS) {
+ /*
+ * Dig out the pool guid and convert it to a 'unit number'
+ */
+ uint64_t guid;
+ int unit;
+ char devname[32];
+ extern int zfs_guid_to_unit(uint64_t);
+
+ guid = kargs->zfspool;
+ unit = zfs_guid_to_unit(guid);
+ if (unit >= 0) {
+ sprintf(devname, "zfs%d", unit);
+ setenv("currdev", devname, 1);
+ }
+ }
+#endif
}
COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);