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