Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/stand/common/bootstrap.h
34677 views
1
/*-
2
* Copyright (c) 1998 Michael Smith <[email protected]>
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*/
26
27
#ifndef _BOOTSTRAP_H_
28
#define _BOOTSTRAP_H_
29
30
#include <stand.h>
31
#include <sys/types.h>
32
#include <sys/queue.h>
33
#include <sys/linker_set.h>
34
#include <stdbool.h>
35
36
#include "readin.h"
37
38
/* Commands and return values; nonzero return sets command_errmsg != NULL */
39
typedef int (bootblk_cmd_t)(int argc, char *argv[]);
40
#define COMMAND_ERRBUFSZ (256)
41
extern const char *command_errmsg;
42
extern char command_errbuf[COMMAND_ERRBUFSZ];
43
#define CMD_OK 0
44
#define CMD_WARN 1
45
#define CMD_ERROR 2
46
#define CMD_CRIT 3
47
#define CMD_FATAL 4
48
49
/* interp.c */
50
void interact(void);
51
void interp_emit_prompt(void);
52
int interp_builtin_cmd(int argc, char *argv[]);
53
bool interp_has_builtin_cmd(const char *cmd);
54
55
/* Called by interp.c for interp_*.c embedded interpreters */
56
int interp_include(const char *); /* Execute commands from filename */
57
void interp_preinit(void); /* Initialize interpreater execution engine */
58
void interp_init(void); /* Initialize interpreater and run main script */
59
int interp_run(const char *); /* Run a single command */
60
61
/* interp_backslash.c */
62
char *backslash(const char *str);
63
64
/* interp_parse.c */
65
int parse(int *argc, char ***argv, const char *str);
66
67
/* boot.c */
68
void autoboot_maybe(void);
69
int getrootmount(char *rootdev);
70
71
/* misc.c */
72
char *unargv(int argc, char *argv[]);
73
size_t strlenout(vm_offset_t str);
74
char *strdupout(vm_offset_t str);
75
void kern_bzero(vm_offset_t dest, size_t len);
76
int kern_pread(readin_handle_t fd, vm_offset_t dest, size_t len, off_t off);
77
void *alloc_pread(readin_handle_t fd, off_t off, size_t len);
78
79
/* bcache.c */
80
void bcache_init(size_t nblks, size_t bsize);
81
void bcache_add_dev(int);
82
void *bcache_allocate(void);
83
void bcache_free(void *);
84
int bcache_strategy(void *devdata, int rw, daddr_t blk, size_t size,
85
char *buf, size_t *rsize);
86
87
/*
88
* Disk block cache
89
*/
90
struct bcache_devdata
91
{
92
int (*dv_strategy)(void *, int, daddr_t, size_t, char *, size_t *);
93
void *dv_devdata;
94
void *dv_cache;
95
};
96
97
/*
98
* Modular console support.
99
*/
100
struct console
101
{
102
const char *c_name;
103
const char *c_desc;
104
int c_flags;
105
#define C_PRESENTIN (1<<0) /* console can provide input */
106
#define C_PRESENTOUT (1<<1) /* console can provide output */
107
#define C_ACTIVEIN (1<<2) /* user wants input from console */
108
#define C_ACTIVEOUT (1<<3) /* user wants output to console */
109
#define C_WIDEOUT (1<<4) /* c_out routine groks wide chars */
110
111
/* set c_flags to match hardware */
112
void (* c_probe)(struct console *cp);
113
/* reinit XXX may need more args */
114
int (* c_init)(int arg);
115
/* emit c */
116
void (* c_out)(int c);
117
/* wait for and return input */
118
int (* c_in)(void);
119
/* return nonzero if input waiting */
120
int (* c_ready)(void);
121
};
122
extern struct console *consoles[];
123
void cons_probe(void);
124
bool cons_update_mode(bool);
125
void autoload_font(bool);
126
127
extern int module_verbose;
128
enum {
129
MODULE_VERBOSE_SILENT, /* say nothing */
130
MODULE_VERBOSE_SIZE, /* print name and size */
131
MODULE_VERBOSE_TWIDDLE, /* show progress */
132
MODULE_VERBOSE_FULL, /* all we have */
133
};
134
135
/*
136
* Plug-and-play enumerator/configurator interface.
137
*/
138
struct pnphandler
139
{
140
const char *pp_name; /* handler/bus name */
141
void (*pp_enumerate)(void); /* enumerate PnP devices, add to chain */
142
};
143
144
struct pnpident
145
{
146
/* ASCII identifier, actual format varies with bus/handler */
147
char *id_ident;
148
STAILQ_ENTRY(pnpident) id_link;
149
};
150
151
struct pnpinfo
152
{
153
char *pi_desc; /* ASCII description, optional */
154
int pi_revision; /* optional revision (or -1) if not supported */
155
char *pi_module; /* module/args nominated to handle device */
156
int pi_argc; /* module arguments */
157
char **pi_argv;
158
struct pnphandler *pi_handler; /* handler which detected this device */
159
STAILQ_HEAD(, pnpident) pi_ident; /* list of identifiers */
160
STAILQ_ENTRY(pnpinfo) pi_link;
161
};
162
163
STAILQ_HEAD(pnpinfo_stql, pnpinfo);
164
165
extern struct pnphandler *pnphandlers[]; /* provided by MD code */
166
167
void pnp_addident(struct pnpinfo *pi, char *ident);
168
struct pnpinfo *pnp_allocinfo(void);
169
void pnp_freeinfo(struct pnpinfo *pi);
170
void pnp_addinfo(struct pnpinfo *pi);
171
char *pnp_eisaformat(uint8_t *data);
172
173
/*
174
* < 0 - No ISA in system
175
* == 0 - Maybe ISA, search for read data port
176
* > 0 - ISA in system, value is read data port address
177
*/
178
extern int isapnp_readport;
179
180
/*
181
* Version information
182
*/
183
extern char bootprog_info[];
184
extern unsigned bootprog_rev;
185
186
/*
187
* Interpreter information
188
*/
189
extern const char bootprog_interp[];
190
#define INTERP_DEFINE(interpstr) \
191
const char bootprog_interp[] = "$Interpreter:" interpstr
192
193
194
/*
195
* Preloaded file metadata header.
196
*
197
* Metadata are allocated on our heap, and copied into kernel space
198
* before executing the kernel.
199
*/
200
struct file_metadata
201
{
202
size_t md_size;
203
uint16_t md_type;
204
vm_offset_t md_addr; /* Valid after copied to kernel space */
205
struct file_metadata *md_next;
206
char md_data[1]; /* data are immediately appended */
207
};
208
209
struct preloaded_file;
210
struct mod_depend;
211
212
struct kernel_module
213
{
214
char *m_name; /* module name */
215
int m_version; /* module version */
216
/* char *m_args; */ /* arguments for the module */
217
struct preloaded_file *m_fp;
218
struct kernel_module *m_next;
219
};
220
221
/*
222
* Preloaded file information. Depending on type, file can contain
223
* additional units called 'modules'.
224
*
225
* At least one file (the kernel) must be loaded in order to boot.
226
* The kernel is always loaded first.
227
*
228
* String fields (m_name, m_type) should be dynamically allocated.
229
*/
230
struct preloaded_file
231
{
232
char *f_name; /* file name */
233
char *f_type; /* verbose file type, eg 'elf kernel', 'pnptable', etc. */
234
char *f_args; /* arguments for the file */
235
/* metadata that will be placed in the module directory */
236
struct file_metadata *f_metadata;
237
int f_loader; /* index of the loader that read the file */
238
vm_offset_t f_addr; /* load address */
239
size_t f_size; /* file size */
240
struct kernel_module *f_modules; /* list of modules if any */
241
struct preloaded_file *f_next; /* next file */
242
#if defined(__amd64__) || (defined(__i386__) && defined(EFI))
243
bool f_kernphys_relocatable;
244
#endif
245
#if defined(__i386__) && !defined(EFI)
246
bool f_tg_kernel_support;
247
#endif
248
};
249
250
struct file_format
251
{
252
/*
253
* Load function must return EFTYPE if it can't handle
254
* the module supplied
255
*/
256
int (*l_load)(char *, uint64_t, struct preloaded_file **);
257
/*
258
* Only a loader that will load a kernel (first module)
259
* should have an exec handler
260
*/
261
int (*l_exec)(struct preloaded_file *);
262
};
263
264
extern struct file_format *file_formats[]; /* supplied by consumer */
265
extern struct preloaded_file *preloaded_files;
266
267
int mod_load(char *name, struct mod_depend *verinfo, int argc, char *argv[]);
268
int mod_loadkld(const char *name, int argc, char *argv[]);
269
void unload(void);
270
271
struct preloaded_file *file_alloc(void);
272
struct preloaded_file *file_findfile(const char *name, const char *type);
273
struct file_metadata *file_findmetadata(struct preloaded_file *fp, int type);
274
struct preloaded_file *file_loadraw(const char *name, const char *type, int insert);
275
void file_discard(struct preloaded_file *fp);
276
void file_addmetadata(struct preloaded_file *, int, size_t, void *);
277
int file_addmodule(struct preloaded_file *, char *, int,
278
struct kernel_module **);
279
void file_removemetadata(struct preloaded_file *fp);
280
int file_addbuf(const char *name, const char *type, size_t len, void *buf);
281
int tslog_init(void);
282
int tslog_publish(void);
283
284
vm_offset_t build_font_module(vm_offset_t);
285
vm_offset_t build_splash_module(vm_offset_t);
286
287
/* MI module loaders */
288
#ifdef __elfN
289
/* Relocation types. */
290
#define ELF_RELOC_REL 1
291
#define ELF_RELOC_RELA 2
292
293
/* Relocation offset for some architectures */
294
extern uint64_t __elfN(relocation_offset);
295
296
struct elf_file;
297
typedef Elf_Addr (symaddr_fn)(struct elf_file *ef, Elf_Size symidx);
298
299
int __elfN(loadfile)(char *, uint64_t, struct preloaded_file **);
300
int __elfN(obj_loadfile)(char *, uint64_t, struct preloaded_file **);
301
int __elfN(reloc)(struct elf_file *ef, symaddr_fn *symaddr,
302
const void *reldata, int reltype, Elf_Addr relbase,
303
Elf_Addr dataaddr, void *data, size_t len);
304
int __elfN(loadfile_raw)(char *, uint64_t, struct preloaded_file **, int);
305
int __elfN(load_modmetadata)(struct preloaded_file *, uint64_t);
306
#endif
307
308
/*
309
* Support for commands
310
*/
311
struct bootblk_command
312
{
313
const char *c_name;
314
const char *c_desc;
315
bootblk_cmd_t *c_fn;
316
};
317
318
#define COMMAND_SET(tag, key, desc, func) \
319
static bootblk_cmd_t func; \
320
static struct bootblk_command _cmd_ ## tag = { key, desc, func }; \
321
DATA_SET(Xcommand_set, _cmd_ ## tag)
322
323
SET_DECLARE(Xcommand_set, struct bootblk_command);
324
325
/*
326
* The intention of the architecture switch is to provide a convenient
327
* encapsulation of the interface between the bootstrap MI and MD code.
328
* MD code may selectively populate the switch at runtime based on the
329
* actual configuration of the target system, though some routines are
330
* mandatory.
331
*/
332
struct arch_switch
333
{
334
/* Automatically load modules as required by detected hardware */
335
int (*arch_autoload)(void);
336
/* Locate the device for (name), return pointer to tail in (*path) */
337
int (*arch_getdev)(void **dev, const char *name, const char **path);
338
/*
339
* Copy from local address space to module address space,
340
* similar to bcopy()
341
*/
342
ssize_t (*arch_copyin)(const void *, vm_offset_t, const size_t);
343
/*
344
* Copy to local address space from module address space,
345
* similar to bcopy()
346
*/
347
ssize_t (*arch_copyout)(const vm_offset_t, void *, const size_t);
348
/* Read from file to module address space, same semantics as read() */
349
ssize_t (*arch_readin)(readin_handle_t, vm_offset_t, const size_t);
350
/* Perform ISA byte port I/O (only for systems with ISA) */
351
int (*arch_isainb)(int port);
352
void (*arch_isaoutb)(int port, int value);
353
354
/*
355
* Interface to inform MD code about a loaded (ELF) segment. This
356
* can be used to flush caches and/or set up translations.
357
*/
358
#ifdef __elfN
359
void (*arch_loadseg)(Elf_Ehdr *eh, Elf_Phdr *ph, uint64_t delta);
360
#else
361
void (*arch_loadseg)(void *eh, void *ph, uint64_t delta);
362
#endif
363
364
/* Probe ZFS pool(s), if needed. */
365
void (*arch_zfs_probe)(void);
366
367
/* Return the hypervisor name/type or NULL if not virtualized. */
368
const char *(*arch_hypervisor)(void);
369
};
370
extern struct arch_switch archsw;
371
372
/* This must be provided by the MD code, but should it be in the archsw? */
373
void delay(int delay);
374
375
int setprint_delay(struct env_var *ev, int flags, const void *value);
376
377
/* common code to set currdev variable. */
378
int gen_setcurrdev(struct env_var *ev, int flags, const void *value);
379
int mount_currdev(struct env_var *, int, const void *);
380
void set_currdev(const char *devname);
381
382
#endif /* !_BOOTSTRAP_H_ */
383
384