boot.c revision 1.20 1 1.20 christos /* $NetBSD: boot.c,v 1.20 2014/03/26 16:16:06 christos Exp $ */
2 1.1 thorpej
3 1.1 thorpej /*-
4 1.1 thorpej * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 1.1 thorpej * All rights reserved.
6 1.1 thorpej *
7 1.1 thorpej * This code is derived from software contributed to The NetBSD Foundation
8 1.1 thorpej * by Jonathan Stone, Michael Hitch and Simon Burge.
9 1.1 thorpej *
10 1.1 thorpej * Redistribution and use in source and binary forms, with or without
11 1.1 thorpej * modification, are permitted provided that the following conditions
12 1.1 thorpej * are met:
13 1.1 thorpej * 1. Redistributions of source code must retain the above copyright
14 1.1 thorpej * notice, this list of conditions and the following disclaimer.
15 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 thorpej * notice, this list of conditions and the following disclaimer in the
17 1.1 thorpej * documentation and/or other materials provided with the distribution.
18 1.1 thorpej *
19 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 thorpej * POSSIBILITY OF SUCH DAMAGE.
30 1.1 thorpej */
31 1.1 thorpej
32 1.1 thorpej /*
33 1.1 thorpej * Copyright (c) 1992, 1993
34 1.1 thorpej * The Regents of the University of California. All rights reserved.
35 1.1 thorpej *
36 1.1 thorpej * This code is derived from software contributed to Berkeley by
37 1.1 thorpej * Ralph Campbell.
38 1.1 thorpej *
39 1.1 thorpej * Redistribution and use in source and binary forms, with or without
40 1.1 thorpej * modification, are permitted provided that the following conditions
41 1.1 thorpej * are met:
42 1.1 thorpej * 1. Redistributions of source code must retain the above copyright
43 1.1 thorpej * notice, this list of conditions and the following disclaimer.
44 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright
45 1.1 thorpej * notice, this list of conditions and the following disclaimer in the
46 1.1 thorpej * documentation and/or other materials provided with the distribution.
47 1.4 agc * 3. Neither the name of the University nor the names of its contributors
48 1.1 thorpej * may be used to endorse or promote products derived from this software
49 1.1 thorpej * without specific prior written permission.
50 1.1 thorpej *
51 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
52 1.1 thorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 1.1 thorpej * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 1.1 thorpej * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55 1.1 thorpej * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 1.1 thorpej * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 1.1 thorpej * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 1.1 thorpej * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 1.1 thorpej * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 1.1 thorpej * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 1.1 thorpej * SUCH DAMAGE.
62 1.1 thorpej *
63 1.1 thorpej * @(#)boot.c 8.1 (Berkeley) 6/10/93
64 1.1 thorpej */
65 1.1 thorpej
66 1.1 thorpej #include <lib/libsa/stand.h>
67 1.1 thorpej #include <lib/libsa/loadfile.h>
68 1.1 thorpej #include <lib/libkern/libkern.h>
69 1.1 thorpej
70 1.1 thorpej #include <sys/param.h>
71 1.1 thorpej #include <sys/exec.h>
72 1.1 thorpej #include <sys/exec_elf.h>
73 1.5 sekiya #include <sys/boot_flag.h>
74 1.1 thorpej
75 1.1 thorpej #include <dev/arcbios/arcbios.h>
76 1.1 thorpej
77 1.1 thorpej #include "common.h"
78 1.1 thorpej #include "bootinfo.h"
79 1.1 thorpej
80 1.1 thorpej /*
81 1.1 thorpej * We won't go overboard with gzip'd kernel names. After all we can
82 1.2 soren * still boot a gzip'd kernel called "netbsd.sgimips" - it doesn't need
83 1.1 thorpej * the .gz suffix.
84 1.5 sekiya *
85 1.5 sekiya * For arcane reasons, the first byte of the first element of this struct will
86 1.5 sekiya * contain a zero. We therefore start from one.
87 1.1 thorpej */
88 1.5 sekiya
89 1.15 tsutsui const char *kernelnames[] = {
90 1.5 sekiya "placekeeper",
91 1.1 thorpej "netbsd.sgimips",
92 1.5 sekiya "netbsd",
93 1.5 sekiya "netbsd.gz",
94 1.1 thorpej "netbsd.bak",
95 1.1 thorpej "netbsd.old",
96 1.1 thorpej "onetbsd",
97 1.1 thorpej "gennetbsd",
98 1.1 thorpej NULL
99 1.1 thorpej };
100 1.1 thorpej
101 1.15 tsutsui static int debug = 0;
102 1.1 thorpej
103 1.15 tsutsui int main(int, char **);
104 1.1 thorpej
105 1.3 thorpej /* Storage must be static. */
106 1.3 thorpej struct btinfo_symtab bi_syms;
107 1.3 thorpej struct btinfo_bootpath bi_bpath;
108 1.3 thorpej
109 1.13 tsutsui static uint8_t bootinfo[BOOTINFO_SIZE];
110 1.13 tsutsui
111 1.1 thorpej /*
112 1.5 sekiya * This gets arguments from the ARCS monitor, calls ARCS routines to open
113 1.5 sekiya * and load the program to boot, then transfers execution to the new program.
114 1.5 sekiya *
115 1.5 sekiya * argv[0] will be the ARCS path to the bootloader (i.e.,
116 1.5 sekiya * "pci(0)scsi(0)disk(2)rdisk(0)partition(8)/boot.ip3").
117 1.5 sekiya *
118 1.5 sekiya * argv[1] through argv[n] will contain arguments passed from the PROM, if any.
119 1.1 thorpej */
120 1.5 sekiya
121 1.1 thorpej int
122 1.5 sekiya main(int argc, char **argv)
123 1.1 thorpej {
124 1.11 martin const char *kernel = NULL;
125 1.11 martin const char *bootpath = NULL;
126 1.5 sekiya char bootfile[PATH_MAX];
127 1.5 sekiya void (*entry) (int, char *[], int, void *);
128 1.5 sekiya u_long marks[MARK_MAX];
129 1.5 sekiya int win = 0;
130 1.5 sekiya int i;
131 1.5 sekiya int ch;
132 1.1 thorpej
133 1.1 thorpej /* print a banner */
134 1.1 thorpej printf("\n");
135 1.15 tsutsui printf("%s " NETBSD_VERS " Bootstrap, Revision %s\n",
136 1.15 tsutsui bootprog_name, bootprog_rev);
137 1.1 thorpej printf("\n");
138 1.1 thorpej
139 1.5 sekiya memset(marks, 0, sizeof marks);
140 1.1 thorpej
141 1.1 thorpej /* initialise bootinfo structure early */
142 1.13 tsutsui bi_init(bootinfo);
143 1.1 thorpej
144 1.5 sekiya /* Parse arguments, if present. */
145 1.5 sekiya while ((ch = getopt(argc, argv, "v")) != -1) {
146 1.5 sekiya switch (ch) {
147 1.5 sekiya case 'v':
148 1.5 sekiya debug = 1;
149 1.5 sekiya break;
150 1.5 sekiya }
151 1.5 sekiya }
152 1.5 sekiya
153 1.1 thorpej /*
154 1.1 thorpej * How to find partition and file to load?
155 1.5 sekiya *
156 1.6 sekiya * If argv[0] contains the string "cdrom(", we're probably doing an
157 1.6 sekiya * install. The bootpath will therefore be partition 0 of whatever
158 1.6 sekiya * device we've booted from. Derive the install kernel name from
159 1.15 tsutsui * the bootloader name ("ip3xboot", "ip2xboot", or "aoutboot").
160 1.1 thorpej */
161 1.5 sekiya
162 1.15 tsutsui if (strstr(argv[0], "cdrom(")) {
163 1.20 christos char *ep =
164 1.6 sekiya strcpy(bootfile, argv[0]);
165 1.20 christos ep = strrchr(bootfile, ')');
166 1.20 christos i = ep - bootfile;
167 1.15 tsutsui bootfile[i - 1] = '0';
168 1.6 sekiya if (strstr(bootfile, "ip3x"))
169 1.14 tsutsui kernel = "ip3x";
170 1.6 sekiya else
171 1.14 tsutsui kernel = "ip2x";
172 1.20 christos strcpy(ep + 1, kernel);
173 1.15 tsutsui if ((loadfile(bootfile, marks, LOAD_KERNEL)) >= 0)
174 1.6 sekiya goto finish;
175 1.6 sekiya }
176 1.6 sekiya
177 1.19 matt bootpath = arcbios_GetEnvironmentVariable("OSLoadPartition");
178 1.5 sekiya
179 1.5 sekiya if (bootpath == NULL) {
180 1.5 sekiya /* XXX need to actually do the fixup */
181 1.15 tsutsui printf("\nPlease set the OSLoadPartition "
182 1.15 tsutsui "environment variable.\n");
183 1.5 sekiya return 0;
184 1.1 thorpej }
185 1.5 sekiya
186 1.5 sekiya /*
187 1.5 sekiya * Grab OSLoadFilename from ARCS.
188 1.5 sekiya */
189 1.5 sekiya
190 1.19 matt kernel = arcbios_GetEnvironmentVariable("OSLoadFilename");
191 1.5 sekiya
192 1.5 sekiya /*
193 1.5 sekiya * argv[1] is assumed to contain the name of the kernel to boot,
194 1.5 sekiya * if it a) does not start with a hyphen and b) does not contain
195 1.5 sekiya * an equals sign.
196 1.5 sekiya */
197 1.5 sekiya
198 1.5 sekiya if (((strchr(argv[1], '=')) == NULL) && (argv[1][0] != '-'))
199 1.5 sekiya kernel = argv[1];
200 1.5 sekiya
201 1.5 sekiya if (kernel != NULL) {
202 1.5 sekiya /*
203 1.5 sekiya * if the name contains parenthesis, we assume that it
204 1.5 sekiya * contains the bootpath and ignore anything passed through
205 1.5 sekiya * the environment
206 1.5 sekiya */
207 1.5 sekiya if (strchr(kernel, '('))
208 1.5 sekiya win = loadfile(kernel, marks, LOAD_KERNEL);
209 1.5 sekiya else {
210 1.5 sekiya strcpy(bootfile, bootpath);
211 1.5 sekiya strcat(bootfile, kernel);
212 1.5 sekiya win = loadfile(bootfile, marks, LOAD_KERNEL);
213 1.1 thorpej }
214 1.1 thorpej
215 1.5 sekiya } else {
216 1.5 sekiya i = 1;
217 1.5 sekiya while (kernelnames[i] != NULL) {
218 1.5 sekiya strcpy(bootfile, bootpath);
219 1.5 sekiya strcat(bootfile, kernelnames[i]);
220 1.5 sekiya kernel = kernelnames[i];
221 1.5 sekiya win = loadfile(bootfile, marks, LOAD_KERNEL);
222 1.5 sekiya if (win != -1)
223 1.5 sekiya break;
224 1.5 sekiya i++;
225 1.1 thorpej }
226 1.1 thorpej }
227 1.1 thorpej
228 1.5 sekiya if (win < 0) {
229 1.5 sekiya printf("Boot failed! Halting...\n");
230 1.5 sekiya return 0;
231 1.5 sekiya }
232 1.6 sekiya
233 1.6 sekiya finish:
234 1.16 tsutsui strlcpy(bi_bpath.bootpath, bootfile, BTINFO_BOOTPATH_LEN);
235 1.13 tsutsui bi_add(&bi_bpath, BTINFO_BOOTPATH, sizeof(bi_bpath));
236 1.1 thorpej
237 1.1 thorpej bi_syms.nsym = marks[MARK_NSYM];
238 1.1 thorpej bi_syms.ssym = marks[MARK_SYM];
239 1.1 thorpej bi_syms.esym = marks[MARK_END];
240 1.13 tsutsui bi_add(&bi_syms, BTINFO_SYMTAB, sizeof(bi_syms));
241 1.13 tsutsui entry = (void *)marks[MARK_ENTRY];
242 1.1 thorpej
243 1.5 sekiya if (debug) {
244 1.5 sekiya printf("Starting at %p\n\n", entry);
245 1.5 sekiya printf("nsym 0x%lx ssym 0x%lx esym 0x%lx\n", marks[MARK_NSYM],
246 1.5 sekiya marks[MARK_SYM], marks[MARK_END]);
247 1.5 sekiya }
248 1.13 tsutsui (*entry)(argc, argv, BOOTINFO_MAGIC, bootinfo);
249 1.3 thorpej
250 1.3 thorpej printf("Kernel returned! Halting...\n");
251 1.15 tsutsui return 0;
252 1.1 thorpej }
253