exec.c revision 1.4
1/*	$NetBSD: exec.c,v 1.4 1997/09/17 18:02:11 drochner 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
55#include "libi386.h"
56#include "bootinfo.h"
57
58#ifdef COMPAT_OLDBOOT
59static int
60dev2major(devname, major)
61	char           *devname;
62	int            *major;
63{
64	static char    *devices[] = {"wd", "", "fd", "", "sd"};
65#define NUMDEVICES (sizeof(devices)/sizeof(char *))
66	int             i;
67
68	for (i = 0; i < NUMDEVICES; i++)
69		if (!strcmp(devname, devices[i])) {
70			*major = i;
71			return (0);
72		}
73	return (-1);
74}
75#endif
76
77extern struct btinfo_console btinfo_console;
78
79int
80exec_netbsd(file, loadaddr, boothowto)
81	const char     *file;
82	physaddr_t      loadaddr;
83	int             boothowto;
84{
85	register int    io;
86	struct exec     x;
87	int             cc, magic;
88	physaddr_t      entry;
89	register physaddr_t cp;
90	u_long          boot_argv[6];
91
92#ifdef COMPAT_OLDBOOT
93	char           *fsname, *devname;
94	int             unit, part;
95	const char     *filename;
96	int             bootdevnr;
97#endif
98
99#ifdef	DEBUG
100	printf("exec: file=%s loadaddr=0x%lx\n", file, loadaddr);
101#endif
102
103	BI_ALLOC(5); /* ??? */
104
105	BI_ADD(&btinfo_console, BTINFO_CONSOLE, sizeof(struct btinfo_console));
106
107	io = open(file, 0);
108	if (io < 0)
109		goto out;
110
111	/*
112	 * Read in the exec header, and validate it.
113	 */
114	if (read(io, (char *) &x, sizeof(x)) != sizeof(x))
115		goto shread;
116	magic = N_GETMAGIC(x);
117
118	if ((magic != ZMAGIC) || (N_GETMID(x) != MID_MACHINE)) {
119#ifdef DEBUG
120		printf("invalid NetBSD kernel (%o/%d)\n", magic, N_GETMID(x));
121#endif
122		errno = EFTYPE;
123		goto closeout;
124	}
125	entry = x.a_entry & 0xffffff;
126
127	if (!loadaddr)
128		loadaddr = (entry & 0x100000);
129
130	cp = loadaddr;
131
132	/*
133	 * Leave a copy of the exec header before the text.
134	 * The kernel may use this to verify that the
135	 * symbols were loaded by this boot program.
136	 */
137	vpbcopy(&x, cp, sizeof(x));
138	cp += sizeof(x);
139	/*
140	 * Read in the text segment.
141	 */
142
143	printf("%ld", x.a_text);
144
145	if (pread(io, cp, x.a_text - sizeof(x)) != x.a_text - sizeof(x))
146		goto shread;
147	cp += x.a_text - sizeof(x);
148
149	/*
150	 * Read in the data segment.
151	 */
152
153	printf("+%ld", x.a_data);
154
155	if (pread(io, cp, x.a_data) != x.a_data)
156		goto shread;
157	cp += x.a_data;
158
159	/*
160	 * Zero out the BSS section.
161	 * (Kernel doesn't care, but do it anyway.)
162	 */
163
164
165	printf("+%ld", x.a_bss);
166
167	pbzero(cp, x.a_bss);
168	cp += x.a_bss;
169
170	/*
171	 * Read in the symbol table and strings.
172	 * (Always set the symtab size word.)
173	 */
174	vpbcopy(&x.a_syms, cp, sizeof(x.a_syms));
175	cp += sizeof(x.a_syms);
176
177	if (x.a_syms > 0) {
178
179		/* Symbol table and string table length word. */
180
181		printf("+[%ld", x.a_syms);
182
183		if (pread(io, cp, x.a_syms) != x.a_syms)
184			goto shread;
185		cp += x.a_syms;
186
187		read(io, &cc, sizeof(cc));
188
189		vpbcopy(&cc, cp, sizeof(cc));
190		cp += sizeof(cc);
191
192		/* String table.  Length word includes itself. */
193
194		printf("+%d]", cc);
195
196		cc -= sizeof(int);
197		if (cc <= 0)
198			goto shread;
199		if (pread(io, cp, cc) != cc)
200			goto shread;
201		cp += cc;
202	}
203	boot_argv[3] = (((u_int) cp + sizeof(int) - 1)) & (-sizeof(int));
204
205	printf("=0x%lx\n", cp - loadaddr);
206
207	boot_argv[0] = boothowto;
208
209#ifdef COMPAT_OLDBOOT
210	/* prepare boot device information for kernel */
211	if (parsebootfile(file, &fsname, &devname, &unit, &part, &filename)
212	    || strcmp(fsname, "ufs"))
213		bootdevnr = 0;	/* XXX error out if parse error??? */
214	else {
215		int             major;
216
217		if (strcmp(devname, "hd") == 0) {
218			/* generic BIOS disk, have to guess type */
219			struct open_file *f = &files[io];	/* XXX */
220
221			if (biosdisk_gettype(f) == DTYPE_SCSI)
222				devname = "sd";
223			else
224				devname = "wd";
225
226			/*
227			 * The old boot block performed the following
228			 * conversion:
229			 *
230			 *	hdN -> Xd0
231			 *
232			 * where X is the type specified by the label.
233			 * We mimmick that here, for lack of any better
234			 * way of doing things.
235			 */
236			unit = 0;
237		}
238
239		if (dev2major(devname, &major))
240			bootdevnr = 0;	/* XXX error out??? */
241		else
242			bootdevnr = MAKEBOOTDEV(major, 0, 0, unit, part);
243	}
244
245	boot_argv[1] = bootdevnr;
246	boot_argv[2] = 0;	/* cyl offset, unused */
247#else				/* XXX to be specified */
248#ifdef PASS_BIOSGEOM
249	bi_getbiosgeom();
250#endif
251	boot_argv[1] = 0;
252	boot_argv[2] = vtophys(bootinfo);	/* cyl offset */
253#endif
254	/*
255	 * boot_argv[3] = end (set above)
256	 */
257	boot_argv[4] = getextmem();
258	boot_argv[5] = getbasemem();
259
260	close(io);
261
262#ifdef DEBUG
263	printf("Start @ 0x%lx ...\n", entry);
264#endif
265
266	startprog(entry, 6, boot_argv, 0x90000);
267	panic("exec returned");
268
269shread:
270	printf("exec: short read\n");
271	errno = EIO;
272closeout:
273	close(io);
274out:
275	BI_FREE();
276	bootinfo = 0;
277	return (-1);
278}
279