xref: /openbsd/sys/arch/alpha/stand/boot/boot.c (revision df930be7)
1*df930be7Sderaadt /*	$NetBSD: boot.c,v 1.3 1995/06/28 00:58:48 cgd Exp $	*/
2*df930be7Sderaadt 
3*df930be7Sderaadt /*
4*df930be7Sderaadt  * Copyright (c) 1992, 1993
5*df930be7Sderaadt  *	The Regents of the University of California.  All rights reserved.
6*df930be7Sderaadt  *
7*df930be7Sderaadt  * This code is derived from software contributed to Berkeley by
8*df930be7Sderaadt  * Ralph Campbell.
9*df930be7Sderaadt  *
10*df930be7Sderaadt  * Redistribution and use in source and binary forms, with or without
11*df930be7Sderaadt  * modification, are permitted provided that the following conditions
12*df930be7Sderaadt  * are met:
13*df930be7Sderaadt  * 1. Redistributions of source code must retain the above copyright
14*df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer.
15*df930be7Sderaadt  * 2. Redistributions in binary form must reproduce the above copyright
16*df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer in the
17*df930be7Sderaadt  *    documentation and/or other materials provided with the distribution.
18*df930be7Sderaadt  * 3. All advertising materials mentioning features or use of this software
19*df930be7Sderaadt  *    must display the following acknowledgement:
20*df930be7Sderaadt  *	This product includes software developed by the University of
21*df930be7Sderaadt  *	California, Berkeley and its contributors.
22*df930be7Sderaadt  * 4. Neither the name of the University nor the names of its contributors
23*df930be7Sderaadt  *    may be used to endorse or promote products derived from this software
24*df930be7Sderaadt  *    without specific prior written permission.
25*df930be7Sderaadt  *
26*df930be7Sderaadt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27*df930be7Sderaadt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28*df930be7Sderaadt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29*df930be7Sderaadt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30*df930be7Sderaadt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31*df930be7Sderaadt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32*df930be7Sderaadt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33*df930be7Sderaadt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34*df930be7Sderaadt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35*df930be7Sderaadt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36*df930be7Sderaadt  * SUCH DAMAGE.
37*df930be7Sderaadt  *
38*df930be7Sderaadt  *	@(#)boot.c	8.1 (Berkeley) 6/10/93
39*df930be7Sderaadt  */
40*df930be7Sderaadt 
41*df930be7Sderaadt #include <lib/libsa/stand.h>
42*df930be7Sderaadt 
43*df930be7Sderaadt #include <sys/param.h>
44*df930be7Sderaadt #include <sys/exec.h>
45*df930be7Sderaadt 
46*df930be7Sderaadt #include <machine/prom.h>
47*df930be7Sderaadt 
48*df930be7Sderaadt #include "../../include/coff.h"
49*df930be7Sderaadt #define _KERNEL
50*df930be7Sderaadt #include "../../include/pte.h"
51*df930be7Sderaadt 
52*df930be7Sderaadt static int aout_exec __P((int, struct exec *, u_int64_t *));
53*df930be7Sderaadt static int coff_exec __P((int, struct exechdr *, u_int64_t *));
54*df930be7Sderaadt static int loadfile __P((char *, u_int64_t *));
55*df930be7Sderaadt 
56*df930be7Sderaadt char line[64] = "/netbsd";
57*df930be7Sderaadt 
58*df930be7Sderaadt char boot_file[128];
59*df930be7Sderaadt char boot_dev[128];
60*df930be7Sderaadt char boot_flags[128];
61*df930be7Sderaadt char boot_console[8];
62*df930be7Sderaadt 
63*df930be7Sderaadt extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
64*df930be7Sderaadt 
65*df930be7Sderaadt #define	KERNEL_ARGC	4
66*df930be7Sderaadt char *kernel_argv[KERNEL_ARGC+1] = {
67*df930be7Sderaadt 	boot_file,
68*df930be7Sderaadt 	boot_flags,
69*df930be7Sderaadt 	boot_console,
70*df930be7Sderaadt 	boot_dev,
71*df930be7Sderaadt 	NULL
72*df930be7Sderaadt };
73*df930be7Sderaadt 
74*df930be7Sderaadt vm_offset_t ffp_save, ptbr_save;
75*df930be7Sderaadt 
76*df930be7Sderaadt void
77*df930be7Sderaadt main(argc, argv, envp)
78*df930be7Sderaadt 	int argc;
79*df930be7Sderaadt 	char **argv;
80*df930be7Sderaadt 	char **envp;
81*df930be7Sderaadt {
82*df930be7Sderaadt 	u_int64_t entry;
83*df930be7Sderaadt 	int ask;
84*df930be7Sderaadt 	prom_return_t ret;
85*df930be7Sderaadt 
86*df930be7Sderaadt #ifdef notdef
87*df930be7Sderaadt 	{
88*df930be7Sderaadt 		extern char *_EDATA, *_end;
89*df930be7Sderaadt 		bzero(_EDATA, _end - _EDATA);
90*df930be7Sderaadt 	}
91*df930be7Sderaadt #endif
92*df930be7Sderaadt 
93*df930be7Sderaadt 	/* Init prom callback vector. */
94*df930be7Sderaadt 	init_prom_calls();
95*df930be7Sderaadt 
96*df930be7Sderaadt 	/* print a banner */
97*df930be7Sderaadt 	printf("\n\n");
98*df930be7Sderaadt 	printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
99*df930be7Sderaadt 	printf("(%s, %s)\n", bootprog_maker, bootprog_date);
100*df930be7Sderaadt 	printf("\n");
101*df930be7Sderaadt 
102*df930be7Sderaadt 	/* switch to OSF pal code. */
103*df930be7Sderaadt 	OSFpal();
104*df930be7Sderaadt 
105*df930be7Sderaadt 	printf("\n");
106*df930be7Sderaadt 
107*df930be7Sderaadt 	prom_getenv(PROM_E_BOOTED_DEV, boot_dev, sizeof(boot_dev));
108*df930be7Sderaadt 	prom_getenv(PROM_E_BOOTED_FILE, boot_file, sizeof(boot_file));
109*df930be7Sderaadt 	prom_getenv(PROM_E_BOOTED_OSFLAGS, boot_flags, sizeof(boot_flags));
110*df930be7Sderaadt 	prom_getenv(PROM_E_TTY_DEV, boot_console, sizeof(boot_console));
111*df930be7Sderaadt 
112*df930be7Sderaadt 	printf("boot_dev = \"%s\"\n", boot_dev);
113*df930be7Sderaadt 	printf("boot_file = \"%s\"\n", boot_file);
114*df930be7Sderaadt 	printf("boot_flags = \"%s\"\n", boot_flags);
115*df930be7Sderaadt 	printf("boot_console = \"%s\"\n", boot_console);
116*df930be7Sderaadt 
117*df930be7Sderaadt 	if (boot_file[0] == '\0')
118*df930be7Sderaadt 		bcopy(line, boot_file, strlen(line)+1);
119*df930be7Sderaadt 
120*df930be7Sderaadt #ifdef JUSTASK
121*df930be7Sderaadt 	ask = 1;
122*df930be7Sderaadt #else
123*df930be7Sderaadt 	ask = 0;
124*df930be7Sderaadt #endif
125*df930be7Sderaadt 	for (;;) {
126*df930be7Sderaadt 		if (ask) {
127*df930be7Sderaadt 			(void)printf("Boot: ");
128*df930be7Sderaadt 			gets(line);
129*df930be7Sderaadt 			if (line[0] == '\0')
130*df930be7Sderaadt 				continue;
131*df930be7Sderaadt 			if (!strcmp(line, "halt"))
132*df930be7Sderaadt 				halt();
133*df930be7Sderaadt /* XXX TURN LINE INTO BOOT FILE/FLAGS */
134*df930be7Sderaadt 			bcopy(line, boot_file, strlen(line)+1);
135*df930be7Sderaadt 		} else
136*df930be7Sderaadt 			(void)printf("Boot: %s %s\n", boot_file, boot_flags);
137*df930be7Sderaadt 
138*df930be7Sderaadt 		if (!loadfile(boot_file, &entry)) {
139*df930be7Sderaadt 
140*df930be7Sderaadt printf("calling %lx with %lx, %lx, %lx, %lx, %lx\n", entry,
141*df930be7Sderaadt ffp_save, ptbr_save, KERNEL_ARGC, kernel_argv, NULL);
142*df930be7Sderaadt 			(*(void (*)())entry)(ffp_save, ptbr_save, KERNEL_ARGC,
143*df930be7Sderaadt 			    kernel_argv, NULL);
144*df930be7Sderaadt 		}
145*df930be7Sderaadt 
146*df930be7Sderaadt 		ask = 1;
147*df930be7Sderaadt 	}
148*df930be7Sderaadt 	/* NOTREACHED */
149*df930be7Sderaadt }
150*df930be7Sderaadt 
151*df930be7Sderaadt /*
152*df930be7Sderaadt  * Open 'filename', read in program and return the entry point or -1 if error.
153*df930be7Sderaadt  */
154*df930be7Sderaadt static int
155*df930be7Sderaadt loadfile(fname, entryp)
156*df930be7Sderaadt 	char *fname;
157*df930be7Sderaadt 	u_int64_t *entryp;
158*df930be7Sderaadt {
159*df930be7Sderaadt 	struct devices *dp;
160*df930be7Sderaadt 	union {
161*df930be7Sderaadt 		struct exec aout;
162*df930be7Sderaadt 		struct exechdr coff;
163*df930be7Sderaadt 	} hdr;
164*df930be7Sderaadt 	ssize_t nr;
165*df930be7Sderaadt 	int fd, rval;
166*df930be7Sderaadt 
167*df930be7Sderaadt 	/* Open the file. */
168*df930be7Sderaadt 	rval = 1;
169*df930be7Sderaadt 	if ((fd = open(fname, 0)) < 0) {
170*df930be7Sderaadt 		(void)printf("open error: %d\n", errno);
171*df930be7Sderaadt 		goto err;
172*df930be7Sderaadt 	}
173*df930be7Sderaadt 
174*df930be7Sderaadt 	/* Read the exec header. */
175*df930be7Sderaadt 	if ((nr = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) {
176*df930be7Sderaadt 		(void)printf("read error: %d\n", errno);
177*df930be7Sderaadt 		goto err;
178*df930be7Sderaadt 	}
179*df930be7Sderaadt 
180*df930be7Sderaadt 	/* Exec a.out or COFF. */
181*df930be7Sderaadt 	rval = N_COFFBADMAG(hdr.coff.a) ?
182*df930be7Sderaadt 	    aout_exec(fd, &hdr.aout, entryp) :
183*df930be7Sderaadt 	    coff_exec(fd, &hdr.coff, entryp);
184*df930be7Sderaadt 
185*df930be7Sderaadt err:
186*df930be7Sderaadt #ifndef SMALL
187*df930be7Sderaadt 	if (fd >= 0)
188*df930be7Sderaadt 		(void)close(fd);
189*df930be7Sderaadt #endif
190*df930be7Sderaadt 	if (rval)
191*df930be7Sderaadt 		(void)printf("can't boot '%s'\n", fname);
192*df930be7Sderaadt 	return (rval);
193*df930be7Sderaadt }
194*df930be7Sderaadt 
195*df930be7Sderaadt static int
196*df930be7Sderaadt aout_exec(fd, aout, entryp)
197*df930be7Sderaadt 	int fd;
198*df930be7Sderaadt 	struct exec *aout;
199*df930be7Sderaadt 	u_int64_t *entryp;
200*df930be7Sderaadt {
201*df930be7Sderaadt 	size_t sz;
202*df930be7Sderaadt 
203*df930be7Sderaadt 	/* Check the magic number. */
204*df930be7Sderaadt 	if (N_GETMAGIC(*aout) != OMAGIC) {
205*df930be7Sderaadt 		(void)printf("bad magic: %o\n", N_GETMAGIC(*aout));
206*df930be7Sderaadt 		return (1);
207*df930be7Sderaadt 	}
208*df930be7Sderaadt 
209*df930be7Sderaadt 	/* Read in text, data. */
210*df930be7Sderaadt 	(void)printf("%lu+%lu", aout->a_text, aout->a_data);
211*df930be7Sderaadt 	if (lseek(fd, (off_t)N_TXTOFF(*aout), SEEK_SET) < 0) {
212*df930be7Sderaadt 		(void)printf("lseek: %d\n", errno);
213*df930be7Sderaadt 		return (1);
214*df930be7Sderaadt 	}
215*df930be7Sderaadt 	sz = aout->a_text + aout->a_data;
216*df930be7Sderaadt 	if (read(fd, (void *)aout->a_entry, sz) != sz) {
217*df930be7Sderaadt 		(void)printf("read text/data: %d\n", errno);
218*df930be7Sderaadt 		return (1);
219*df930be7Sderaadt 	}
220*df930be7Sderaadt 
221*df930be7Sderaadt 	/* Zero out bss. */
222*df930be7Sderaadt 	if (aout->a_bss != 0) {
223*df930be7Sderaadt 		(void)printf("+%lu", aout->a_bss);
224*df930be7Sderaadt 		bzero(aout->a_entry + sz, aout->a_bss);
225*df930be7Sderaadt 	}
226*df930be7Sderaadt 
227*df930be7Sderaadt 	ffp_save = aout->a_entry + aout->a_text + aout->a_data + aout->a_bss;
228*df930be7Sderaadt 	ffp_save = k0segtophys((ffp_save + PGOFSET & ~PGOFSET)) >> PGSHIFT;
229*df930be7Sderaadt 	ffp_save += 2;		/* XXX OSF/1 does this, no idea why. */
230*df930be7Sderaadt 
231*df930be7Sderaadt 	(void)printf("\n");
232*df930be7Sderaadt 	*entryp = aout->a_entry;
233*df930be7Sderaadt 	return (0);
234*df930be7Sderaadt }
235*df930be7Sderaadt 
236*df930be7Sderaadt static int
237*df930be7Sderaadt coff_exec(fd, coff, entryp)
238*df930be7Sderaadt 	int fd;
239*df930be7Sderaadt 	struct exechdr *coff;
240*df930be7Sderaadt 	u_int64_t *entryp;
241*df930be7Sderaadt {
242*df930be7Sderaadt 
243*df930be7Sderaadt 	/* Read in text. */
244*df930be7Sderaadt 	(void)printf("%lu", coff->a.tsize);
245*df930be7Sderaadt 	(void)lseek(fd, N_COFFTXTOFF(coff->f, coff->a), 0);
246*df930be7Sderaadt 	if (read(fd, (void *)coff->a.text_start, coff->a.tsize) !=
247*df930be7Sderaadt 	    coff->a.tsize) {
248*df930be7Sderaadt 		(void)printf("read text: %d\n", errno);
249*df930be7Sderaadt 		return (1);
250*df930be7Sderaadt 	}
251*df930be7Sderaadt 
252*df930be7Sderaadt 	/* Read in data. */
253*df930be7Sderaadt 	if (coff->a.dsize != 0) {
254*df930be7Sderaadt 		(void)printf("+%lu", coff->a.dsize);
255*df930be7Sderaadt 		if (read(fd, (void *)coff->a.data_start, coff->a.dsize) !=
256*df930be7Sderaadt 		    coff->a.dsize) {
257*df930be7Sderaadt 			(void)printf("read data: %d\n", errno);
258*df930be7Sderaadt 			return (1);
259*df930be7Sderaadt 		}
260*df930be7Sderaadt 	}
261*df930be7Sderaadt 
262*df930be7Sderaadt 
263*df930be7Sderaadt 	/* Zero out bss. */
264*df930be7Sderaadt 	if (coff->a.bsize != 0) {
265*df930be7Sderaadt 		(void)printf("+%lu", coff->a.bsize);
266*df930be7Sderaadt 		bzero(coff->a.bss_start, coff->a.bsize);
267*df930be7Sderaadt 	}
268*df930be7Sderaadt 
269*df930be7Sderaadt 	ffp_save = coff->a.text_start + coff->a.tsize;
270*df930be7Sderaadt 	if (ffp_save < coff->a.data_start + coff->a.dsize)
271*df930be7Sderaadt 		ffp_save = coff->a.data_start + coff->a.dsize;
272*df930be7Sderaadt 	if (ffp_save < coff->a.bss_start + coff->a.bsize)
273*df930be7Sderaadt 		ffp_save = coff->a.bss_start + coff->a.bsize;
274*df930be7Sderaadt 	ffp_save = k0segtophys((ffp_save + PGOFSET & ~PGOFSET)) >> PGSHIFT;
275*df930be7Sderaadt 	ffp_save += 2;		/* XXX OSF/1 does this, no idea why. */
276*df930be7Sderaadt 
277*df930be7Sderaadt 	(void)printf("\n");
278*df930be7Sderaadt 	*entryp = coff->a.entry;
279*df930be7Sderaadt 	return (0);
280*df930be7Sderaadt }
281