boot.c revision 1.14 1 1.14 agc /* $NetBSD: boot.c,v 1.14 2003/08/07 16:29:15 agc Exp $ */
2 1.3 simonb
3 1.3 simonb /*-
4 1.3 simonb * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 1.3 simonb * All rights reserved.
6 1.3 simonb *
7 1.3 simonb * This code is derived from software contributed to The NetBSD Foundation
8 1.3 simonb * by Jonathan Stone, Michael Hitch and Simon Burge.
9 1.3 simonb *
10 1.3 simonb * Redistribution and use in source and binary forms, with or without
11 1.3 simonb * modification, are permitted provided that the following conditions
12 1.3 simonb * are met:
13 1.3 simonb * 1. Redistributions of source code must retain the above copyright
14 1.3 simonb * notice, this list of conditions and the following disclaimer.
15 1.3 simonb * 2. Redistributions in binary form must reproduce the above copyright
16 1.3 simonb * notice, this list of conditions and the following disclaimer in the
17 1.3 simonb * documentation and/or other materials provided with the distribution.
18 1.3 simonb * 3. All advertising materials mentioning features or use of this software
19 1.3 simonb * must display the following acknowledgement:
20 1.3 simonb * This product includes software developed by the NetBSD
21 1.3 simonb * Foundation, Inc. and its contributors.
22 1.3 simonb * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.3 simonb * contributors may be used to endorse or promote products derived
24 1.3 simonb * from this software without specific prior written permission.
25 1.3 simonb *
26 1.3 simonb * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.3 simonb * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.3 simonb * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.3 simonb * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.3 simonb * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.3 simonb * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.3 simonb * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.3 simonb * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.3 simonb * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.3 simonb * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.3 simonb * POSSIBILITY OF SUCH DAMAGE.
37 1.3 simonb */
38 1.1 simonb
39 1.1 simonb /*
40 1.1 simonb * Copyright (c) 1992, 1993
41 1.1 simonb * The Regents of the University of California. All rights reserved.
42 1.1 simonb *
43 1.1 simonb * This code is derived from software contributed to Berkeley by
44 1.1 simonb * Ralph Campbell.
45 1.1 simonb *
46 1.1 simonb * Redistribution and use in source and binary forms, with or without
47 1.1 simonb * modification, are permitted provided that the following conditions
48 1.1 simonb * are met:
49 1.1 simonb * 1. Redistributions of source code must retain the above copyright
50 1.1 simonb * notice, this list of conditions and the following disclaimer.
51 1.1 simonb * 2. Redistributions in binary form must reproduce the above copyright
52 1.1 simonb * notice, this list of conditions and the following disclaimer in the
53 1.1 simonb * documentation and/or other materials provided with the distribution.
54 1.14 agc * 3. Neither the name of the University nor the names of its contributors
55 1.1 simonb * may be used to endorse or promote products derived from this software
56 1.1 simonb * without specific prior written permission.
57 1.1 simonb *
58 1.1 simonb * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59 1.1 simonb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 1.1 simonb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 1.1 simonb * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 1.1 simonb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 1.1 simonb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 1.1 simonb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 1.1 simonb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 1.1 simonb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 1.1 simonb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 1.1 simonb * SUCH DAMAGE.
69 1.1 simonb *
70 1.1 simonb * @(#)boot.c 8.1 (Berkeley) 6/10/93
71 1.1 simonb */
72 1.1 simonb
73 1.11 simonb #include <lib/libsa/stand.h>
74 1.11 simonb #include <lib/libsa/loadfile.h>
75 1.11 simonb #include <lib/libkern/libkern.h>
76 1.1 simonb
77 1.1 simonb #include <sys/param.h>
78 1.1 simonb #include <sys/exec.h>
79 1.1 simonb #include <sys/exec_elf.h>
80 1.11 simonb
81 1.1 simonb #include <machine/dec_prom.h>
82 1.1 simonb
83 1.5 simonb #include "common.h"
84 1.1 simonb #include "bootinfo.h"
85 1.1 simonb
86 1.11 simonb /*
87 1.11 simonb * We won't go overboard with gzip'd kernel names. After all we can
88 1.11 simonb * still boot a gzip'd kernel called "netbsd.pmax" - it doesn't need
89 1.11 simonb * the .gz suffix.
90 1.11 simonb */
91 1.6 simonb char *kernelnames[] = {
92 1.11 simonb "netbsd.pmax",
93 1.6 simonb "netbsd", "netbsd.gz",
94 1.11 simonb "netbsd.bak",
95 1.11 simonb "netbsd.old",
96 1.11 simonb "onetbsd",
97 1.11 simonb "gennetbsd",
98 1.6 simonb #ifdef notyet
99 1.11 simonb "netbsd.el",
100 1.6 simonb #endif /*notyet*/
101 1.6 simonb NULL
102 1.6 simonb };
103 1.6 simonb
104 1.6 simonb
105 1.12 simonb static char *devname __P((char *));
106 1.5 simonb int main __P((int, char **));
107 1.5 simonb
108 1.1 simonb /*
109 1.6 simonb * This gets arguments from the first stage boot lader, calls PROM routines
110 1.6 simonb * to open and load the program to boot, and then transfers execution to
111 1.6 simonb * that new program.
112 1.6 simonb *
113 1.6 simonb * Argv[0] should be something like "rz(0,0,0)netbsd" on a DECstation 3100.
114 1.6 simonb * Argv[0,1] should be something like "boot 5/rz0/netbsd" on a DECstation 5000.
115 1.6 simonb * The argument "-a" means netbsd should do an automatic reboot.
116 1.1 simonb */
117 1.1 simonb int
118 1.1 simonb main(argc, argv)
119 1.1 simonb int argc;
120 1.1 simonb char **argv;
121 1.1 simonb {
122 1.12 simonb char *name, **namep, *dev, *kernel;
123 1.6 simonb char bootname[PATH_MAX], bootpath[PATH_MAX];
124 1.6 simonb int entry, win;
125 1.1 simonb u_long marks[MARK_MAX];
126 1.1 simonb struct btinfo_symtab bi_syms;
127 1.1 simonb struct btinfo_bootpath bi_bpath;
128 1.1 simonb
129 1.11 simonb /* print a banner */
130 1.11 simonb printf("\n");
131 1.11 simonb printf("NetBSD/pmax " NETBSD_VERS " " BOOT_TYPE_NAME " Bootstrap, Revision %s\n",
132 1.11 simonb bootprog_rev);
133 1.11 simonb printf("(%s, %s)\n", bootprog_maker, bootprog_date);
134 1.11 simonb printf("\n");
135 1.6 simonb
136 1.1 simonb /* initialise bootinfo structure early */
137 1.1 simonb bi_init(BOOTINFO_ADDR);
138 1.1 simonb
139 1.1 simonb /* check for DS5000 boot */
140 1.1 simonb if (strcmp(argv[0], "boot") == 0) {
141 1.1 simonb argc--;
142 1.1 simonb argv++;
143 1.1 simonb }
144 1.6 simonb name = argv[0];
145 1.6 simonb printf("Boot: %s\n", name);
146 1.1 simonb
147 1.13 soren /* NOTE: devname() can modify bootname[]. */
148 1.6 simonb strcpy(bootname, argv[0]);
149 1.12 simonb if ((kernel = devname(bootname)) == NULL) {
150 1.6 simonb dev = bootname;
151 1.6 simonb name = NULL;
152 1.6 simonb }
153 1.2 simonb
154 1.11 simonb memset(marks, 0, sizeof marks);
155 1.6 simonb if (name != NULL)
156 1.11 simonb win = (loadfile(name, marks, LOAD_KERNEL) == 0);
157 1.6 simonb else {
158 1.6 simonb win = 0;
159 1.6 simonb for (namep = kernelnames, win = 0; *namep != NULL && !win;
160 1.6 simonb namep++) {
161 1.12 simonb kernel = *namep;
162 1.6 simonb strcpy(bootpath, dev);
163 1.12 simonb strcat(bootpath, kernel);
164 1.6 simonb printf("Loading: %s\n", bootpath);
165 1.6 simonb win = (loadfile(bootpath, marks, LOAD_ALL) != -1);
166 1.12 simonb if (win) {
167 1.6 simonb name = bootpath;
168 1.12 simonb }
169 1.6 simonb }
170 1.6 simonb }
171 1.6 simonb if (!win)
172 1.5 simonb goto fail;
173 1.5 simonb
174 1.12 simonb strncpy(bi_bpath.bootpath, kernel, BTINFO_BOOTPATH_LEN);
175 1.6 simonb bi_add(&bi_bpath, BTINFO_BOOTPATH, sizeof(bi_bpath));
176 1.6 simonb
177 1.1 simonb entry = marks[MARK_ENTRY];
178 1.1 simonb bi_syms.nsym = marks[MARK_NSYM];
179 1.1 simonb bi_syms.ssym = marks[MARK_SYM];
180 1.1 simonb bi_syms.esym = marks[MARK_END];
181 1.1 simonb bi_add(&bi_syms, BTINFO_SYMTAB, sizeof(bi_syms));
182 1.1 simonb
183 1.1 simonb printf("Starting at 0x%x\n\n", entry);
184 1.1 simonb if (callv == &callvec)
185 1.1 simonb startprog(entry, entry, argc, argv, 0, 0,
186 1.1 simonb BOOTINFO_MAGIC, BOOTINFO_ADDR);
187 1.1 simonb else
188 1.1 simonb startprog(entry, entry, argc, argv, DEC_PROM_MAGIC,
189 1.1 simonb callv, BOOTINFO_MAGIC, BOOTINFO_ADDR);
190 1.6 simonb (void)printf("KERNEL RETURNED!\n");
191 1.5 simonb
192 1.5 simonb fail:
193 1.5 simonb (void)printf("Boot failed! Halting...\n");
194 1.5 simonb return (0);
195 1.6 simonb }
196 1.6 simonb
197 1.6 simonb
198 1.6 simonb /*
199 1.6 simonb * Check whether or not fname is a device name only or a full
200 1.6 simonb * bootpath including the kernel name. This code to do this
201 1.6 simonb * is copied from loadfile() in the first stage bootblocks.
202 1.12 simonb * Returns the kernel name, or NULL if no kernel name specified.
203 1.6 simonb *
204 1.6 simonb * NOTE: fname will be modified if it's of the form N/rzY
205 1.6 simonb * without a trailing slash.
206 1.6 simonb */
207 1.12 simonb static char *
208 1.12 simonb devname(fname)
209 1.6 simonb char *fname;
210 1.6 simonb {
211 1.6 simonb char c;
212 1.6 simonb
213 1.6 simonb while ((c = *fname++) != '\0') {
214 1.6 simonb if (c == ')')
215 1.6 simonb break;
216 1.6 simonb if (c != '/')
217 1.6 simonb continue;
218 1.6 simonb while ((c = *fname++) != '\0')
219 1.6 simonb if (c == '/')
220 1.6 simonb break;
221 1.6 simonb /*
222 1.6 simonb * Make "N/rzY" with no trailing '/' valid by adding
223 1.11 simonb * the extra '/' before appending 'boot.pmax' to the path.
224 1.6 simonb */
225 1.6 simonb if (c != '/') {
226 1.6 simonb fname--;
227 1.6 simonb *fname++ = '/';
228 1.6 simonb *fname = '\0';
229 1.6 simonb }
230 1.6 simonb break;
231 1.6 simonb }
232 1.12 simonb return (*fname == '\0' ? NULL : fname);
233 1.1 simonb }
234