Commit | Line | Data |
---|---|---|
15637ed4 | 1 | /* |
15637ed4 RG |
2 | * Mach Operating System |
3 | * Copyright (c) 1992, 1991 Carnegie Mellon University | |
4 | * All Rights Reserved. | |
5 | * | |
6 | * Permission to use, copy, modify and distribute this software and its | |
7 | * documentation is hereby granted, provided that both the copyright | |
8 | * notice and this permission notice appear in all copies of the | |
9 | * software, derivative works or modified versions, and any portions | |
10 | * thereof, and that both notices appear in supporting documentation. | |
11 | * | |
12 | * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" | |
13 | * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR | |
14 | * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. | |
15 | * | |
16 | * Carnegie Mellon requests users of this software to return to | |
17 | * | |
18 | * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU | |
19 | * School of Computer Science | |
20 | * Carnegie Mellon University | |
21 | * Pittsburgh PA 15213-3890 | |
22 | * | |
23 | * any improvements or extensions that they make and grant Carnegie Mellon | |
24 | * the rights to redistribute these changes. | |
25 | * | |
78ed81a3 | 26 | * from: Mach, [92/04/03 16:51:14 rvb] |
27 | * $Id: boot.c,v 1.7 1993/10/15 12:33:03 rgrimes Exp $ | |
15637ed4 RG |
28 | */ |
29 | ||
15637ed4 RG |
30 | |
31 | /* | |
32 | Copyright 1988, 1989, 1990, 1991, 1992 | |
33 | by Intel Corporation, Santa Clara, California. | |
34 | ||
35 | All Rights Reserved | |
36 | ||
37 | Permission to use, copy, modify, and distribute this software and | |
38 | its documentation for any purpose and without fee is hereby | |
39 | granted, provided that the above copyright notice appears in all | |
40 | copies and that both the copyright notice and this permission notice | |
41 | appear in supporting documentation, and that the name of Intel | |
42 | not be used in advertising or publicity pertaining to distribution | |
43 | of the software without specific, written prior permission. | |
44 | ||
45 | INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE | |
46 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, | |
47 | IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR | |
48 | CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | |
49 | LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, | |
50 | NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION | |
51 | WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
52 | */ | |
53 | ||
54 | #include <sys/param.h> | |
55 | #include "boot.h" | |
56 | #include <a.out.h> | |
57 | #include <sys/reboot.h> | |
58 | ||
15637ed4 RG |
59 | struct exec head; |
60 | int argv[10], esym; | |
61 | char *name; | |
62 | char *names[] = { | |
78ed81a3 | 63 | "/386bsd", "/o386bsd", "/386bsd.old", |
64 | "/vmunix", "/ovmunix", "/vmunix.old" | |
15637ed4 RG |
65 | }; |
66 | #define NUMNAMES (sizeof(names)/sizeof(char *)) | |
67 | ||
68 | extern int end; | |
69 | boot(drive) | |
70 | int drive; | |
71 | { | |
72 | int loadflags, currname = 0; | |
78ed81a3 | 73 | char *t; |
74 | ||
75 | printf("\n>> FreeBSD BOOT @ 0x%x: %d/%d k of memory [%s]\n", | |
15637ed4 RG |
76 | ouraddr, |
77 | argv[7] = memsize(0), | |
78ed81a3 | 78 | argv[8] = memsize(1), |
79 | "$Revision: 1.7 $"); | |
80 | printf("use hd(1,a)/386bsd to boot sd0 when wd0 is also installed\n"); | |
15637ed4 RG |
81 | gateA20(); |
82 | loadstart: | |
83 | /***************************************************************\ | |
84 | * As a default set it to the first partition of the first * | |
85 | * floppy or hard drive * | |
86 | \***************************************************************/ | |
87 | part = unit = 0; | |
88 | maj = (drive&0x80 ? 0 : 2); /* a good first bet */ | |
89 | name = names[currname++]; | |
90 | ||
91 | loadflags = 0; | |
92 | if (currname == NUMNAMES) | |
93 | currname = 0; | |
94 | getbootdev(&loadflags); | |
95 | if (openrd()) { | |
96 | printf("Can't find %s\n", name); | |
97 | goto loadstart; | |
98 | } | |
99 | /* if (inode.i_mode&IEXEC) | |
100 | loadflags |= RB_KDB; | |
101 | */ | |
102 | loadprog(loadflags); | |
103 | goto loadstart; | |
104 | } | |
105 | ||
106 | loadprog(howto) | |
107 | int howto; | |
108 | { | |
109 | long int startaddr; | |
110 | long int addr; /* physical address.. not directly useable */ | |
78ed81a3 | 111 | long int addr0; |
15637ed4 RG |
112 | int i; |
113 | static int (*x_entry)() = 0; | |
114 | unsigned char tmpbuf[4096]; /* we need to load the first 4k here */ | |
115 | ||
116 | argv[3] = 0; | |
117 | argv[4] = 0; | |
118 | read(&head, sizeof(head)); | |
78ed81a3 | 119 | if ( N_BADMAG(head)) { |
15637ed4 RG |
120 | printf("Invalid format!\n"); |
121 | return; | |
122 | } | |
123 | ||
78ed81a3 | 124 | poff = N_TXTOFF(head); |
125 | /*if(poff==0) | |
126 | poff = 32;*/ | |
127 | ||
15637ed4 | 128 | startaddr = (int)head.a_entry; |
78ed81a3 | 129 | addr = (startaddr & 0x00ffffff); /* some MEG boundary */ |
130 | addr0 = addr; | |
15637ed4 RG |
131 | printf("Booting %s(%d,%c)%s @ 0x%x\n" |
132 | , devs[maj] | |
133 | , unit | |
134 | , 'a'+part | |
135 | , name | |
136 | , addr); | |
137 | if(addr < ouraddr) | |
138 | { | |
139 | if((addr + head.a_text + head.a_data) > ouraddr) | |
140 | { | |
141 | printf("kernel will not fit below loader\n"); | |
142 | return; | |
143 | } | |
78ed81a3 | 144 | if((addr + head.a_text + head.a_data + head.a_bss) > 0xa0000) |
15637ed4 RG |
145 | { |
146 | printf("kernel too big, won't fit in 640K with bss\n"); | |
147 | printf("Only hope is to link the kernel for > 1MB\n"); | |
148 | return; | |
149 | } | |
15637ed4 | 150 | } |
78ed81a3 | 151 | printf("text=0x%x ", head.a_text); |
15637ed4 RG |
152 | /********************************************************/ |
153 | /* LOAD THE TEXT SEGMENT */ | |
154 | /* don't clobber the first 4k yet (BIOS NEEDS IT) */ | |
155 | /********************************************************/ | |
156 | read(tmpbuf,4096); | |
157 | addr += 4096; | |
158 | xread(addr, head.a_text - 4096); | |
159 | addr += head.a_text - 4096; | |
160 | ||
161 | /********************************************************/ | |
162 | /* Load the Initialised data after the text */ | |
163 | /********************************************************/ | |
164 | while (addr & CLOFSET) | |
165 | *(char *)addr++ = 0; | |
166 | ||
78ed81a3 | 167 | printf("data=0x%x ", head.a_data); |
15637ed4 RG |
168 | xread(addr, head.a_data); |
169 | addr += head.a_data; | |
170 | ||
171 | /********************************************************/ | |
172 | /* Skip over the uninitialised data */ | |
173 | /* (but clear it) */ | |
174 | /********************************************************/ | |
78ed81a3 | 175 | printf("bss=0x%x ", head.a_bss); |
15637ed4 RG |
176 | if( (addr < ouraddr) && ((addr + head.a_bss) > ouraddr)) |
177 | { | |
178 | pbzero(addr,ouraddr - (int)addr); | |
179 | } | |
180 | else | |
181 | { | |
182 | pbzero(addr,head.a_bss); | |
183 | } | |
184 | argv[3] = (addr += head.a_bss); | |
185 | ||
186 | #ifdef LOADSYMS /* not yet, haven't worked this out yet */ | |
187 | if (addr > 0x100000) | |
188 | { | |
189 | /********************************************************/ | |
190 | /*copy in the symbol header */ | |
191 | /********************************************************/ | |
192 | pcpy(&head.a_syms, addr, sizeof(head.a_syms)); | |
193 | addr += sizeof(head.a_syms); | |
194 | ||
195 | /********************************************************/ | |
196 | /* READ in the symbol table */ | |
197 | /********************************************************/ | |
78ed81a3 | 198 | printf("symbols=[+0x%x", head.a_syms); |
15637ed4 RG |
199 | xread(addr, head.a_syms); |
200 | addr += head.a_syms; | |
201 | ||
202 | /********************************************************/ | |
203 | /* Followed by the next integer (another header) */ | |
204 | /* more debug symbols? */ | |
205 | /********************************************************/ | |
206 | read(&i, sizeof(int)); | |
207 | pcpy(&i, addr, sizeof(int)); | |
208 | i -= sizeof(int); | |
209 | addr += sizeof(int); | |
210 | ||
211 | ||
212 | /********************************************************/ | |
213 | /* and that many bytes of (debug symbols?) */ | |
214 | /********************************************************/ | |
78ed81a3 | 215 | printf("+0x%x] ", i); |
15637ed4 RG |
216 | xread(addr, i); |
217 | addr += i; | |
218 | } | |
219 | #endif LOADSYMS | |
220 | /********************************************************/ | |
221 | /* and note the end address of all this */ | |
222 | /********************************************************/ | |
223 | ||
224 | argv[4] = ((addr+sizeof(int)-1))&~(sizeof(int)-1); | |
78ed81a3 | 225 | printf("total=0x%x ",argv[4]); |
15637ed4 RG |
226 | |
227 | ||
228 | /* | |
229 | * We now pass the various bootstrap parameters to the loaded | |
230 | * image via the argument list | |
231 | * (THIS IS A BIT OF HISTORY FROM MACH.. LEAVE FOR NOW) | |
232 | * arg1 = boot flags | |
233 | * arg2 = boot device | |
234 | * arg3 = start of symbol table (0 if not loaded) | |
235 | * arg4 = end of symbol table (0 if not loaded) | |
236 | * arg5 = transfer address from image | |
237 | * arg6 = transfer address for next image pointer | |
238 | */ | |
239 | switch(maj) | |
240 | { | |
241 | case 2: | |
78ed81a3 | 242 | printf("\n\nInsert file system floppy in drive A or B\n"); |
243 | printf("Press 'A', 'B' or any other key for the default "); | |
244 | printf("%c: ", unit+'A'); | |
245 | i = getchar(); | |
246 | switch (i) { | |
247 | case '0': case 'A': case 'a': | |
248 | unit = 0; | |
249 | break; | |
250 | case '1': case 'B': case 'b': | |
251 | unit = 1; | |
252 | break; | |
253 | } | |
254 | printf("\n"); | |
15637ed4 RG |
255 | break; |
256 | case 4: | |
257 | break; | |
258 | } | |
259 | argv[1] = howto; | |
260 | argv[2] = (MAKEBOOTDEV(maj, 0, 0, unit, part)) ; | |
261 | argv[5] = (head.a_entry &= 0xfffffff); | |
262 | argv[6] = (int) &x_entry; | |
263 | argv[0] = 8; | |
264 | /****************************************************************/ | |
265 | /* copy that first page and overwrite any BIOS variables */ | |
266 | /****************************************************************/ | |
78ed81a3 | 267 | printf("entry point=0x%x\n" ,((int)startaddr) & 0xffffff); |
268 | /* Under no circumstances overwrite precious BIOS variables! */ | |
269 | pcpy(tmpbuf, addr0, 0x400); | |
270 | pcpy(tmpbuf + 0x500, addr0 + 0x500, 4096 - 0x500); | |
15637ed4 RG |
271 | startprog(((int)startaddr & 0xffffff),argv); |
272 | } | |
273 | ||
274 | char namebuf[100]; | |
275 | getbootdev(howto) | |
276 | int *howto; | |
277 | { | |
278 | char c, *ptr = namebuf; | |
279 | printf("Boot: [[[%s(%d,%c)]%s][-s][-a][-d]] :- " | |
280 | , devs[maj] | |
281 | , unit | |
282 | , 'a'+part | |
283 | , name); | |
284 | if (gets(namebuf)) { | |
285 | while (c=*ptr) { | |
286 | while (c==' ') | |
287 | c = *++ptr; | |
288 | if (!c) | |
289 | return; | |
290 | if (c=='-') | |
291 | while ((c = *++ptr) && c!=' ') | |
292 | switch (c) { | |
293 | case 'a': | |
294 | *howto |= RB_ASKNAME; continue; | |
295 | case 's': | |
296 | *howto |= RB_SINGLE; continue; | |
297 | case 'd': | |
298 | *howto |= RB_KDB; continue; | |
299 | case 'b': | |
300 | *howto |= RB_HALT; continue; | |
301 | } | |
302 | else { | |
303 | name = ptr; | |
304 | while ((c = *++ptr) && c!=' '); | |
305 | if (c) | |
306 | *ptr++ = 0; | |
307 | } | |
308 | } | |
78ed81a3 | 309 | } else |
310 | printf("\n"); | |
15637ed4 RG |
311 | } |
312 |