diff options
Diffstat (limited to 'stand/i386/common')
-rw-r--r-- | stand/i386/common/bootargs.h | 78 |
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_ */ |