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