xref: /freebsd/stand/i386/common/bootargs.h (revision 148a8da8)
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