]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/boot/userboot/userboot/main.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / boot / userboot / userboot / main.c
1 /*-
2  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3  * Copyright (c) 1998,2000 Doug Rabson <dfr@freebsd.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include <stand.h>
32 #include <string.h>
33 #include <setjmp.h>
34
35 #include "bootstrap.h"
36 #include "disk.h"
37 #include "libuserboot.h"
38
39 #define USERBOOT_VERSION        USERBOOT_VERSION_3
40
41 struct loader_callbacks *callbacks;
42 void *callbacks_arg;
43
44 extern char bootprog_name[];
45 extern char bootprog_rev[];
46 extern char bootprog_date[];
47 extern char bootprog_maker[];
48 static jmp_buf jb;
49
50 struct arch_switch archsw;      /* MI/MD interface boundary */
51
52 static void     extract_currdev(void);
53
54 void
55 delay(int usec)
56 {
57
58         CALLBACK(delay, usec);
59 }
60
61 void
62 exit(int v)
63 {
64
65         CALLBACK(exit, v);
66         longjmp(jb, 1);
67 }
68
69 void
70 loader_main(struct loader_callbacks *cb, void *arg, int version, int ndisks)
71 {
72         static char malloc[1024*1024];
73         const char *var;
74         int i;
75
76         if (version != USERBOOT_VERSION)
77                 abort();
78
79         callbacks = cb;
80         callbacks_arg = arg;
81         userboot_disk_maxunit = ndisks;
82
83         /*
84          * initialise the heap as early as possible.  Once this is done,
85          * alloc() is usable. The stack is buried inside us, so this is
86          * safe.
87          */
88         setheap((void *)malloc, (void *)(malloc + 1024*1024));
89
90         /*
91          * Hook up the console
92          */
93         cons_probe();
94
95         /*
96          * March through the device switch probing for things.
97          */
98         for (i = 0; devsw[i] != NULL; i++)
99                 if (devsw[i]->dv_init != NULL)
100                         (devsw[i]->dv_init)();
101
102         printf("\n");
103         printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
104         printf("(%s, %s)\n", bootprog_maker, bootprog_date);
105 #if 0
106         printf("Memory: %ld k\n", memsize() / 1024);
107 #endif
108
109         setenv("LINES", "24", 1);       /* optional */
110
111         /*
112          * Set custom environment variables
113          */
114         i = 0;
115         while (1) {
116                 var = CALLBACK(getenv, i++);
117                 if (var == NULL)
118                         break;
119                 putenv(var);
120         }
121
122         archsw.arch_autoload = userboot_autoload;
123         archsw.arch_getdev = userboot_getdev;
124         archsw.arch_copyin = userboot_copyin;
125         archsw.arch_copyout = userboot_copyout;
126         archsw.arch_readin = userboot_readin;
127
128         extract_currdev();
129
130         if (setjmp(jb))
131                 return;
132
133         interact();                     /* doesn't return */
134
135         exit(0);
136 }
137
138 /*
139  * Set the 'current device' by (if possible) recovering the boot device as 
140  * supplied by the initial bootstrap.
141  */
142 static void
143 extract_currdev(void)
144 {
145         struct disk_devdesc dev;
146
147         //bzero(&dev, sizeof(dev));
148
149         if (userboot_disk_maxunit > 0) {
150                 dev.d_dev = &userboot_disk;
151                 dev.d_type = dev.d_dev->dv_type;
152                 dev.d_unit = 0;
153                 dev.d_slice = 0;
154                 dev.d_partition = 0;
155                 /*
156                  * If we cannot auto-detect the partition type then
157                  * access the disk as a raw device.
158                  */
159                 if (dev.d_dev->dv_open(NULL, &dev)) {
160                         dev.d_slice = -1;
161                         dev.d_partition = -1;
162                 }
163         } else {
164                 dev.d_dev = &host_dev;
165                 dev.d_type = dev.d_dev->dv_type;
166                 dev.d_unit = 0;
167         }
168
169         env_setenv("currdev", EV_VOLATILE, userboot_fmtdev(&dev),
170             userboot_setcurrdev, env_nounset);
171         env_setenv("loaddev", EV_VOLATILE, userboot_fmtdev(&dev),
172             env_noset, env_nounset);
173 }
174
175 COMMAND_SET(quit, "quit", "exit the loader", command_quit);
176
177 static int
178 command_quit(int argc, char *argv[])
179 {
180
181         exit(USERBOOT_EXIT_QUIT);
182         return (CMD_OK);
183 }
184
185 COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
186
187 static int
188 command_reboot(int argc, char *argv[])
189 {
190
191         exit(USERBOOT_EXIT_REBOOT);
192         return (CMD_OK);
193 }