added my responsibility for the `cpm' port
[unix-history] / sys / i386 / stand / boot.c
CommitLineData
15637ed4
RG
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * William Jolitz.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
e73885af
RG
35 *
36 * from: @(#)boot.c 7.3 (Berkeley) 5/4/91
37 * $Id$
15637ed4
RG
38 */
39
40#ifdef lint
41char copyright[] =
42"@(#) Copyright (c) 1990 The Regents of the University of California.\n\
43 All rights reserved.\n";
44#endif /* not lint */
45
15637ed4
RG
46#include "param.h"
47#include "reboot.h"
48#include <a.out.h>
49#include "saio.h"
50#include "disklabel.h"
51#include "dinode.h"
52
53/*
54 * Boot program, loaded by boot block from remaing 7.5K of boot area.
55 * Sifts through disklabel and attempts to load an program image of
56 * a standalone program off the disk. If keyboard is hit during load,
57 * or if an error is encounter, try alternate files.
58 */
59
60char *files[] = { "386bsd", "386bsd.alt", "386bsd.old", "boot" , "vmunix", 0};
61int retry = 0;
62extern struct disklabel disklabel;
63extern int bootdev, cyloffset;
64static unsigned char *biosparams = (char *) 0x9ff00; /* XXX */
65
66/*
67 * Boot program... loads /boot out of filesystem indicated by arguements.
68 * We assume an autoboot unless we detect a misconfiguration.
69 */
70
71main(dev, unit, off)
72{
73 register struct disklabel *lp;
74 register int io;
75 register char **bootfile = files;
76 int howto = 0;
77 extern int scsisn; /* XXX */
78
79
80 /* are we a disk, if so look at disklabel and do things */
81 lp = &disklabel;
82 if (lp->d_type == DTYPE_SCSI) /* XXX */
83 off = htonl(scsisn); /* XXX */
84
85/*printf("cyl %x %x hd %x sect %x ", biosparams[0], biosparams[1], biosparams[2], biosparams[0xe]);
86 printf("dev %x unit %x off %d\n", dev, unit, off);*/
87
88 if (lp->d_magic == DISKMAGIC) {
89 /*
90 * Synthesize bootdev from dev, unit, type and partition
91 * information from the block 0 bootstrap.
92 * It's dirty work, but someone's got to do it.
93 * This will be used by the filesystem primatives, and
94 * drivers. Ultimately, opendev will be created corresponding
95 * to which drive to pass to top level bootstrap.
96 */
97 for (io = 0; io < lp->d_npartitions; io++) {
98 int sn;
99
100 if (lp->d_partitions[io].p_size == 0)
101 continue;
102 if (lp->d_type == DTYPE_SCSI)
103 sn = off;
104 else
105 sn = off * lp->d_secpercyl;
106 if (lp->d_partitions[io].p_offset == sn)
107 break;
108 }
109
110 if (io == lp->d_npartitions) goto screwed;
111 cyloffset = off;
112 } else {
113screwed:
114 /* probably a bad or non-existant disklabel */
115 io = 0 ;
116 howto |= RB_SINGLE|RB_ASKNAME ;
117 }
118
119 /* construct bootdev */
120 /* currently, PC has no way of booting off alternate controllers */
121 bootdev = MAKEBOOTDEV(/*i_dev*/ dev, /*i_adapt*/0, /*i_ctlr*/0,
122 unit, /*i_part*/io);
123
124 for (;;) {
125
126/*printf("namei %s", *bootfile);*/
127 io = namei(*bootfile);
128 if (io > 2) {
129 copyunix(io, howto, off);
130 } else
131 printf("File not found");
132
133 printf(" - didn't load %s, ",*bootfile);
134 if(*++bootfile == 0) bootfile = files;
135 printf("will try %s\n", *bootfile);
136
137 wait(1<<((retry++) + 10));
138 }
139}
140
141/*ARGSUSED*/
142copyunix(io, howto, cyloff)
143 register io;
144{
145 struct exec x;
146 int i;
147 char *addr,c;
148 struct dinode fil;
149 int off;
150
151 fetchi(io, &fil);
152/*printf("mode %o ", fil.di_mode);*/
153 i = iread(&fil, 0, (char *)&x, sizeof x);
154 off = sizeof x;
155 if (i != sizeof x || x.a_magic != 0413) {
156 printf("Not an executable format");
157 return;
158 }
159
160 if (roundup(x.a_text, 4096) + x.a_data + x.a_bss > (unsigned)&fil) {
161 printf("File too big to load");
162 return;
163 }
164
165 off = 4096;
166 if (iread(&fil, off, (char *)0, x.a_text) != x.a_text)
167 goto shread;
168 off += x.a_text;
169
170 addr = (char *)x.a_text;
171 while ((int)addr & CLOFSET)
172 *addr++ = 0;
173
174 if (iread(&fil, off, addr, x.a_data) != x.a_data)
175 goto shread;
176
177 addr += x.a_data;
178
179 if (addr + x.a_bss > (unsigned) &fil) {
180 printf("Warning: bss overlaps bootstrap");
181 x.a_bss = (unsigned)addr - (unsigned)&fil;
182 }
183 bzero(addr, x.a_bss);
184
185 /* mask high order bits corresponding to relocated system base */
186 x.a_entry &= ~0xfff00000;
187
188 /*if (scankbd()) {
189 printf("Operator abort");
190 kbdreset();
191 return;
192 }*/
193
194 /* howto, bootdev, cyl */
195 /*printf("entry %x [%x] ", x.a_entry, *(int *) x.a_entry);*/
196 bcopy(0x9ff00, 0x300, 0x20); /* XXX */
197 i = (*((int (*)()) x.a_entry))(howto, bootdev, off);
198
199 if (i) printf("Program exits with %d", i) ;
200 return;
201shread:
202 printf("Read of file is incomplete");
203 return;
204}