xref: /dflybsd-src/stand/boot/common/boot.c (revision d5ee81904c129f2868183acef7c3ff6230fa9c51)
1*479ab7f0SSascha Wildner /*-
2*479ab7f0SSascha Wildner  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3*479ab7f0SSascha Wildner  * All rights reserved.
4*479ab7f0SSascha Wildner  *
5*479ab7f0SSascha Wildner  * Redistribution and use in source and binary forms, with or without
6*479ab7f0SSascha Wildner  * modification, are permitted provided that the following conditions
7*479ab7f0SSascha Wildner  * are met:
8*479ab7f0SSascha Wildner  * 1. Redistributions of source code must retain the above copyright
9*479ab7f0SSascha Wildner  *    notice, this list of conditions and the following disclaimer.
10*479ab7f0SSascha Wildner  * 2. Redistributions in binary form must reproduce the above copyright
11*479ab7f0SSascha Wildner  *    notice, this list of conditions and the following disclaimer in the
12*479ab7f0SSascha Wildner  *    documentation and/or other materials provided with the distribution.
13*479ab7f0SSascha Wildner  *
14*479ab7f0SSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*479ab7f0SSascha Wildner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*479ab7f0SSascha Wildner  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*479ab7f0SSascha Wildner  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*479ab7f0SSascha Wildner  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*479ab7f0SSascha Wildner  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*479ab7f0SSascha Wildner  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*479ab7f0SSascha Wildner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*479ab7f0SSascha Wildner  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*479ab7f0SSascha Wildner  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*479ab7f0SSascha Wildner  * SUCH DAMAGE.
25*479ab7f0SSascha Wildner  *
26*479ab7f0SSascha Wildner  * $FreeBSD: src/sys/boot/common/boot.c,v 1.29 2003/08/25 23:30:41 obrien Exp $
27*479ab7f0SSascha Wildner  */
28*479ab7f0SSascha Wildner 
29*479ab7f0SSascha Wildner /*
30*479ab7f0SSascha Wildner  * Loading modules, booting the system
31*479ab7f0SSascha Wildner  */
32*479ab7f0SSascha Wildner 
33*479ab7f0SSascha Wildner #include <stand.h>
34*479ab7f0SSascha Wildner #include <string.h>
35*479ab7f0SSascha Wildner 
36*479ab7f0SSascha Wildner #include "bootstrap.h"
37*479ab7f0SSascha Wildner 
38*479ab7f0SSascha Wildner static char	*getbootfile(int try);
39*479ab7f0SSascha Wildner static int	loadakernel(int try, int argc, char* argv[]);
40*479ab7f0SSascha Wildner 
41*479ab7f0SSascha Wildner /* List of kernel names to try (may be overwritten by boot.config) XXX should move from here? */
42*479ab7f0SSascha Wildner static const char *default_bootfiles = "kernel";
43*479ab7f0SSascha Wildner 
44*479ab7f0SSascha Wildner static int autoboot_tried;
45*479ab7f0SSascha Wildner 
46*479ab7f0SSascha Wildner /*
47*479ab7f0SSascha Wildner  * The user wants us to boot.
48*479ab7f0SSascha Wildner  */
49*479ab7f0SSascha Wildner COMMAND_SET(boot, "boot", "boot a file or loaded kernel", command_boot);
50*479ab7f0SSascha Wildner 
51*479ab7f0SSascha Wildner static int
command_boot(int argc,char * argv[])52*479ab7f0SSascha Wildner command_boot(int argc, char *argv[])
53*479ab7f0SSascha Wildner {
54*479ab7f0SSascha Wildner     struct preloaded_file	*fp;
55*479ab7f0SSascha Wildner     char *local_module_path;
56*479ab7f0SSascha Wildner     char *exported_module_path;
57*479ab7f0SSascha Wildner 
58*479ab7f0SSascha Wildner     /*
59*479ab7f0SSascha Wildner      * See if the user has specified an explicit kernel to boot.
60*479ab7f0SSascha Wildner      */
61*479ab7f0SSascha Wildner     if ((argc > 1) && (argv[1][0] != '-')) {
62*479ab7f0SSascha Wildner 
63*479ab7f0SSascha Wildner 	/* XXX maybe we should discard everything and start again? */
64*479ab7f0SSascha Wildner 	if (file_findfile(NULL, NULL) != NULL) {
65*479ab7f0SSascha Wildner 	    snprintf(command_errbuf, sizeof(command_errbuf),
66*479ab7f0SSascha Wildner 		"can't boot '%s', kernel module already loaded", argv[1]);
67*479ab7f0SSascha Wildner 	    return(CMD_ERROR);
68*479ab7f0SSascha Wildner 	}
69*479ab7f0SSascha Wildner 
70*479ab7f0SSascha Wildner 	/* find/load the kernel module */
71*479ab7f0SSascha Wildner 	if (mod_loadkld(argv[1], argc - 2, argv + 2) != 0)
72*479ab7f0SSascha Wildner 	    return(CMD_ERROR);
73*479ab7f0SSascha Wildner 	/* we have consumed all arguments */
74*479ab7f0SSascha Wildner 	argc = 1;
75*479ab7f0SSascha Wildner     }
76*479ab7f0SSascha Wildner 
77*479ab7f0SSascha Wildner     /*
78*479ab7f0SSascha Wildner      * See if there is a kernel module already loaded
79*479ab7f0SSascha Wildner      */
80*479ab7f0SSascha Wildner     if (file_findfile(NULL, NULL) == NULL)
81*479ab7f0SSascha Wildner 	if (loadakernel(0, argc - 1, argv + 1))
82*479ab7f0SSascha Wildner 	    /* we have consumed all arguments */
83*479ab7f0SSascha Wildner 	    argc = 1;
84*479ab7f0SSascha Wildner 
85*479ab7f0SSascha Wildner     /*
86*479ab7f0SSascha Wildner      * Loaded anything yet?
87*479ab7f0SSascha Wildner      */
88*479ab7f0SSascha Wildner     if ((fp = file_findfile(NULL, NULL)) == NULL) {
89*479ab7f0SSascha Wildner 	command_errmsg = "no bootable kernel";
90*479ab7f0SSascha Wildner 	return(CMD_ERROR);
91*479ab7f0SSascha Wildner     }
92*479ab7f0SSascha Wildner 
93*479ab7f0SSascha Wildner     /*
94*479ab7f0SSascha Wildner      * If we were given arguments, discard any previous.
95*479ab7f0SSascha Wildner      * XXX should we merge arguments?  Hard to DWIM.
96*479ab7f0SSascha Wildner      */
97*479ab7f0SSascha Wildner     if (argc > 1) {
98*479ab7f0SSascha Wildner 	if (fp->f_args != NULL)
99*479ab7f0SSascha Wildner 	    free(fp->f_args);
100*479ab7f0SSascha Wildner 	fp->f_args = unargv(argc - 1, argv + 1);
101*479ab7f0SSascha Wildner     }
102*479ab7f0SSascha Wildner 
103*479ab7f0SSascha Wildner     /* Hook for platform-specific autoloading of modules */
104*479ab7f0SSascha Wildner     if (archsw.arch_autoload() != 0)
105*479ab7f0SSascha Wildner 	return(CMD_ERROR);
106*479ab7f0SSascha Wildner 
107*479ab7f0SSascha Wildner     /*
108*479ab7f0SSascha Wildner      * Exec the kernel.  We have to shift our exported_module_path
109*479ab7f0SSascha Wildner      * (which has the correct /boot prefix for the kernel) over to
110*479ab7f0SSascha Wildner      * module_path.  If the exec fails we switch it back.
111*479ab7f0SSascha Wildner      */
112*479ab7f0SSascha Wildner     exported_module_path = getenv("exported_module_path");
113*479ab7f0SSascha Wildner     if (exported_module_path) {
114*479ab7f0SSascha Wildner 	    exported_module_path = strdup(exported_module_path);
115*479ab7f0SSascha Wildner 	    local_module_path = getenv("module_path");
116*479ab7f0SSascha Wildner 	    if (local_module_path)
117*479ab7f0SSascha Wildner 		local_module_path = strdup(local_module_path);
118*479ab7f0SSascha Wildner 	    setenv("module_path", exported_module_path, 1);
119*479ab7f0SSascha Wildner 	    unsetenv("exported_module_path");
120*479ab7f0SSascha Wildner     }
121*479ab7f0SSascha Wildner 
122*479ab7f0SSascha Wildner     /* Call the exec handler from the loader matching the kernel */
123*479ab7f0SSascha Wildner     file_formats[fp->f_loader]->l_exec(fp);
124*479ab7f0SSascha Wildner 
125*479ab7f0SSascha Wildner     if (exported_module_path) {
126*479ab7f0SSascha Wildner 	    if (local_module_path) {
127*479ab7f0SSascha Wildner 		setenv("module_path", local_module_path, 1);
128*479ab7f0SSascha Wildner 		free(local_module_path);
129*479ab7f0SSascha Wildner 	    } else {
130*479ab7f0SSascha Wildner 		unsetenv("module_path");
131*479ab7f0SSascha Wildner 	    }
132*479ab7f0SSascha Wildner 	    setenv("exported_module_path", exported_module_path, 1);
133*479ab7f0SSascha Wildner 	    free(exported_module_path);
134*479ab7f0SSascha Wildner     }
135*479ab7f0SSascha Wildner     return(CMD_ERROR);
136*479ab7f0SSascha Wildner }
137*479ab7f0SSascha Wildner 
138*479ab7f0SSascha Wildner 
139*479ab7f0SSascha Wildner /*
140*479ab7f0SSascha Wildner  * Autoboot after a delay
141*479ab7f0SSascha Wildner  */
142*479ab7f0SSascha Wildner 
143*479ab7f0SSascha Wildner COMMAND_SET(autoboot, "autoboot", "boot automatically after a delay", command_autoboot);
144*479ab7f0SSascha Wildner 
145*479ab7f0SSascha Wildner static int
command_autoboot(int argc,char * argv[])146*479ab7f0SSascha Wildner command_autoboot(int argc, char *argv[])
147*479ab7f0SSascha Wildner {
148*479ab7f0SSascha Wildner     int		howlong;
149*479ab7f0SSascha Wildner     char	*cp, *prompt;
150*479ab7f0SSascha Wildner 
151*479ab7f0SSascha Wildner     prompt = NULL;
152*479ab7f0SSascha Wildner     howlong = -1;
153*479ab7f0SSascha Wildner     switch(argc) {
154*479ab7f0SSascha Wildner     case 3:
155*479ab7f0SSascha Wildner 	prompt = argv[2];
156*479ab7f0SSascha Wildner 	/* FALLTHROUGH */
157*479ab7f0SSascha Wildner     case 2:
158*479ab7f0SSascha Wildner 	howlong = strtol(argv[1], &cp, 0);
159*479ab7f0SSascha Wildner 	if (*cp != 0) {
160*479ab7f0SSascha Wildner 	    snprintf(command_errbuf, sizeof(command_errbuf),
161*479ab7f0SSascha Wildner 		"bad delay '%s'", argv[1]);
162*479ab7f0SSascha Wildner 	    return(CMD_ERROR);
163*479ab7f0SSascha Wildner 	}
164*479ab7f0SSascha Wildner 	/* FALLTHROUGH */
165*479ab7f0SSascha Wildner     case 1:
166*479ab7f0SSascha Wildner 	return(autoboot(howlong, prompt));
167*479ab7f0SSascha Wildner     }
168*479ab7f0SSascha Wildner 
169*479ab7f0SSascha Wildner     command_errmsg = "too many arguments";
170*479ab7f0SSascha Wildner     return(CMD_ERROR);
171*479ab7f0SSascha Wildner }
172*479ab7f0SSascha Wildner 
173*479ab7f0SSascha Wildner /*
174*479ab7f0SSascha Wildner  * Called before we go interactive.  If we think we can autoboot, and
175*479ab7f0SSascha Wildner  * we haven't tried already, try now.
176*479ab7f0SSascha Wildner  */
177*479ab7f0SSascha Wildner void
autoboot_maybe(void)178*479ab7f0SSascha Wildner autoboot_maybe(void)
179*479ab7f0SSascha Wildner {
180*479ab7f0SSascha Wildner     char	*cp;
181*479ab7f0SSascha Wildner 
182*479ab7f0SSascha Wildner     cp = getenv("autoboot_delay");
183*479ab7f0SSascha Wildner     if ((autoboot_tried == 0) && ((cp == NULL) || strcasecmp(cp, "NO")))
184*479ab7f0SSascha Wildner 	autoboot(-1, NULL);		/* try to boot automatically */
185*479ab7f0SSascha Wildner }
186*479ab7f0SSascha Wildner 
187*479ab7f0SSascha Wildner int
autoboot(int timeout,char * prompt)188*479ab7f0SSascha Wildner autoboot(int timeout, char *prompt)
189*479ab7f0SSascha Wildner {
190*479ab7f0SSascha Wildner     time_t	when, otime, ntime;
191*479ab7f0SSascha Wildner     int		c, yes;
192*479ab7f0SSascha Wildner     char	*argv[2], *cp, *ep;
193*479ab7f0SSascha Wildner     char	*kernelname;
194*479ab7f0SSascha Wildner 
195*479ab7f0SSascha Wildner     autoboot_tried = 1;
196*479ab7f0SSascha Wildner 
197*479ab7f0SSascha Wildner     if (timeout == -1) {
198*479ab7f0SSascha Wildner 	/* try to get a delay from the environment */
199*479ab7f0SSascha Wildner 	if ((cp = getenv("autoboot_delay"))) {
200*479ab7f0SSascha Wildner 	    timeout = strtol(cp, &ep, 0);
201*479ab7f0SSascha Wildner 	    if (cp == ep)
202*479ab7f0SSascha Wildner 		timeout = -1;
203*479ab7f0SSascha Wildner 	}
204*479ab7f0SSascha Wildner     }
205*479ab7f0SSascha Wildner     if (timeout == -1)		/* all else fails */
206*479ab7f0SSascha Wildner 	timeout = 10;
207*479ab7f0SSascha Wildner 
208*479ab7f0SSascha Wildner     kernelname = getenv("kernelname");
209*479ab7f0SSascha Wildner     if (kernelname == NULL) {
210*479ab7f0SSascha Wildner 	argv[0] = NULL;
211*479ab7f0SSascha Wildner 	loadakernel(0, 0, argv);
212*479ab7f0SSascha Wildner 	kernelname = getenv("kernelname");
213*479ab7f0SSascha Wildner 	if (kernelname == NULL) {
214*479ab7f0SSascha Wildner 	    command_errmsg = "no valid kernel found";
215*479ab7f0SSascha Wildner 	    return(CMD_ERROR);
216*479ab7f0SSascha Wildner 	}
217*479ab7f0SSascha Wildner     }
218*479ab7f0SSascha Wildner 
219*479ab7f0SSascha Wildner     otime = time(NULL);
220*479ab7f0SSascha Wildner     when = otime + timeout;	/* when to boot */
221*479ab7f0SSascha Wildner     yes = 0;
222*479ab7f0SSascha Wildner 
223*479ab7f0SSascha Wildner     printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or any other key for command prompt." : prompt);
224*479ab7f0SSascha Wildner 
225*479ab7f0SSascha Wildner     for (;;) {
226*479ab7f0SSascha Wildner 	if (ischar()) {
227*479ab7f0SSascha Wildner 	    c = getchar();
228*479ab7f0SSascha Wildner 	    if ((c == '\r') || (c == '\n'))
229*479ab7f0SSascha Wildner 		yes = 1;
230*479ab7f0SSascha Wildner 	    break;
231*479ab7f0SSascha Wildner 	}
232*479ab7f0SSascha Wildner 	ntime = time(NULL);
233*479ab7f0SSascha Wildner 	if (ntime >= when) {
234*479ab7f0SSascha Wildner 	    yes = 1;
235*479ab7f0SSascha Wildner 	    break;
236*479ab7f0SSascha Wildner 	}
237*479ab7f0SSascha Wildner 
238*479ab7f0SSascha Wildner 	if (ntime != otime) {
239*479ab7f0SSascha Wildner 	    printf("\rBooting [%s] in %d second%s... ",
240*479ab7f0SSascha Wildner 	    		kernelname, (int)(when - ntime),
241*479ab7f0SSascha Wildner 			(when-ntime)==1?"":"s");
242*479ab7f0SSascha Wildner 	    otime = ntime;
243*479ab7f0SSascha Wildner 	}
244*479ab7f0SSascha Wildner     }
245*479ab7f0SSascha Wildner     if (yes)
246*479ab7f0SSascha Wildner 	printf("\rBooting [%s]...               ", kernelname);
247*479ab7f0SSascha Wildner     putchar('\n');
248*479ab7f0SSascha Wildner     if (yes) {
249*479ab7f0SSascha Wildner 	argv[0] = "boot";
250*479ab7f0SSascha Wildner 	argv[1] = NULL;
251*479ab7f0SSascha Wildner 	return(command_boot(1, argv));
252*479ab7f0SSascha Wildner     }
253*479ab7f0SSascha Wildner     return(CMD_OK);
254*479ab7f0SSascha Wildner }
255*479ab7f0SSascha Wildner 
256*479ab7f0SSascha Wildner /*
257*479ab7f0SSascha Wildner  * Scrounge for the name of the (try)'th file we will try to boot.
258*479ab7f0SSascha Wildner  */
259*479ab7f0SSascha Wildner static char *
getbootfile(int try)260*479ab7f0SSascha Wildner getbootfile(int try)
261*479ab7f0SSascha Wildner {
262*479ab7f0SSascha Wildner     static char *name = NULL;
263*479ab7f0SSascha Wildner     const char	*spec, *ep;
264*479ab7f0SSascha Wildner     size_t	len;
265*479ab7f0SSascha Wildner 
266*479ab7f0SSascha Wildner     /* we use dynamic storage */
267*479ab7f0SSascha Wildner     if (name != NULL) {
268*479ab7f0SSascha Wildner 	free(name);
269*479ab7f0SSascha Wildner 	name = NULL;
270*479ab7f0SSascha Wildner     }
271*479ab7f0SSascha Wildner 
272*479ab7f0SSascha Wildner     /*
273*479ab7f0SSascha Wildner      * Try $bootfile, then try our builtin default
274*479ab7f0SSascha Wildner      */
275*479ab7f0SSascha Wildner     if ((spec = getenv("bootfile")) == NULL)
276*479ab7f0SSascha Wildner 	spec = default_bootfiles;
277*479ab7f0SSascha Wildner 
278*479ab7f0SSascha Wildner     while ((try > 0) && (spec != NULL)) {
279*479ab7f0SSascha Wildner 	spec = strchr(spec, ';');
280*479ab7f0SSascha Wildner 	if (spec)
281*479ab7f0SSascha Wildner 	    spec++;	/* skip over the leading ';' */
282*479ab7f0SSascha Wildner 	try--;
283*479ab7f0SSascha Wildner     }
284*479ab7f0SSascha Wildner     if (spec != NULL) {
285*479ab7f0SSascha Wildner 	if ((ep = strchr(spec, ';')) != NULL) {
286*479ab7f0SSascha Wildner 	    len = ep - spec;
287*479ab7f0SSascha Wildner 	} else {
288*479ab7f0SSascha Wildner 	    len = strlen(spec);
289*479ab7f0SSascha Wildner 	}
290*479ab7f0SSascha Wildner 	name = malloc(len + 1);
291*479ab7f0SSascha Wildner 	strncpy(name, spec, len);
292*479ab7f0SSascha Wildner 	name[len] = 0;
293*479ab7f0SSascha Wildner     }
294*479ab7f0SSascha Wildner     if (name && name[0] == 0) {
295*479ab7f0SSascha Wildner 	free(name);
296*479ab7f0SSascha Wildner 	name = NULL;
297*479ab7f0SSascha Wildner     }
298*479ab7f0SSascha Wildner     return(name);
299*479ab7f0SSascha Wildner }
300*479ab7f0SSascha Wildner 
301*479ab7f0SSascha Wildner /*
302*479ab7f0SSascha Wildner  * Try to find the /etc/fstab file on the filesystem (rootdev),
303*479ab7f0SSascha Wildner  * which should be be the root filesystem, and parse it to find
304*479ab7f0SSascha Wildner  * out what the kernel ought to think the root filesystem is.
305*479ab7f0SSascha Wildner  *
306*479ab7f0SSascha Wildner  * If we're successful, set vfs.root.mountfrom to <vfstype>:<path>
307*479ab7f0SSascha Wildner  * so that the kernel can tell both which VFS and which node to use
308*479ab7f0SSascha Wildner  * to mount the device.  If this variable's already set, don't
309*479ab7f0SSascha Wildner  * overwrite it.
310*479ab7f0SSascha Wildner  */
311*479ab7f0SSascha Wildner int
getrootmount(char * rootdev)312*479ab7f0SSascha Wildner getrootmount(char *rootdev)
313*479ab7f0SSascha Wildner {
314*479ab7f0SSascha Wildner     char	lbuf[128], *cp, *ep, *dev, *fstyp;
315*479ab7f0SSascha Wildner     int		fd, error;
316*479ab7f0SSascha Wildner 
317*479ab7f0SSascha Wildner     if (getenv("vfs.root.mountfrom") != NULL)
318*479ab7f0SSascha Wildner 	return(0);
319*479ab7f0SSascha Wildner 
320*479ab7f0SSascha Wildner     sprintf(lbuf, "%s/etc/fstab", rootdev);
321*479ab7f0SSascha Wildner     if ((fd = open(lbuf, O_RDONLY)) < 0)
322*479ab7f0SSascha Wildner 	return(1);
323*479ab7f0SSascha Wildner 
324*479ab7f0SSascha Wildner     /* loop reading lines from /etc/fstab    What was that about sscanf again? */
325*479ab7f0SSascha Wildner     error = 1;
326*479ab7f0SSascha Wildner     while (fgetstr(lbuf, sizeof(lbuf), fd) >= 0) {
327*479ab7f0SSascha Wildner 	if ((lbuf[0] == 0) || (lbuf[0] == '#'))
328*479ab7f0SSascha Wildner 	    continue;
329*479ab7f0SSascha Wildner 
330*479ab7f0SSascha Wildner 	/* skip device name */
331*479ab7f0SSascha Wildner 	for (cp = lbuf; (*cp != 0) && !isspace(*cp); cp++)
332*479ab7f0SSascha Wildner 	    ;
333*479ab7f0SSascha Wildner 	if (*cp == 0)		/* misformatted */
334*479ab7f0SSascha Wildner 	    continue;
335*479ab7f0SSascha Wildner 	/* delimit and save */
336*479ab7f0SSascha Wildner 	*cp++ = 0;
337*479ab7f0SSascha Wildner 	dev = strdup(lbuf);
338*479ab7f0SSascha Wildner 
339*479ab7f0SSascha Wildner 	/* skip whitespace up to mountpoint */
340*479ab7f0SSascha Wildner 	while ((*cp != 0) && isspace(*cp))
341*479ab7f0SSascha Wildner 	    cp++;
342*479ab7f0SSascha Wildner 	/* must have /<space> to be root */
343*479ab7f0SSascha Wildner 	if ((*cp == 0) || (*cp != '/') || !isspace(*(cp + 1)))
344*479ab7f0SSascha Wildner 	    continue;
345*479ab7f0SSascha Wildner 	/* skip whitespace up to fstype */
346*479ab7f0SSascha Wildner 	cp += 2;
347*479ab7f0SSascha Wildner 	while ((*cp != 0) && isspace(*cp))
348*479ab7f0SSascha Wildner 	    cp++;
349*479ab7f0SSascha Wildner 	if (*cp == 0)		/* misformatted */
350*479ab7f0SSascha Wildner 	    continue;
351*479ab7f0SSascha Wildner 	/* skip text to end of fstype and delimit */
352*479ab7f0SSascha Wildner 	ep = cp;
353*479ab7f0SSascha Wildner 	while ((*cp != 0) && !isspace(*cp))
354*479ab7f0SSascha Wildner 	    cp++;
355*479ab7f0SSascha Wildner 	*cp = 0;
356*479ab7f0SSascha Wildner 	fstyp = strdup(ep);
357*479ab7f0SSascha Wildner 
358*479ab7f0SSascha Wildner 	/* build the final result and save it */
359*479ab7f0SSascha Wildner 	sprintf(lbuf, "%s:%s", fstyp, dev);
360*479ab7f0SSascha Wildner 	free(dev);
361*479ab7f0SSascha Wildner 	free(fstyp);
362*479ab7f0SSascha Wildner 	setenv("vfs.root.mountfrom", lbuf, 0);
363*479ab7f0SSascha Wildner 	error = 0;
364*479ab7f0SSascha Wildner 	break;
365*479ab7f0SSascha Wildner     }
366*479ab7f0SSascha Wildner     close(fd);
367*479ab7f0SSascha Wildner     return(error);
368*479ab7f0SSascha Wildner }
369*479ab7f0SSascha Wildner 
370*479ab7f0SSascha Wildner static int
loadakernel(int try,int argc,char * argv[])371*479ab7f0SSascha Wildner loadakernel(int try, int argc, char* argv[])
372*479ab7f0SSascha Wildner {
373*479ab7f0SSascha Wildner     char *cp;
374*479ab7f0SSascha Wildner 
375*479ab7f0SSascha Wildner 	for (try = 0; (cp = getbootfile(try)) != NULL; try++)
376*479ab7f0SSascha Wildner 	    if (mod_loadkld(cp, argc - 1, argv + 1) != 0)
377*479ab7f0SSascha Wildner 		printf("can't load '%s'\n", cp);
378*479ab7f0SSascha Wildner 	    else
379*479ab7f0SSascha Wildner 		return 1;
380*479ab7f0SSascha Wildner 	return 0;
381*479ab7f0SSascha Wildner }
382*479ab7f0SSascha Wildner 
383