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