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