bootargs.h revision 344399
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: stable/11/stand/i386/common/bootargs.h 344399 2019-02-20 23:55:35Z kevans $
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 */
65struct 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 */
95struct 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
116static inline void
117export_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
127static inline void
128import_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
140struct geli_boot_args
141{
142	uint32_t		size;
143	struct geli_boot_data	gelidata;
144};
145
146struct 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