exec.c revision 1.1 1 /* $NetBSD: exec.c,v 1.1 1997/03/14 02:40:32 perry 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 /* starts NetBSD a.out kernel
43 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 exec_netbsd(file, loadaddr, boothowto, bootdev, consdev)
76 const char *file;
77 physaddr_t loadaddr;
78 int boothowto;
79 char *bootdev, *consdev; /* passed to kernel */
80 {
81 register int io;
82 struct exec x;
83 int cc, magic;
84 physaddr_t entry;
85 register physaddr_t cp;
86 u_long boot_argv[6];
87
88 #ifdef COMPAT_OLDBOOT
89 char *fsname, *devname;
90 int unit, part;
91 const char *filename;
92 int bootdevnr;
93 #else
94 u_long xbootinfo[2];
95 #endif
96
97 #ifdef DEBUG
98 printf("exec: file=%s loadaddr=0x%lx\n", file, loadaddr);
99 #endif
100 io = open(file, 0);
101 if (io < 0)
102 return(-1);
103
104 /*
105 * Read in the exec header, and validate it.
106 */
107 if (read(io, (char *)&x, sizeof(x)) != sizeof(x))
108 goto shread;
109 magic = N_GETMAGIC(x);
110
111 if ((magic != ZMAGIC) || (N_GETMID(x) != MID_MACHINE)){
112 #ifdef DEBUG
113 printf("invalid NetBSD kernel (%o/%ld)\n", magic, N_GETMID(x));
114 #endif
115 errno = EFTYPE;
116 goto closeout;
117 }
118
119 entry = x.a_entry & 0xffffff;
120
121 if(!loadaddr) loadaddr = (entry & 0x100000);
122
123 cp = loadaddr;
124
125 /*
126 * Leave a copy of the exec header before the text.
127 * The kernel may use this to verify that the
128 * symbols were loaded by this boot program.
129 */
130 vpbcopy(&x, cp, sizeof(x));
131 cp += sizeof(x);
132 /*
133 * Read in the text segment.
134 */
135
136 printf("%ld", x.a_text);
137
138 if (pread(io, cp, x.a_text - sizeof(x)) != x.a_text - sizeof(x))
139 goto shread;
140 cp += x.a_text-sizeof(x);
141
142 /*
143 * Read in the data segment.
144 */
145
146 printf("+%ld", x.a_data);
147
148 if (pread(io, cp, x.a_data) != x.a_data)
149 goto shread;
150 cp += x.a_data;
151
152 /*
153 * Zero out the BSS section.
154 * (Kernel doesn't care, but do it anyway.)
155 */
156
157
158 printf("+%ld", x.a_bss);
159
160 pbzero(cp, x.a_bss);
161 cp += x.a_bss;
162
163 /*
164 * Read in the symbol table and strings.
165 * (Always set the symtab size word.)
166 */
167 vpbcopy(&x.a_syms, cp, sizeof(x.a_syms));
168 cp += sizeof(x.a_syms);
169
170 if (x.a_syms > 0) {
171
172 /* Symbol table and string table length word. */
173
174 printf("+[%ld", x.a_syms);
175
176 if (pread(io, cp, x.a_syms) != x.a_syms)
177 goto shread;
178 cp += x.a_syms;
179
180 read(io, &cc, sizeof(cc));
181
182 vpbcopy(&cc, cp, sizeof(cc));
183 cp += sizeof(cc);
184
185 /* String table. Length word includes itself. */
186
187 printf("+%d]", cc);
188
189 cc -= sizeof(int);
190 if (cc <= 0)
191 goto shread;
192 if (pread(io, cp, cc) != cc)
193 goto shread;
194 cp += cc;
195 }
196 boot_argv[3] = (((u_int)cp + sizeof(int) - 1)) & (-sizeof(int));
197
198 printf("=0x%lx\n", cp - loadaddr);
199
200 boot_argv[0] = boothowto;
201
202 #ifdef COMPAT_OLDBOOT
203 /* prepare boot device information for kernel */
204 if(parsebootfile(file, &fsname, &devname, &unit, &part, &filename)
205 || strcmp(fsname, "ufs"))
206 bootdevnr = 0; /* XXX error out if parse error??? */
207 else {
208 int major;
209
210 if(!strcmp(devname, "hd")) {
211 /* generic BIOS disk, have to guess type */
212 struct open_file *f = &files[io]; /* XXX */
213
214 if(biosdisk_gettype(f) == DTYPE_SCSI)
215 devname = "sd";
216 else
217 devname = "wd";
218 }
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