bootstrap.h revision 38466
1/*-
2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
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 *	$Id$
27 */
28
29#include <sys/types.h>
30
31/* XXX debugging */
32extern struct console vidconsole;
33#define MARK(s, c) {vidconsole.c_out(s); vidconsole.c_out(c); while (!vidconsole.c_ready()) ; vidconsole.c_in();}
34
35/*
36 * Generic device specifier; architecture-dependant
37 * versions may be larger, but should be allowed to
38 * overlap.
39 */
40struct devdesc
41{
42    struct devsw	*d_dev;
43    int			d_type;
44#define DEVT_NONE	0
45#define DEVT_DISK	1
46#define DEVT_NET	2
47};
48
49/* Commands and return values; nonzero return sets command_errmsg != NULL */
50typedef int	(bootblk_cmd_t)(int argc, char *argv[]);
51extern char	*command_errmsg;
52extern char	command_errbuf[];	/* XXX blah, length */
53#define CMD_OK		0
54#define CMD_ERROR	1
55
56/* interp.c */
57extern void	interact(void);
58extern void	source(char *filename);
59
60/* boot.c */
61extern int	autoboot(int delay, char *prompt);
62
63/* misc.c */
64extern char	*unargv(int argc, char *argv[]);
65
66/*
67 * Modular console support.
68 */
69struct console
70{
71    char	*c_name;
72    char	*c_desc;
73    int		c_flags;
74#define C_PRESENTIN	(1<<0)
75#define C_PRESENTOUT	(1<<1)
76#define C_ACTIVEIN	(1<<2)
77#define C_ACTIVEOUT	(1<<3)
78    void	(* c_probe)(struct console *cp);	/* set c_flags to match hardware */
79    int		(* c_init)(int arg);			/* reinit XXX may need more args */
80    void	(* c_out)(int c);			/* emit c */
81    int		(* c_in)(void);				/* wait for and return input */
82    int		(* c_ready)(void);			/* return nonzer if input waiting */
83};
84extern struct console	*consoles[];
85extern void		cons_probe(void);
86
87/*
88 * Module loader.
89 */
90#define MF_FORMATMASK	0xf
91#define MF_AOUT		0
92#define MF_ELF		1
93
94/*
95 * Module metadata header.
96 *
97 * Metadata are allocated on our heap, and copied into kernel space
98 * before executing the kernel.
99 */
100struct module_metadata
101{
102    size_t			md_size;
103    u_int16_t			md_type;
104    struct module_metadata	*md_next;
105    char			md_data[0];	/* data are immediately appended */
106};
107
108/*
109 * Loaded module information.
110 *
111 * At least one module (the kernel) must be loaded in order to boot.
112 * The kernel is always loaded first.
113 */
114struct loaded_module
115{
116    char			*m_name;	/* module name */
117    char			*m_type;	/* module type, eg 'kernel', 'pnptable', etc. */
118    char			*m_args;	/* arguments for the module */
119    void			*m_metadata;	/* metadata that will be placed in the module directory */
120    int				m_flags;	/* 0xffff reserved for arch-specific use */
121    vm_offset_t			m_addr;		/* load address */
122    size_t			m_size;		/* module size */
123    struct loaded_module	*m_next;	/* next module */
124};
125
126struct module_format
127{
128    int		l_format;
129    /* Load function must return EFTYPE if it can't handle the module supplied */
130    int		(* l_load)(char *filename, vm_offset_t dest, struct loaded_module **result);
131    int		(* l_exec)(struct loaded_module *amp);
132};
133extern struct module_format	*module_formats[];	/* supplied by consumer */
134extern struct loaded_module	*loaded_modules;
135extern int			mod_load(char *name, int argc, char *argv[]);
136extern struct loaded_module	*mod_findmodule(char *name, char *type);
137
138/* XXX these belong in <machine/bootinfo.h> */
139#define MODINFO_NAME		0x0000
140#define MODINFO_TYPE		0x0001
141#define MODINFO_ADDR		0x0002
142#define MODINFO_SIZE		0x0003
143#define MODINFO_METADATA	0x8000
144
145
146#if defined(__ELF__)
147
148/*
149 * Alpha GAS needs an align before the section change.  It seems to assume
150 * that after the .previous, it is aligned, so the following .align 3 is
151 * ignored.  Since the previous instructions often contain strings, this is
152 * a problem.
153 */
154
155#ifdef __alpha__
156#define MAKE_SET(set, sym)			\
157	__asm(".align 3");			\
158	__asm(".section .set." #set ",\"aw\"");	\
159	__asm(".quad " #sym);			\
160	__asm(".previous")
161#else
162#define MAKE_SET(set, sym)			\
163	__asm(".section .set." #set ",\"aw\"");	\
164	__asm(".long " #sym);			\
165	__asm(".previous")
166#endif
167#define TEXT_SET(set, sym) MAKE_SET(set, sym)
168#define DATA_SET(set, sym) MAKE_SET(set, sym)
169#define BSS_SET(set, sym)  MAKE_SET(set, sym)
170#define ABS_SET(set, sym)  MAKE_SET(set, sym)
171
172#else
173
174/*
175 * Linker set support, directly from <sys/kernel.h>
176 *
177 * NB: the constants defined below must match those defined in
178 * ld/ld.h.  Since their calculation requires arithmetic, we
179 * can't name them symbolically (e.g., 23 is N_SETT | N_EXT).
180 */
181#define MAKE_SET(set, sym, type) \
182	static void const * const __set_##set##_sym_##sym = &sym; \
183	__asm(".stabs \"_" #set "\", " #type ", 0, 0, _" #sym)
184#define TEXT_SET(set, sym) MAKE_SET(set, sym, 23)
185#define DATA_SET(set, sym) MAKE_SET(set, sym, 25)
186#define BSS_SET(set, sym)  MAKE_SET(set, sym, 27)
187#define ABS_SET(set, sym)  MAKE_SET(set, sym, 21)
188
189#endif
190
191struct linker_set {
192    int             ls_length;
193    const void      *ls_items[1];	/* really ls_length of them, trailing NULL */
194};
195
196/*
197 * Support for commands
198 */
199struct bootblk_command
200{
201    const char		*c_name;
202    const char		*c_desc;
203    bootblk_cmd_t	*c_fn;
204};
205
206#define COMMAND_SET(tag, key, desc, func)				\
207    static bootblk_cmd_t func;						\
208    static struct bootblk_command _cmd_ ## tag = { key, desc, func };	\
209    DATA_SET(Xcommand_set, _cmd_ ## tag);
210
211extern struct linker_set Xcommand_set;
212
213/*
214 * functions called down from the generic code
215 */
216struct arch_switch
217{
218    /* Automatically load modules as required by detected hardware */
219    int			(* arch_autoload)();
220    /* Boot the loaded kernel (first loaded module) */
221    int			(* arch_boot)(void);
222    /* Locate the device for (name), return pointer to tail in (*path) */
223    int			(*arch_getdev)(void **dev, char *name, char **path);
224};
225extern struct arch_switch archsw;
226
227