exec.c revision 1.2 1 /* $NetBSD: exec.c,v 1.2 1997/03/22 01:48:33 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 1982, 1986, 1990, 1993
5 * The Regents of the University of California. All rights reserved.
6 * Copyright (c) 1996
7 * Matthias Drochner. All rights reserved.
8 * Copyright (c) 1996
9 * Perry E. Metzger. All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * @(#)boot.c 8.1 (Berkeley) 6/10/93
40 */
41
42 /*
43 * starts NetBSD a.out kernel needs lowlevel startup from startprog.S
44 */
45
46 #include <sys/param.h>
47 #include <sys/exec_aout.h>
48 #include <sys/reboot.h>
49 #ifdef COMPAT_OLDBOOT
50 #include <sys/disklabel.h>
51 #endif
52
53 #include <lib/libsa/stand.h>
54 #include "libi386.h"
55
56 #ifdef COMPAT_OLDBOOT
57 static int
58 dev2major(devname, major)
59 char *devname;
60 int *major;
61 {
62 static char *devices[] = {"wd", "", "fd", "", "sd"};
63 #define NUMDEVICES (sizeof(devices)/sizeof(char *))
64 int i;
65
66 for (i = 0; i < NUMDEVICES; i++)
67 if (!strcmp(devname, devices[i])) {
68 *major = i;
69 return (0);
70 }
71 return (-1);
72 }
73 #endif
74
75 int
76 exec_netbsd(file, loadaddr, boothowto, bootdev, consdev)
77 const char *file;
78 physaddr_t loadaddr;
79 int boothowto;
80 char *bootdev, *consdev; /* passed to kernel */
81 {
82 register int io;
83 struct exec x;
84 int cc, magic;
85 physaddr_t entry;
86 register physaddr_t cp;
87 u_long boot_argv[6];
88
89 #ifdef COMPAT_OLDBOOT
90 char *fsname, *devname;
91 int unit, part;
92 const char *filename;
93 int bootdevnr;
94 #else
95 u_long xbootinfo[2];
96 #endif
97
98 #ifdef DEBUG
99 printf("exec: file=%s loadaddr=0x%lx\n", file, loadaddr);
100 #endif
101 io = open(file, 0);
102 if (io < 0)
103 return (-1);
104
105 /*
106 * Read in the exec header, and validate it.
107 */
108 if (read(io, (char *) &x, sizeof(x)) != sizeof(x))
109 goto shread;
110 magic = N_GETMAGIC(x);
111
112 if ((magic != ZMAGIC) || (N_GETMID(x) != MID_MACHINE)) {
113 #ifdef DEBUG
114 printf("invalid NetBSD kernel (%o/%ld)\n", magic, N_GETMID(x));
115 #endif
116 errno = EFTYPE;
117 goto closeout;
118 }
119 entry = x.a_entry & 0xffffff;
120
121 if (!loadaddr)
122 loadaddr = (entry & 0x100000);
123
124 cp = loadaddr;
125
126 /*
127 * Leave a copy of the exec header before the text.
128 * The kernel may use this to verify that the
129 * symbols were loaded by this boot program.
130 */
131 vpbcopy(&x, cp, sizeof(x));
132 cp += sizeof(x);
133 /*
134 * Read in the text segment.
135 */
136
137 printf("%ld", x.a_text);
138
139 if (pread(io, cp, x.a_text - sizeof(x)) != x.a_text - sizeof(x))
140 goto shread;
141 cp += x.a_text - sizeof(x);
142
143 /*
144 * Read in the data segment.
145 */
146
147 printf("+%ld", x.a_data);
148
149 if (pread(io, cp, x.a_data) != x.a_data)
150 goto shread;
151 cp += x.a_data;
152
153 /*
154 * Zero out the BSS section.
155 * (Kernel doesn't care, but do it anyway.)
156 */
157
158
159 printf("+%ld", x.a_bss);
160
161 pbzero(cp, x.a_bss);
162 cp += x.a_bss;
163
164 /*
165 * Read in the symbol table and strings.
166 * (Always set the symtab size word.)
167 */
168 vpbcopy(&x.a_syms, cp, sizeof(x.a_syms));
169 cp += sizeof(x.a_syms);
170
171 if (x.a_syms > 0) {
172
173 /* Symbol table and string table length word. */
174
175 printf("+[%ld", x.a_syms);
176
177 if (pread(io, cp, x.a_syms) != x.a_syms)
178 goto shread;
179 cp += x.a_syms;
180
181 read(io, &cc, sizeof(cc));
182
183 vpbcopy(&cc, cp, sizeof(cc));
184 cp += sizeof(cc);
185
186 /* String table. Length word includes itself. */
187
188 printf("+%d]", cc);
189
190 cc -= sizeof(int);
191 if (cc <= 0)
192 goto shread;
193 if (pread(io, cp, cc) != cc)
194 goto shread;
195 cp += cc;
196 }
197 boot_argv[3] = (((u_int) cp + sizeof(int) - 1)) & (-sizeof(int));
198
199 printf("=0x%lx\n", cp - loadaddr);
200
201 boot_argv[0] = boothowto;
202
203 #ifdef COMPAT_OLDBOOT
204 /* prepare boot device information for kernel */
205 if (parsebootfile(file, &fsname, &devname, &unit, &part, &filename)
206 || strcmp(fsname, "ufs"))
207 bootdevnr = 0; /* XXX error out if parse error??? */
208 else {
209 int major;
210
211 if (!strcmp(devname, "hd")) {
212 /* generic BIOS disk, have to guess type */
213 struct open_file *f = &files[io]; /* XXX */
214
215 if (biosdisk_gettype(f) == DTYPE_SCSI)
216 devname = "sd";
217 else
218 devname = "wd";
219 }
220 if (dev2major(devname, &major))
221 bootdevnr = 0; /* XXX error out??? */
222 else
223 bootdevnr = MAKEBOOTDEV(major, 0, 0, unit, part);
224 }
225
226 boot_argv[1] = bootdevnr;
227 boot_argv[2] = 0; /* cyl offset, unused */
228 #else /* XXX to be specified */
229 xbootinfo[0] = vtophys(bootdev);
230 xbootinfo[1] = vtophys(consdev);
231 boot_argv[1] = 0;
232 boot_argv[2] = vtophys(xbootinfo); /* XXX cyl offset */
233 #endif
234 /*
235 * boot_argv[3] = end (set above)
236 */
237 boot_argv[4] = getextmem();
238 boot_argv[5] = getbasemem();
239
240 close(io);
241
242 #ifdef DEBUG
243 printf("Start @ 0x%lx ...\n", entry);
244 #endif
245
246 startprog(entry, 6, boot_argv, 0x90000);
247 panic("exec returned");
248
249 shread:
250 printf("exec: short read\n");
251 errno = EIO;
252 closeout:
253 close(io);
254 return (-1);
255 }
256