aboutsummaryrefslogtreecommitdiff
path: root/stand/i386/common
diff options
context:
space:
mode:
Diffstat (limited to 'stand/i386/common')
-rw-r--r--stand/i386/common/bootargs.h78
1 files changed, 72 insertions, 6 deletions
diff --git a/stand/i386/common/bootargs.h b/stand/i386/common/bootargs.h
index df558072f37f..5a6fef85a8c8 100644
--- a/stand/i386/common/bootargs.h
+++ b/stand/i386/common/bootargs.h
@@ -18,10 +18,11 @@
#ifndef _BOOT_I386_ARGS_H_
#define _BOOT_I386_ARGS_H_
-#define KARGS_FLAGS_CD 0x1
-#define KARGS_FLAGS_PXE 0x2
-#define KARGS_FLAGS_ZFS 0x4
-#define KARGS_FLAGS_EXTARG 0x8 /* variably sized extended argument */
+#define KARGS_FLAGS_CD 0x0001 /* .bootdev is a bios CD dev */
+#define KARGS_FLAGS_PXE 0x0002 /* .pxeinfo is valid */
+#define KARGS_FLAGS_ZFS 0x0004 /* .zfspool is valid, EXTARG is zfs_boot_args */
+#define KARGS_FLAGS_EXTARG 0x0008 /* variably sized extended argument */
+#define KARGS_FLAGS_GELI 0x0010 /* EXTARG is geli_boot_args */
#define BOOTARGS_SIZE 24 /* sizeof(struct bootargs) */
#define BA_BOOTFLAGS 8 /* offsetof(struct bootargs, bootflags) */
@@ -43,6 +44,24 @@
#ifndef __ASSEMBLER__
+/*
+ * This struct describes the contents of the stack on entry to btxldr.S. This
+ * is the data that follows the return address, so it begins at 4(%esp). On
+ * the sending side, this data is passed as individual args to __exec(). On the
+ * receiving side, code in btxldr.S copies the data from the entry stack to a
+ * known fixed location in the new address space. Then, btxcsu.S sets the
+ * global variable __args to point to that known fixed location before calling
+ * main(), which casts __args to a struct bootargs pointer to access the data.
+ * The btxldr.S code is aware of KARGS_FLAGS_EXTARG, and if it's set, the extra
+ * args data is copied along with the other bootargs from the entry stack to the
+ * fixed location in the new address space.
+ *
+ * The bootinfo field is actually a pointer to a bootinfo struct that has been
+ * converted to uint32_t using VTOP(). On the receiving side it must be
+ * converted back to a pointer using PTOV(). Code in btxldr.S is aware of this
+ * field and if it's non-NULL it copies the data it points to into another known
+ * fixed location, and adjusts the bootinfo field to point to that new location.
+ */
struct bootargs
{
uint32_t howto;
@@ -66,11 +85,15 @@ struct bootargs
#ifdef LOADER_GELI_SUPPORT
#include <crypto/intake.h>
+#include "geliboot.h"
#endif
-struct geli_boot_args
+/*
+ * geli_boot_data is embedded in geli_boot_args (passed from gptboot to loader)
+ * and in zfs_boot_args (passed from zfsboot and gptzfsboot to loader).
+ */
+struct geli_boot_data
{
- uint32_t size;
union {
char gelipw[256];
struct {
@@ -88,6 +111,49 @@ struct geli_boot_args
};
};
+#ifdef LOADER_GELI_SUPPORT
+
+static inline void
+export_geli_boot_data(struct geli_boot_data *gbdata)
+{
+
+ gbdata->notapw = '\0';
+ gbdata->keybuf_sentinel = KEYBUF_SENTINEL;
+ gbdata->keybuf = malloc(sizeof(struct keybuf) +
+ (GELI_MAX_KEYS * sizeof(struct keybuf_ent)));
+ geli_export_key_buffer(gbdata->keybuf);
+}
+
+static inline void
+import_geli_boot_data(struct geli_boot_data *gbdata)
+{
+
+ if (gbdata->gelipw[0] != '\0') {
+ setenv("kern.geom.eli.passphrase", gbdata->gelipw, 1);
+ explicit_bzero(gbdata->gelipw, sizeof(gbdata->gelipw));
+ } else if (gbdata->keybuf_sentinel == KEYBUF_SENTINEL) {
+ geli_import_key_buffer(gbdata->keybuf);
+ }
+}
+#endif /* LOADER_GELI_SUPPORT */
+
+struct geli_boot_args
+{
+ uint32_t size;
+ struct geli_boot_data gelidata;
+};
+
+struct zfs_boot_args
+{
+ uint32_t size;
+ uint32_t reserved;
+ uint64_t pool;
+ uint64_t root;
+ uint64_t primary_pool;
+ uint64_t primary_vdev;
+ struct geli_boot_data gelidata;
+};
+
#endif /*__ASSEMBLER__*/
#endif /* !_BOOT_I386_ARGS_H_ */