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