]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/boot/userboot/userboot/main.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.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_2
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[512*1024];
73         int i;
74
75         if (version != USERBOOT_VERSION)
76                 abort();
77
78         callbacks = cb;
79         callbacks_arg = arg;
80         userboot_disk_maxunit = ndisks;
81
82         /*
83          * initialise the heap as early as possible.  Once this is done,
84          * alloc() is usable. The stack is buried inside us, so this is
85          * safe.
86          */
87         setheap((void *)malloc, (void *)(malloc + 512*1024));
88
89         /*
90          * Hook up the console
91          */
92         cons_probe();
93
94         /*
95          * March through the device switch probing for things.
96          */
97         for (i = 0; devsw[i] != NULL; i++)
98                 if (devsw[i]->dv_init != NULL)
99                         (devsw[i]->dv_init)();
100
101         printf("\n");
102         printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
103         printf("(%s, %s)\n", bootprog_maker, bootprog_date);
104 #if 0
105         printf("Memory: %ld k\n", memsize() / 1024);
106 #endif
107
108         setenv("LINES", "24", 1);       /* optional */
109
110         archsw.arch_autoload = userboot_autoload;
111         archsw.arch_getdev = userboot_getdev;
112         archsw.arch_copyin = userboot_copyin;
113         archsw.arch_copyout = userboot_copyout;
114         archsw.arch_readin = userboot_readin;
115
116         extract_currdev();
117
118         if (setjmp(jb))
119                 return;
120
121         interact();                     /* doesn't return */
122
123         exit(0);
124 }
125
126 /*
127  * Set the 'current device' by (if possible) recovering the boot device as 
128  * supplied by the initial bootstrap.
129  */
130 static void
131 extract_currdev(void)
132 {
133         struct disk_devdesc dev;
134
135         //bzero(&dev, sizeof(dev));
136
137         if (userboot_disk_maxunit > 0) {
138                 dev.d_dev = &userboot_disk;
139                 dev.d_type = dev.d_dev->dv_type;
140                 dev.d_unit = 0;
141                 dev.d_slice = 0;
142                 dev.d_partition = 0;
143                 /*
144                  * Figure out if we are using MBR or GPT - for GPT we
145                  * set the partition to 0 since everything is a GPT slice.
146                  */
147                 if (dev.d_dev->dv_open(NULL, &dev))
148                         dev.d_partition = 255;
149         } else {
150                 dev.d_dev = &host_dev;
151                 dev.d_type = dev.d_dev->dv_type;
152                 dev.d_unit = 0;
153         }
154
155         env_setenv("currdev", EV_VOLATILE, userboot_fmtdev(&dev),
156             userboot_setcurrdev, env_nounset);
157         env_setenv("loaddev", EV_VOLATILE, userboot_fmtdev(&dev),
158             env_noset, env_nounset);
159 }
160
161 COMMAND_SET(quit, "quit", "exit the loader", command_quit);
162
163 static int
164 command_quit(int argc, char *argv[])
165 {
166
167         exit(USERBOOT_EXIT_QUIT);
168         return (CMD_OK);
169 }
170
171 COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
172
173 static int
174 command_reboot(int argc, char *argv[])
175 {
176
177         exit(USERBOOT_EXIT_REBOOT);
178         return (CMD_OK);
179 }