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