/*-1* Copyright (c) 2012 Andriy Gapon <[email protected]>2* All rights reserved.3*4* Redistribution and use in source and binary forms are freely5* permitted provided that the above copyright notice and this6* paragraph and the following disclaimer are duplicated in all7* such forms.8*9* This software is provided "AS IS" and without any express or10* implied warranties, including, without limitation, the implied11* warranties of merchantability and fitness for a particular12* purpose.13*/1415#ifndef _BOOT_I386_ARGS_H_16#define _BOOT_I386_ARGS_H_1718#define KARGS_FLAGS_CD 0x0001 /* .bootdev is a bios CD dev */19#define KARGS_FLAGS_PXE 0x0002 /* .pxeinfo is valid */20#define KARGS_FLAGS_ZFS 0x0004 /* .zfspool is valid, EXTARG is zfs_boot_args */21#define KARGS_FLAGS_EXTARG 0x0008 /* variably sized extended argument */22#define KARGS_FLAGS_GELI 0x0010 /* EXTARG is geli_boot_args */2324#define BOOTARGS_SIZE 24 /* sizeof(struct bootargs) */25#define BA_BOOTFLAGS 8 /* offsetof(struct bootargs, bootflags) */26#define BA_BOOTINFO 20 /* offsetof(struct bootargs, bootinfo) */27#define BI_SIZE 48 /* offsetof(struct bootinfo, bi_size) */2829/*30* We reserve some space above BTX allocated stack for the arguments31* and certain data that could hang off them. Currently only struct bootinfo32* is supported in that category. The bootinfo is placed at the top33* of the arguments area and the actual arguments are placed at ARGOFF offset34* from the top and grow towards the top. Hopefully we have enough space35* for bootinfo and the arguments to not run into each other.36* Arguments area below ARGOFF is reserved for future use.37*/38#define ARGSPACE 0x1000 /* total size of the BTX args area */39#define ARGOFF 0x800 /* actual args offset within the args area */40#define ARGADJ (ARGSPACE - ARGOFF)4142#ifndef __ASSEMBLER__4344/*45* This struct describes the contents of the stack on entry to btxldr.S. This46* is the data that follows the return address, so it begins at 4(%esp). On47* the sending side, this data is passed as individual args to __exec(). On the48* receiving side, code in btxldr.S copies the data from the entry stack to a49* known fixed location in the new address space. Then, btxcsu.S sets the50* global variable __args to point to that known fixed location before calling51* main(), which casts __args to a struct bootargs pointer to access the data.52* The btxldr.S code is aware of KARGS_FLAGS_EXTARG, and if it's set, the extra53* args data is copied along with the other bootargs from the entry stack to the54* fixed location in the new address space.55*56* The bootinfo field is actually a pointer to a bootinfo struct that has been57* converted to uint32_t using VTOP(). On the receiving side it must be58* converted back to a pointer using PTOV(). Code in btxldr.S is aware of this59* field and if it's non-NULL it copies the data it points to into another known60* fixed location, and adjusts the bootinfo field to point to that new location.61*/62struct bootargs63{64uint32_t howto;65uint32_t bootdev;66uint32_t bootflags;67union {68struct {69uint32_t pxeinfo;70uint32_t reserved;71};72uint64_t zfspool;73};74uint32_t bootinfo;7576/*77* If KARGS_FLAGS_EXTARG is set in bootflags, then the above fields78* are followed by a uint32_t field that specifies a size of the79* extended arguments (including the size field).80*/81};8283#ifdef LOADER_GELI_SUPPORT84#include <crypto/intake.h>85#include "geliboot.h"86#endif8788/*89* geli_boot_data is embedded in geli_boot_args (passed from gptboot to loader)90* and in zfs_boot_args (passed from gptzfsboot to loader).91*/92struct geli_boot_data93{94union {95char gelipw[256];96struct {97char notapw; /*98* single null byte to stop keybuf99* being interpreted as a password100*/101uint32_t keybuf_sentinel;102#ifdef LOADER_GELI_SUPPORT103struct keybuf *keybuf;104#else105void *keybuf;106#endif107};108};109};110111#ifdef LOADER_GELI_SUPPORT112113static inline void114export_geli_boot_data(struct geli_boot_data *gbdata)115{116117gbdata->notapw = '\0';118gbdata->keybuf_sentinel = KEYBUF_SENTINEL;119gbdata->keybuf = malloc(sizeof(struct keybuf) +120(GELI_MAX_KEYS * sizeof(struct keybuf_ent)));121geli_export_key_buffer(gbdata->keybuf);122}123124static inline void125import_geli_boot_data(struct geli_boot_data *gbdata)126{127128if (gbdata->gelipw[0] != '\0') {129setenv("kern.geom.eli.passphrase", gbdata->gelipw, 1);130explicit_bzero(gbdata->gelipw, sizeof(gbdata->gelipw));131} else if (gbdata->keybuf_sentinel == KEYBUF_SENTINEL) {132geli_import_key_buffer(gbdata->keybuf);133}134}135#endif /* LOADER_GELI_SUPPORT */136137struct geli_boot_args138{139uint32_t size;140struct geli_boot_data gelidata;141};142143struct zfs_boot_args144{145uint32_t size;146uint32_t reserved;147uint64_t pool;148uint64_t root;149uint64_t primary_pool;150uint64_t primary_vdev;151struct geli_boot_data gelidata;152};153154#endif /*__ASSEMBLER__*/155156#endif /* !_BOOT_I386_ARGS_H_ */157158159