1 /*- 2 * Copyright (c) 2012 Andriy Gapon <avg@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are freely 6 * permitted provided that the above copyright notice and this 7 * paragraph and the following disclaimer are duplicated in all 8 * such forms. 9 * 10 * This software is provided "AS IS" and without any express or 11 * implied warranties, including, without limitation, the implied 12 * warranties of merchantability and fitness for a particular 13 * purpose. 14 * 15 * $FreeBSD$ 16 */ 17 18 #ifndef _BOOT_I386_ARGS_H_ 19 #define _BOOT_I386_ARGS_H_ 20 21 #define KARGS_FLAGS_CD 0x0001 /* .bootdev is a bios CD dev */ 22 #define KARGS_FLAGS_PXE 0x0002 /* .pxeinfo is valid */ 23 #define KARGS_FLAGS_ZFS 0x0004 /* .zfspool is valid, EXTARG is zfs_boot_args */ 24 #define KARGS_FLAGS_EXTARG 0x0008 /* variably sized extended argument */ 25 #define KARGS_FLAGS_GELI 0x0010 /* EXTARG is geli_boot_args */ 26 27 #define BOOTARGS_SIZE 24 /* sizeof(struct bootargs) */ 28 #define BA_BOOTFLAGS 8 /* offsetof(struct bootargs, bootflags) */ 29 #define BA_BOOTINFO 20 /* offsetof(struct bootargs, bootinfo) */ 30 #define BI_SIZE 48 /* offsetof(struct bootinfo, bi_size) */ 31 32 /* 33 * We reserve some space above BTX allocated stack for the arguments 34 * and certain data that could hang off them. Currently only struct bootinfo 35 * is supported in that category. The bootinfo is placed at the top 36 * of the arguments area and the actual arguments are placed at ARGOFF offset 37 * from the top and grow towards the top. Hopefully we have enough space 38 * for bootinfo and the arguments to not run into each other. 39 * Arguments area below ARGOFF is reserved for future use. 40 */ 41 #define ARGSPACE 0x1000 /* total size of the BTX args area */ 42 #define ARGOFF 0x800 /* actual args offset within the args area */ 43 #define ARGADJ (ARGSPACE - ARGOFF) 44 45 #ifndef __ASSEMBLER__ 46 47 /* 48 * This struct describes the contents of the stack on entry to btxldr.S. This 49 * is the data that follows the return address, so it begins at 4(%esp). On 50 * the sending side, this data is passed as individual args to __exec(). On the 51 * receiving side, code in btxldr.S copies the data from the entry stack to a 52 * known fixed location in the new address space. Then, btxcsu.S sets the 53 * global variable __args to point to that known fixed location before calling 54 * main(), which casts __args to a struct bootargs pointer to access the data. 55 * The btxldr.S code is aware of KARGS_FLAGS_EXTARG, and if it's set, the extra 56 * args data is copied along with the other bootargs from the entry stack to the 57 * fixed location in the new address space. 58 * 59 * The bootinfo field is actually a pointer to a bootinfo struct that has been 60 * converted to uint32_t using VTOP(). On the receiving side it must be 61 * converted back to a pointer using PTOV(). Code in btxldr.S is aware of this 62 * field and if it's non-NULL it copies the data it points to into another known 63 * fixed location, and adjusts the bootinfo field to point to that new location. 64 */ 65 struct bootargs 66 { 67 uint32_t howto; 68 uint32_t bootdev; 69 uint32_t bootflags; 70 union { 71 struct { 72 uint32_t pxeinfo; 73 uint32_t reserved; 74 }; 75 uint64_t zfspool; 76 }; 77 uint32_t bootinfo; 78 79 /* 80 * If KARGS_FLAGS_EXTARG is set in bootflags, then the above fields 81 * are followed by a uint32_t field that specifies a size of the 82 * extended arguments (including the size field). 83 */ 84 }; 85 86 #ifdef LOADER_GELI_SUPPORT 87 #include <crypto/intake.h> 88 #include "geliboot.h" 89 #endif 90 91 /* 92 * geli_boot_data is embedded in geli_boot_args (passed from gptboot to loader) 93 * and in zfs_boot_args (passed from zfsboot and gptzfsboot to loader). 94 */ 95 struct geli_boot_data 96 { 97 union { 98 char gelipw[256]; 99 struct { 100 char notapw; /* 101 * single null byte to stop keybuf 102 * being interpreted as a password 103 */ 104 uint32_t keybuf_sentinel; 105 #ifdef LOADER_GELI_SUPPORT 106 struct keybuf *keybuf; 107 #else 108 void *keybuf; 109 #endif 110 }; 111 }; 112 }; 113 114 #ifdef LOADER_GELI_SUPPORT 115 116 static inline void 117 export_geli_boot_data(struct geli_boot_data *gbdata) 118 { 119 120 gbdata->notapw = '\0'; 121 gbdata->keybuf_sentinel = KEYBUF_SENTINEL; 122 gbdata->keybuf = malloc(sizeof(struct keybuf) + 123 (GELI_MAX_KEYS * sizeof(struct keybuf_ent))); 124 geli_export_key_buffer(gbdata->keybuf); 125 } 126 127 static inline void 128 import_geli_boot_data(struct geli_boot_data *gbdata) 129 { 130 131 if (gbdata->gelipw[0] != '\0') { 132 setenv("kern.geom.eli.passphrase", gbdata->gelipw, 1); 133 explicit_bzero(gbdata->gelipw, sizeof(gbdata->gelipw)); 134 } else if (gbdata->keybuf_sentinel == KEYBUF_SENTINEL) { 135 geli_import_key_buffer(gbdata->keybuf); 136 } 137 } 138 #endif /* LOADER_GELI_SUPPORT */ 139 140 struct geli_boot_args 141 { 142 uint32_t size; 143 struct geli_boot_data gelidata; 144 }; 145 146 struct zfs_boot_args 147 { 148 uint32_t size; 149 uint32_t reserved; 150 uint64_t pool; 151 uint64_t root; 152 uint64_t primary_pool; 153 uint64_t primary_vdev; 154 struct geli_boot_data gelidata; 155 }; 156 157 #endif /*__ASSEMBLER__*/ 158 159 #endif /* !_BOOT_I386_ARGS_H_ */ 160