1 /* $NetBSD: boot.c,v 1.21 2008/04/28 20:23:31 martin Exp $ */
4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
34 * Copyright (C) 1995, 1996 TooLs GmbH.
35 * All rights reserved.
37 * ELF support derived from NetBSD/alpha's boot loader, written
38 * by Christopher G. Demetriou.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. All advertising materials mentioning features or use of this software
49 * must display the following acknowledgement:
50 * This product includes software developed by TooLs GmbH.
51 * 4. The name of TooLs GmbH may not be used to endorse or promote products
52 * derived from this software without specific prior written permission.
54 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
58 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
59 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
60 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
61 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
62 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
63 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67 * First try for the boot code
70 * [promdev[{:|,}partition]]/[filename] [flags]
73 #define ELFSIZE 32 /* We use 32-bit ELF. */
75 #include <sys/param.h>
77 #include <sys/exec_elf.h>
78 #include <sys/reboot.h>
79 #include <sys/disklabel.h>
80 #include <sys/boot_flag.h>
82 #include <lib/libsa/stand.h>
83 #include <lib/libsa/loadfile.h>
84 #include <lib/libkern/libkern.h>
86 #include <machine/cpu.h>
93 # define DPRINTF printf
95 # define DPRINTF while (/*CONSTCOND*/0) printf
104 void dump_ofwtree(int);
107 static char *kernels
[] = { "/netbsd.ofppc", "/netbsd",
108 "/netbsd.gz", "onetbsd", NULL
};
109 static char *kernels64
[] = { "/netbsd.ofppc64", "/netbsd64", "/netbsd64.gz",
110 "onetbsd64", "/netbsd.ofppc", "/netbsd",
111 "/netbsd.gz", "onetbsd", NULL
};
119 cp
= dev
+ strlen(dev
) - 1;
120 for (; cp
>= ocp
; cp
--) {
129 parseargs(char *str
, int *howtop
)
133 /* Allow user to drop back to the PROM. */
134 if (strcmp(str
, "exit") == 0)
136 if (strcmp(str
, "halt") == 0)
138 if (strcmp(str
, "reboot") == 0)
143 for (cp
= str
; *cp
; cp
++)
144 if (*cp
== ' ' || *cp
== '-')
152 BOOT_FLAG(*cp
++, *howtop
);
156 chain(boot_entry_t entry
, char *args
, void *ssym
, void *esym
)
159 u_int l
, magic
= 0x19730224;
162 * Stash pointer to start and end of symbol table after the argument
165 l
= strlen(args
) + 1;
166 DPRINTF("ssym @ %p\n", args
+ l
);
167 memcpy(args
+ l
, &ssym
, sizeof(ssym
));
169 DPRINTF("esym @ %p\n", args
+ l
);
170 memcpy(args
+ l
, &esym
, sizeof(esym
));
172 DPRINTF("magic @ %p\n", args
+ l
);
173 memcpy(args
+ l
, &magic
, sizeof(magic
));
175 DPRINTF("args + l -> %p\n", args
+ l
);
177 OF_chain((void *) RELOC
, end
- (char *)RELOC
, entry
, args
, l
);
191 extern char bootprog_name
[], bootprog_rev
[],
192 bootprog_maker
[], bootprog_date
[];
193 int chosen
, cpu
, cpunode
, j
, is64
=0;
194 char bootline
[512]; /* Should check size? */
196 u_long marks
[MARK_MAX
];
201 printf(">> %s, Revision %s\n", bootprog_name
, bootprog_rev
);
202 printf(">> (%s, %s)\n", bootprog_maker
, bootprog_date
);
205 chosen
= OF_finddevice("/");
206 dump_ofwtree(chosen
);
209 * Get the boot arguments from Openfirmware
211 if ((chosen
= OF_finddevice("/chosen")) == -1 ||
212 OF_getprop(chosen
, "bootpath", bootdev
, sizeof bootdev
) < 0 ||
213 OF_getprop(chosen
, "bootargs", bootline
, sizeof bootline
) < 0) {
214 printf("Invalid Openfirmware environment\n");
218 /* lets see if we can guess the 64bittedness */
219 if (OF_getprop(chosen
, "cpu", &cpu
, sizeof cpu
) == sizeof(cpu
)) {
220 cpunode
= OF_instance_to_package(cpu
);
221 if (OF_getprop(cpunode
, "64-bit", &j
, sizeof j
) >= 0) {
227 parseargs(bootline
, &boothowto
);
228 DPRINTF("bootline=%s\n", bootline
);
233 if (boothowto
& RB_ASKNAME
) {
236 parseargs(bootline
, &boothowto
);
240 kernels
[0] = bootline
;
243 if (!bootline
[0] && is64
) {
244 for (i
= 0; kernels64
[i
]; i
++) {
245 DPRINTF("Trying %s\n", kernels64
[i
]);
247 marks
[MARK_START
] = 0;
248 if (loadfile(kernels64
[i
], marks
, LOAD_KERNEL
) >= 0)
252 for (i
= 0; kernels
[i
]; i
++) {
253 DPRINTF("Trying %s\n", kernels
[i
]);
255 marks
[MARK_START
] = 0;
256 if (loadfile(kernels
[i
], marks
, LOAD_KERNEL
) >= 0)
261 boothowto
|= RB_ASKNAME
;
266 OF_setprop(chosen
, "bootpath", opened_name
, strlen(opened_name
) + 1);
269 strcpy(bootline
, opened_name
);
270 cp
= bootline
+ strlen(bootline
);
274 if (boothowto
& RB_ASKNAME
)
276 if (boothowto
& RB_SINGLE
)
278 if (boothowto
& RB_KDB
)
289 OF_setprop(chosen
, "bootargs", bootline
, strlen(bootline
) + 1);
292 entry
= marks
[MARK_ENTRY
];
293 ssym
= (void *)marks
[MARK_SYM
];
294 esym
= (void *)marks
[MARK_END
];
296 printf(" start=0x%x\n", entry
);
297 __syncicache((void *) entry
, (u_int
) ssym
- (u_int
) entry
);
298 chain((boot_entry_t
) entry
, bootline
, ssym
, esym
);