boot.c revision 1.1 1 1.1 mrg /* $NetBSD: boot.c,v 1.1 1997/06/01 03:39:27 mrg Exp $ */
2 1.1 mrg
3 1.1 mrg /*-
4 1.1 mrg * Copyright (c) 1982, 1986, 1990, 1993
5 1.1 mrg * The Regents of the University of California. All rights reserved.
6 1.1 mrg *
7 1.1 mrg * Redistribution and use in source and binary forms, with or without
8 1.1 mrg * modification, are permitted provided that the following conditions
9 1.1 mrg * are met:
10 1.1 mrg * 1. Redistributions of source code must retain the above copyright
11 1.1 mrg * notice, this list of conditions and the following disclaimer.
12 1.1 mrg * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 mrg * notice, this list of conditions and the following disclaimer in the
14 1.1 mrg * documentation and/or other materials provided with the distribution.
15 1.1 mrg * 3. All advertising materials mentioning features or use of this software
16 1.1 mrg * must display the following acknowledgement:
17 1.1 mrg * This product includes software developed by the University of
18 1.1 mrg * California, Berkeley and its contributors.
19 1.1 mrg * 4. Neither the name of the University nor the names of its contributors
20 1.1 mrg * may be used to endorse or promote products derived from this software
21 1.1 mrg * without specific prior written permission.
22 1.1 mrg *
23 1.1 mrg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 1.1 mrg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 1.1 mrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 1.1 mrg * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 1.1 mrg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 1.1 mrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 1.1 mrg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 1.1 mrg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 1.1 mrg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 1.1 mrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 1.1 mrg * SUCH DAMAGE.
34 1.1 mrg *
35 1.1 mrg * @(#)boot.c 8.1 (Berkeley) 6/10/93
36 1.1 mrg */
37 1.1 mrg
38 1.1 mrg #include <sys/param.h>
39 1.1 mrg #include <sys/reboot.h>
40 1.1 mrg #include <a.out.h>
41 1.1 mrg
42 1.1 mrg #include <lib/libsa/stand.h>
43 1.1 mrg
44 1.1 mrg #include <sparc/stand/common/promdev.h>
45 1.1 mrg
46 1.1 mrg static void copyunix __P((int, char *));
47 1.1 mrg static void promsyms __P((int, struct exec *));
48 1.1 mrg int debug;
49 1.1 mrg int netif_debug;
50 1.1 mrg
51 1.1 mrg /*
52 1.1 mrg * Boot device is derived from ROM provided information.
53 1.1 mrg */
54 1.1 mrg #define DEFAULT_KERNEL "netbsd"
55 1.1 mrg
56 1.1 mrg extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
57 1.1 mrg unsigned long esym;
58 1.1 mrg char *strtab;
59 1.1 mrg int strtablen;
60 1.1 mrg char fbuf[80], dbuf[128];
61 1.1 mrg
62 1.1 mrg typedef void (*entry_t)__P((caddr_t, int, int, int, long, long));
63 1.1 mrg
64 1.1 mrg void loadfile __P((int, caddr_t));
65 1.1 mrg
66 1.1 mrg main()
67 1.1 mrg {
68 1.1 mrg int io;
69 1.1 mrg char *file;
70 1.1 mrg
71 1.1 mrg prom_init();
72 1.1 mrg
73 1.1 mrg printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
74 1.1 mrg printf(">> (%s, %s)\n", bootprog_maker, bootprog_date);
75 1.1 mrg
76 1.1 mrg file = prom_bootfile;
77 1.1 mrg if (file == 0 || *file == 0)
78 1.1 mrg file = DEFAULT_KERNEL;
79 1.1 mrg
80 1.1 mrg for (;;) {
81 1.1 mrg if (prom_boothow & RB_ASKNAME) {
82 1.1 mrg printf("device[%s]: ", prom_bootdevice);
83 1.1 mrg gets(dbuf);
84 1.1 mrg if (dbuf[0])
85 1.1 mrg prom_bootdevice = dbuf;
86 1.1 mrg printf("boot: ");
87 1.1 mrg gets(fbuf);
88 1.1 mrg if (fbuf[0])
89 1.1 mrg file = fbuf;
90 1.1 mrg }
91 1.1 mrg if ((io = open(file, 0)) >= 0)
92 1.1 mrg break;
93 1.1 mrg printf("open: %s: %s\n", file, strerror(errno));
94 1.1 mrg prom_boothow |= RB_ASKNAME;
95 1.1 mrg }
96 1.1 mrg
97 1.1 mrg printf("Booting %s @ 0x%x\n", file, LOADADDR);
98 1.1 mrg loadfile(io, LOADADDR);
99 1.1 mrg
100 1.1 mrg _rtt();
101 1.1 mrg }
102 1.1 mrg
103 1.1 mrg void
104 1.1 mrg loadfile(io, addr)
105 1.1 mrg register int io;
106 1.1 mrg register caddr_t addr;
107 1.1 mrg {
108 1.1 mrg register entry_t entry = (entry_t)LOADADDR;
109 1.1 mrg struct exec x;
110 1.1 mrg int i;
111 1.1 mrg
112 1.1 mrg i = read(io, (char *)&x, sizeof(x));
113 1.1 mrg if (i != sizeof(x) ||
114 1.1 mrg N_BADMAG(x)) {
115 1.1 mrg printf("Bad format\n");
116 1.1 mrg return;
117 1.1 mrg }
118 1.1 mrg printf("%d", x.a_text);
119 1.1 mrg if (N_GETMAGIC(x) == ZMAGIC) {
120 1.1 mrg entry = (entry_t)(addr+sizeof(struct exec));
121 1.1 mrg addr += sizeof(struct exec);
122 1.1 mrg }
123 1.1 mrg if (read(io, (char *)addr, x.a_text) != x.a_text)
124 1.1 mrg goto shread;
125 1.1 mrg addr += x.a_text;
126 1.1 mrg if (N_GETMAGIC(x) == ZMAGIC || N_GETMAGIC(x) == NMAGIC)
127 1.1 mrg while ((int)addr & __LDPGSZ)
128 1.1 mrg *addr++ = 0;
129 1.1 mrg printf("+%d", x.a_data);
130 1.1 mrg if (read(io, addr, x.a_data) != x.a_data)
131 1.1 mrg goto shread;
132 1.1 mrg addr += x.a_data;
133 1.1 mrg printf("+%d", x.a_bss);
134 1.1 mrg for (i = 0; i < x.a_bss; i++)
135 1.1 mrg *addr++ = 0;
136 1.1 mrg if (x.a_syms != 0) {
137 1.1 mrg bcopy(&x.a_syms, addr, sizeof(x.a_syms));
138 1.1 mrg addr += sizeof(x.a_syms);
139 1.1 mrg printf("+[%d", x.a_syms);
140 1.1 mrg if (read(io, addr, x.a_syms) != x.a_syms)
141 1.1 mrg goto shread;
142 1.1 mrg addr += x.a_syms;
143 1.1 mrg
144 1.1 mrg if (read(io, &strtablen, sizeof(int)) != sizeof(int))
145 1.1 mrg goto shread;
146 1.1 mrg
147 1.1 mrg bcopy(&strtablen, addr, sizeof(int));
148 1.1 mrg if (i = strtablen) {
149 1.1 mrg i -= sizeof(int);
150 1.1 mrg addr += sizeof(int);
151 1.1 mrg if (read(io, addr, i) != i)
152 1.1 mrg goto shread;
153 1.1 mrg addr += i;
154 1.1 mrg }
155 1.1 mrg printf("+%d]", i);
156 1.1 mrg esym = KERNBASE +
157 1.1 mrg (((int)addr + sizeof(int) - 1) & ~(sizeof(int) - 1));
158 1.1 mrg #if 0
159 1.1 mrg /*
160 1.1 mrg * The FORTH word `loadsyms' is mentioned in the
161 1.1 mrg * "Openboot command reference" book, but it seems it has
162 1.1 mrg * not been implemented on at least one machine..
163 1.1 mrg */
164 1.1 mrg promsyms(io, &x);
165 1.1 mrg #endif
166 1.1 mrg }
167 1.1 mrg printf("=0x%x\n", addr);
168 1.1 mrg close(io);
169 1.1 mrg
170 1.1 mrg /* Note: args 2-4 not used due to conflicts with SunOS loaders */
171 1.1 mrg (*entry)(cputyp == CPU_SUN4 ? LOADADDR : (caddr_t)promvec,
172 1.1 mrg 0, 0, 0, esym, DDB_MAGIC);
173 1.1 mrg return;
174 1.1 mrg
175 1.1 mrg shread:
176 1.1 mrg printf("boot: short read\n");
177 1.1 mrg return;
178 1.1 mrg }
179 1.1 mrg
180 1.1 mrg #if 0
181 1.1 mrg struct syms {
182 1.1 mrg u_int32_t value;
183 1.1 mrg u_int32_t index;
184 1.1 mrg };
185 1.1 mrg
186 1.1 mrg static void
187 1.1 mrg sort(syms, n)
188 1.1 mrg struct syms *syms;
189 1.1 mrg int n;
190 1.1 mrg {
191 1.1 mrg register struct syms *sj;
192 1.1 mrg register int i, j, k;
193 1.1 mrg register u_int32_t value, index;
194 1.1 mrg
195 1.1 mrg /* Insertion sort. This is O(n^2), but so what? */
196 1.1 mrg for (i = 1; i < n; i++) {
197 1.1 mrg /* save i'th entry */
198 1.1 mrg value = syms[i].value;
199 1.1 mrg index = syms[i].index;
200 1.1 mrg /* find j such that i'th entry goes before j'th */
201 1.1 mrg for (j = 0, sj = syms; j < i; j++, sj++)
202 1.1 mrg if (value < sj->value)
203 1.1 mrg break;
204 1.1 mrg /* slide up any additional entries */
205 1.1 mrg for (k = 0; k < (i - j); k++) {
206 1.1 mrg sj[k+1].value = sj[k].value;
207 1.1 mrg sj[k+1].index = sj[k].index;
208 1.1 mrg }
209 1.1 mrg sj->value = value;
210 1.1 mrg sj->index = index;
211 1.1 mrg }
212 1.1 mrg }
213 1.1 mrg
214 1.1 mrg void
215 1.1 mrg promsyms(fd, hp)
216 1.1 mrg int fd;
217 1.1 mrg struct exec *hp;
218 1.1 mrg {
219 1.1 mrg int i, n, strtablen;
220 1.1 mrg char *str, *p, *cp, buf[128];
221 1.1 mrg struct syms *syms;
222 1.1 mrg
223 1.1 mrg lseek(fd, sizeof(*hp)+hp->a_text+hp->a_data, SEEK_SET);
224 1.1 mrg n = hp->a_syms/sizeof(struct nlist);
225 1.1 mrg if (n == 0)
226 1.1 mrg return;
227 1.1 mrg syms = (struct syms *)alloc(n * sizeof(struct syms));
228 1.1 mrg
229 1.1 mrg printf("+[%x+", hp->a_syms);
230 1.1 mrg for (i = 0; i < n; i++) {
231 1.1 mrg struct nlist nlist;
232 1.1 mrg
233 1.1 mrg if (read(fd, &nlist, sizeof(nlist)) != sizeof(nlist)) {
234 1.1 mrg printf("promsyms: read failed\n");
235 1.1 mrg return;
236 1.1 mrg }
237 1.1 mrg syms[i].value = nlist.n_value;
238 1.1 mrg syms[i].index = nlist.n_un.n_strx - sizeof(strtablen);
239 1.1 mrg }
240 1.1 mrg
241 1.1 mrg sort(syms, n);
242 1.1 mrg
243 1.1 mrg if (read(fd, &strtablen, sizeof(strtablen)) != sizeof(strtablen)) {
244 1.1 mrg printf("promsym: read failed (strtablen)\n");
245 1.1 mrg return;
246 1.1 mrg }
247 1.1 mrg if (strtablen < sizeof(strtablen)) {
248 1.1 mrg printf("promsym: string table corrupted\n");
249 1.1 mrg return;
250 1.1 mrg }
251 1.1 mrg strtablen -= sizeof(strtablen);
252 1.1 mrg str = (char *)alloc(strtablen);
253 1.1 mrg
254 1.1 mrg printf("%x]", strtablen);
255 1.1 mrg if (read(fd, str, strtablen) != strtablen) {
256 1.1 mrg printf("promsym: read failed (strtab)\n");
257 1.1 mrg return;
258 1.1 mrg }
259 1.1 mrg
260 1.1 mrg sprintf(buf, "%x %d %x loadsyms", syms, n, str);
261 1.1 mrg (promvec->pv_fortheval.v2_eval)(buf);
262 1.1 mrg }
263 1.1 mrg #endif
264