1 /* $OpenBSD: boot.c,v 1.36 2007/06/26 10:34:41 tom Exp $ */
2
3 /*
4 * Copyright (c) 2003 Dale Rahn
5 * Copyright (c) 1997,1998 Michael Shalayeff
6 * All rights reserved.
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 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31 #include <sys/param.h>
32 #include <sys/reboot.h>
33 #include <sys/stat.h>
34 #include <libsa.h>
35 #include <lib/libsa/loadfile.h>
36 #include <lib/libkern/funcs.h>
37
38 #include "cmd.h"
39
40 #ifndef KERNEL
41 #define KERNEL "/bsd"
42 #endif
43
44 char prog_ident[40];
45 char *progname = "BOOT";
46
47 extern const char version[];
48 struct cmd_state cmd;
49
50 /* bootprompt can be set by MD code to avoid prompt first time round */
51 int bootprompt = 1;
52 char *kernelfile = KERNEL; /* can be changed by MD code */
53
54 void
55 boot(dev_t bootdev)
56 {
57 int fd;
58 int try = 0, st;
59 u_long marks[MARK_MAX];
60
61 machdep();
62
63 snprintf(prog_ident, sizeof(prog_ident),
64 ">> OpenBSD/" MACHINE " %s %s", progname, version);
65 printf("%s\n", prog_ident);
66
67 devboot(bootdev, cmd.bootdev);
68 strlcpy(cmd.image, kernelfile, sizeof(cmd.image));
69 cmd.boothowto = 0;
70 cmd.conf = "/etc/boot.conf";
71 cmd.addr = (void *)DEFAULT_KERNEL_ADDRESS;
72 cmd.timeout = 5;
73
74 st = read_conf();
75 if (!bootprompt)
76 snprintf(cmd.path, sizeof cmd.path, "%s:%s",
77 cmd.bootdev, cmd.image);
78
79 while (1) {
80 /* no boot.conf, or no boot cmd in there */
81 if (bootprompt && st <= 0)
82 do {
83 printf("boot> ");
84 } while(!getcmd());
85 st = 0;
86 bootprompt = 1; /* allow reselect should we fail */
87
88 printf("booting %s: ", cmd.path);
89 marks[MARK_START] = (u_long)cmd.addr;
90 if ((fd = loadfile(cmd.path, marks, LOAD_ALL)) != -1) {
91 close(fd);
92 break;
93 }
94
95 kernelfile = KERNEL;
96 try++;
97 strlcpy(cmd.image, kernelfile, sizeof(cmd.image));
98 printf(" failed(%d). will try %s\n", errno, kernelfile);
99
100 if (try < 2) {
101 if (cmd.timeout > 0)
102 cmd.timeout++;
103 } else {
104 if (cmd.timeout)
105 printf("Turning timeout off.\n");
106 cmd.timeout = 0;
107 }
108 }
109
110 /* exec */
111 run_loadfile(marks, cmd.boothowto);
112 }
113
114 #ifdef _TEST
115 int
116 main()
117 {
118 boot(0);
119 return 0;
120 }
121 #endif