1235154Savg/*- 2235154Savg * Copyright (c) 2012 Andriy Gapon <avg@FreeBSD.org> 3235154Savg * All rights reserved. 4235154Savg * 5235154Savg * Redistribution and use in source and binary forms are freely 6235154Savg * permitted provided that the above copyright notice and this 7235154Savg * paragraph and the following disclaimer are duplicated in all 8235154Savg * such forms. 9235154Savg * 10235154Savg * This software is provided "AS IS" and without any express or 11235154Savg * implied warranties, including, without limitation, the implied 12235154Savg * warranties of merchantability and fitness for a particular 13235154Savg * purpose. 14235154Savg * 15235154Savg * $FreeBSD: stable/11/stand/i386/common/bootargs.h 344399 2019-02-20 23:55:35Z kevans $ 16235154Savg */ 17235154Savg 18235154Savg#ifndef _BOOT_I386_ARGS_H_ 19235154Savg#define _BOOT_I386_ARGS_H_ 20235154Savg 21344399Skevans#define KARGS_FLAGS_CD 0x0001 /* .bootdev is a bios CD dev */ 22344399Skevans#define KARGS_FLAGS_PXE 0x0002 /* .pxeinfo is valid */ 23344399Skevans#define KARGS_FLAGS_ZFS 0x0004 /* .zfspool is valid, EXTARG is zfs_boot_args */ 24344399Skevans#define KARGS_FLAGS_EXTARG 0x0008 /* variably sized extended argument */ 25344399Skevans#define KARGS_FLAGS_GELI 0x0010 /* EXTARG is geli_boot_args */ 26235154Savg 27235154Savg#define BOOTARGS_SIZE 24 /* sizeof(struct bootargs) */ 28235154Savg#define BA_BOOTFLAGS 8 /* offsetof(struct bootargs, bootflags) */ 29235154Savg#define BA_BOOTINFO 20 /* offsetof(struct bootargs, bootinfo) */ 30235154Savg#define BI_SIZE 48 /* offsetof(struct bootinfo, bi_size) */ 31235154Savg 32235154Savg/* 33235154Savg * We reserve some space above BTX allocated stack for the arguments 34235154Savg * and certain data that could hang off them. Currently only struct bootinfo 35235154Savg * is supported in that category. The bootinfo is placed at the top 36235154Savg * of the arguments area and the actual arguments are placed at ARGOFF offset 37235154Savg * from the top and grow towards the top. Hopefully we have enough space 38235154Savg * for bootinfo and the arguments to not run into each other. 39235154Savg * Arguments area below ARGOFF is reserved for future use. 40235154Savg */ 41235154Savg#define ARGSPACE 0x1000 /* total size of the BTX args area */ 42235154Savg#define ARGOFF 0x800 /* actual args offset within the args area */ 43235154Savg#define ARGADJ (ARGSPACE - ARGOFF) 44235154Savg 45235154Savg#ifndef __ASSEMBLER__ 46235154Savg 47344399Skevans/* 48344399Skevans * This struct describes the contents of the stack on entry to btxldr.S. This 49344399Skevans * is the data that follows the return address, so it begins at 4(%esp). On 50344399Skevans * the sending side, this data is passed as individual args to __exec(). On the 51344399Skevans * receiving side, code in btxldr.S copies the data from the entry stack to a 52344399Skevans * known fixed location in the new address space. Then, btxcsu.S sets the 53344399Skevans * global variable __args to point to that known fixed location before calling 54344399Skevans * main(), which casts __args to a struct bootargs pointer to access the data. 55344399Skevans * The btxldr.S code is aware of KARGS_FLAGS_EXTARG, and if it's set, the extra 56344399Skevans * args data is copied along with the other bootargs from the entry stack to the 57344399Skevans * fixed location in the new address space. 58344399Skevans * 59344399Skevans * The bootinfo field is actually a pointer to a bootinfo struct that has been 60344399Skevans * converted to uint32_t using VTOP(). On the receiving side it must be 61344399Skevans * converted back to a pointer using PTOV(). Code in btxldr.S is aware of this 62344399Skevans * field and if it's non-NULL it copies the data it points to into another known 63344399Skevans * fixed location, and adjusts the bootinfo field to point to that new location. 64344399Skevans */ 65235154Savgstruct bootargs 66235154Savg{ 67235154Savg uint32_t howto; 68235154Savg uint32_t bootdev; 69235154Savg uint32_t bootflags; 70235154Savg union { 71235154Savg struct { 72235154Savg uint32_t pxeinfo; 73235154Savg uint32_t reserved; 74235154Savg }; 75235154Savg uint64_t zfspool; 76235154Savg }; 77235154Savg uint32_t bootinfo; 78235154Savg 79235154Savg /* 80235154Savg * If KARGS_FLAGS_EXTARG is set in bootflags, then the above fields 81235154Savg * are followed by a uint32_t field that specifies a size of the 82235154Savg * extended arguments (including the size field). 83235154Savg */ 84235154Savg}; 85235154Savg 86329099Skevans#ifdef LOADER_GELI_SUPPORT 87329099Skevans#include <crypto/intake.h> 88344399Skevans#include "geliboot.h" 89329099Skevans#endif 90329099Skevans 91344399Skevans/* 92344399Skevans * geli_boot_data is embedded in geli_boot_args (passed from gptboot to loader) 93344399Skevans * and in zfs_boot_args (passed from zfsboot and gptzfsboot to loader). 94344399Skevans */ 95344399Skevansstruct geli_boot_data 96296963Sallanjude{ 97329099Skevans union { 98329099Skevans char gelipw[256]; 99329099Skevans struct { 100329099Skevans char notapw; /* 101329099Skevans * single null byte to stop keybuf 102329099Skevans * being interpreted as a password 103329099Skevans */ 104329099Skevans uint32_t keybuf_sentinel; 105329099Skevans#ifdef LOADER_GELI_SUPPORT 106329099Skevans struct keybuf *keybuf; 107329099Skevans#else 108329099Skevans void *keybuf; 109329099Skevans#endif 110329099Skevans }; 111329099Skevans }; 112296963Sallanjude}; 113296963Sallanjude 114344399Skevans#ifdef LOADER_GELI_SUPPORT 115344399Skevans 116344399Skevansstatic inline void 117344399Skevansexport_geli_boot_data(struct geli_boot_data *gbdata) 118344399Skevans{ 119344399Skevans 120344399Skevans gbdata->notapw = '\0'; 121344399Skevans gbdata->keybuf_sentinel = KEYBUF_SENTINEL; 122344399Skevans gbdata->keybuf = malloc(sizeof(struct keybuf) + 123344399Skevans (GELI_MAX_KEYS * sizeof(struct keybuf_ent))); 124344399Skevans geli_export_key_buffer(gbdata->keybuf); 125344399Skevans} 126344399Skevans 127344399Skevansstatic inline void 128344399Skevansimport_geli_boot_data(struct geli_boot_data *gbdata) 129344399Skevans{ 130344399Skevans 131344399Skevans if (gbdata->gelipw[0] != '\0') { 132344399Skevans setenv("kern.geom.eli.passphrase", gbdata->gelipw, 1); 133344399Skevans explicit_bzero(gbdata->gelipw, sizeof(gbdata->gelipw)); 134344399Skevans } else if (gbdata->keybuf_sentinel == KEYBUF_SENTINEL) { 135344399Skevans geli_import_key_buffer(gbdata->keybuf); 136344399Skevans } 137344399Skevans} 138344399Skevans#endif /* LOADER_GELI_SUPPORT */ 139344399Skevans 140344399Skevansstruct geli_boot_args 141344399Skevans{ 142344399Skevans uint32_t size; 143344399Skevans struct geli_boot_data gelidata; 144344399Skevans}; 145344399Skevans 146344399Skevansstruct zfs_boot_args 147344399Skevans{ 148344399Skevans uint32_t size; 149344399Skevans uint32_t reserved; 150344399Skevans uint64_t pool; 151344399Skevans uint64_t root; 152344399Skevans uint64_t primary_pool; 153344399Skevans uint64_t primary_vdev; 154344399Skevans struct geli_boot_data gelidata; 155344399Skevans}; 156344399Skevans 157235154Savg#endif /*__ASSEMBLER__*/ 158235154Savg 159235154Savg#endif /* !_BOOT_I386_ARGS_H_ */ 160