aboutsummaryrefslogtreecommitdiff
path: root/stand/i386/common/bootargs.h
blob: 072f7ee505fd848eff5d7fca17999818964ed1b3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*-
 * Copyright (c) 2012 Andriy Gapon <avg@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are freely
 * permitted provided that the above copyright notice and this
 * paragraph and the following disclaimer are duplicated in all
 * such forms.
 *
 * This software is provided "AS IS" and without any express or
 * implied warranties, including, without limitation, the implied
 * warranties of merchantability and fitness for a particular
 * purpose.
 */

#ifndef _BOOT_I386_ARGS_H_
#define	_BOOT_I386_ARGS_H_

#define	KARGS_FLAGS_CD		0x0001	/* .bootdev is a bios CD dev */
#define	KARGS_FLAGS_PXE		0x0002	/* .pxeinfo is valid */
#define	KARGS_FLAGS_ZFS		0x0004	/* .zfspool is valid, EXTARG is zfs_boot_args */
#define	KARGS_FLAGS_EXTARG	0x0008	/* variably sized extended argument */
#define	KARGS_FLAGS_GELI	0x0010	/* EXTARG is geli_boot_args */

#define	BOOTARGS_SIZE	24	/* sizeof(struct bootargs) */
#define	BA_BOOTFLAGS	8	/* offsetof(struct bootargs, bootflags) */
#define	BA_BOOTINFO	20	/* offsetof(struct bootargs, bootinfo) */
#define	BI_SIZE		48	/* offsetof(struct bootinfo, bi_size) */

/*
 * We reserve some space above BTX allocated stack for the arguments
 * and certain data that could hang off them.  Currently only struct bootinfo
 * is supported in that category.  The bootinfo is placed at the top
 * of the arguments area and the actual arguments are placed at ARGOFF offset
 * from the top and grow towards the top.  Hopefully we have enough space
 * for bootinfo and the arguments to not run into each other.
 * Arguments area below ARGOFF is reserved for future use.
 */
#define	ARGSPACE	0x1000	/* total size of the BTX args area */
#define	ARGOFF		0x800	/* actual args offset within the args area */
#define	ARGADJ		(ARGSPACE - ARGOFF)

#ifndef __ASSEMBLER__

/*
 * This struct describes the contents of the stack on entry to btxldr.S.  This
 * is the data that follows the return address, so it begins at 4(%esp).  On
 * the sending side, this data is passed as individual args to __exec().  On the
 * receiving side, code in btxldr.S copies the data from the entry stack to a
 * known fixed location in the new address space.  Then, btxcsu.S sets the
 * global variable __args to point to that known fixed location before calling
 * main(), which casts __args to a struct bootargs pointer to access the data.
 * The btxldr.S code is aware of KARGS_FLAGS_EXTARG, and if it's set, the extra
 * args data is copied along with the other bootargs from the entry stack to the
 * fixed location in the new address space.
 *
 * The bootinfo field is actually a pointer to a bootinfo struct that has been
 * converted to uint32_t using VTOP().  On the receiving side it must be
 * converted back to a pointer using PTOV().  Code in btxldr.S is aware of this
 * field and if it's non-NULL it copies the data it points to into another known
 * fixed location, and adjusts the bootinfo field to point to that new location.
 */
struct bootargs
{
	uint32_t			howto;
	uint32_t			bootdev;
	uint32_t			bootflags;
	union {
		struct {
			uint32_t	pxeinfo;
			uint32_t	reserved;
		};
		uint64_t		zfspool;
	};
	uint32_t			bootinfo;

	/*
	 * If KARGS_FLAGS_EXTARG is set in bootflags, then the above fields
	 * are followed by a uint32_t field that specifies a size of the
	 * extended arguments (including the size field).
	 */
};

#ifdef LOADER_GELI_SUPPORT
#include <crypto/intake.h>
#include "geliboot.h"
#endif

/*
 * geli_boot_data is embedded in geli_boot_args (passed from gptboot to loader)
 * and in zfs_boot_args (passed from gptzfsboot to loader).
 */
struct geli_boot_data
{
    union {
        char            gelipw[256];
        struct {
            char                notapw;	/* 
					 * single null byte to stop keybuf
					 * being interpreted as a password
					 */
            uint32_t            keybuf_sentinel;
#ifdef LOADER_GELI_SUPPORT
            struct keybuf       *keybuf;
#else
            void                *keybuf;
#endif
        };
    };
};

#ifdef LOADER_GELI_SUPPORT

static inline void
export_geli_boot_data(struct geli_boot_data *gbdata)
{

	gbdata->notapw = '\0';
	gbdata->keybuf_sentinel = KEYBUF_SENTINEL;
	gbdata->keybuf = malloc(sizeof(struct keybuf) +
	    (GELI_MAX_KEYS * sizeof(struct keybuf_ent)));
	geli_export_key_buffer(gbdata->keybuf);
}

static inline void
import_geli_boot_data(struct geli_boot_data *gbdata)
{

	if (gbdata->gelipw[0] != '\0') {
	    setenv("kern.geom.eli.passphrase", gbdata->gelipw, 1);
	    explicit_bzero(gbdata->gelipw, sizeof(gbdata->gelipw));
	} else if (gbdata->keybuf_sentinel == KEYBUF_SENTINEL) {
	    geli_import_key_buffer(gbdata->keybuf);
	}
}
#endif /* LOADER_GELI_SUPPORT */

struct geli_boot_args
{
	uint32_t		size;
	struct geli_boot_data	gelidata;
};

struct zfs_boot_args
{
	uint32_t		size;
	uint32_t		reserved;
	uint64_t		pool;
	uint64_t		root;
	uint64_t		primary_pool;
	uint64_t		primary_vdev;
	struct geli_boot_data	gelidata;
};

#endif /*__ASSEMBLER__*/

#endif	/* !_BOOT_I386_ARGS_H_ */