bootinfo.c revision 146698
159191Skris/*-
259191Skris * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
359191Skris * All rights reserved.
459191Skris *
559191Skris * Redistribution and use in source and binary forms, with or without
659191Skris * modification, are permitted provided that the following conditions
759191Skris * are met:
859191Skris * 1. Redistributions of source code must retain the above copyright
959191Skris *    notice, this list of conditions and the following disclaimer.
1059191Skris * 2. Redistributions in binary form must reproduce the above copyright
1159191Skris *    notice, this list of conditions and the following disclaimer in the
1259191Skris *    documentation and/or other materials provided with the distribution.
1359191Skris *
1459191Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1559191Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1659191Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1759191Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1859191Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19160814Ssimon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20160814Ssimon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2159191Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2259191Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2359191Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2459191Skris * SUCH DAMAGE.
2559191Skris */
2659191Skris
2759191Skris#include <sys/cdefs.h>
2859191Skris__FBSDID("$FreeBSD: head/sys/boot/i386/libi386/bootinfo.c 146698 2005-05-27 19:31:00Z jhb $");
2959191Skris
3059191Skris#include <stand.h>
3159191Skris#include <sys/param.h>
3259191Skris#include <sys/reboot.h>
3359191Skris#include <sys/linker.h>
3459191Skris#include "bootstrap.h"
3559191Skris#include "libi386.h"
3659191Skris#include "btxv86.h"
3759191Skris
3859191Skris/*
3959191Skris * Return a 'boothowto' value corresponding to the kernel arguments in
4059191Skris * (kargs) and any relevant environment variables.
4159191Skris */
4259191Skrisstatic struct
4359191Skris{
4459191Skris    const char	*ev;
4559191Skris    int		mask;
4659191Skris} howto_names[] = {
4759191Skris    {"boot_askname",	RB_ASKNAME},
4859191Skris    {"boot_cdrom",	RB_CDROM},
4959191Skris    {"boot_ddb",	RB_KDB},
5059191Skris    {"boot_gdb",	RB_GDB},
5159191Skris    {"boot_single",	RB_SINGLE},
5259191Skris    {"boot_verbose",	RB_VERBOSE},
5359191Skris    {"boot_multicons",	RB_MULTIPLE},
5459191Skris    {"boot_serial",	RB_SERIAL},
5559191Skris    {NULL,	0}
5659191Skris};
5759191Skris
5859191Skrisint
5959191Skrisbi_getboothowto(char *kargs)
6059191Skris{
6159191Skris    char	*cp;
6259191Skris    char	*curpos, *next, *string;
6359191Skris    int		howto;
6459191Skris    int		active;
6559191Skris    int		i;
6659191Skris    int		vidconsole;
6759191Skris
6859191Skris    /* Parse kargs */
6959191Skris    howto = 0;
7059191Skris    if (kargs  != NULL) {
7159191Skris	cp = kargs;
72160814Ssimon	active = 0;
7359191Skris	while (*cp != 0) {
74160814Ssimon	    if (!active && (*cp == '-')) {
75238405Sjkim		active = 1;
76238405Sjkim	    } else if (active)
77238405Sjkim		switch (*cp) {
78238405Sjkim		case 'a':
79238405Sjkim		    howto |= RB_ASKNAME;
80160814Ssimon		    break;
8159191Skris		case 'C':
8259191Skris		    howto |= RB_CDROM;
8359191Skris		    break;
8459191Skris		case 'd':
8559191Skris		    howto |= RB_KDB;
8659191Skris		    break;
8759191Skris		case 'D':
8859191Skris		    howto |= RB_MULTIPLE;
8959191Skris		    break;
9059191Skris		case 'm':
9159191Skris		    howto |= RB_MUTE;
9259191Skris		    break;
9359191Skris		case 'g':
9459191Skris		    howto |= RB_GDB;
9559191Skris		    break;
9659191Skris		case 'h':
9759191Skris		    howto |= RB_SERIAL;
9859191Skris		    break;
9959191Skris		case 'p':
10059191Skris		    howto |= RB_PAUSE;
10159191Skris		    break;
10259191Skris		case 'r':
10359191Skris		    howto |= RB_DFLTROOT;
10459191Skris		    break;
10559191Skris		case 's':
10659191Skris		    howto |= RB_SINGLE;
10759191Skris		    break;
10859191Skris		case 'v':
10959191Skris		    howto |= RB_VERBOSE;
11059191Skris		    break;
11159191Skris		default:
11259191Skris		    active = 0;
11359191Skris		    break;
11459191Skris		}
11559191Skris	    cp++;
11659191Skris	}
11759191Skris    }
11859191Skris    /* get equivalents from the environment */
11959191Skris    for (i = 0; howto_names[i].ev != NULL; i++)
12059191Skris	if (getenv(howto_names[i].ev) != NULL)
12159191Skris	    howto |= howto_names[i].mask;
12259191Skris
12359191Skris    /* Enable selected consoles */
12459191Skris    string = next = strdup(getenv("console"));
12559191Skris    vidconsole = 0;
12659191Skris    while (next != NULL) {
12759191Skris	curpos = strsep(&next, " ,");
12859191Skris	if (*curpos == '\0')
12959191Skris		continue;
13059191Skris	if (!strcmp(curpos, "vidconsole"))
13159191Skris	    vidconsole = 1;
13259191Skris	else if (!strcmp(curpos, "comconsole"))
13359191Skris	    howto |= RB_SERIAL;
134160814Ssimon	else if (!strcmp(curpos, "nullconsole"))
135160814Ssimon	    howto |= RB_MUTE;
136160814Ssimon    }
137160814Ssimon
138160814Ssimon    if (vidconsole && (howto & RB_SERIAL))
139160814Ssimon	howto |= RB_MULTIPLE;
140160814Ssimon
141160814Ssimon    /*
142160814Ssimon     * XXX: Note that until the kernel is ready to respect multiple consoles
143160814Ssimon     * for the boot messages, the first named console is the primary console
144160814Ssimon     */
145160814Ssimon    if (!strcmp(string, "vidconsole"))
146160814Ssimon	howto &= ~RB_SERIAL;
147160814Ssimon
148160814Ssimon    free(string);
149160814Ssimon
150160814Ssimon    return(howto);
151160814Ssimon}
152160814Ssimon
153160814Ssimon/*
154160814Ssimon * Copy the environment into the load area starting at (addr).
155160814Ssimon * Each variable is formatted as <name>=<value>, with a single nul
156160814Ssimon * separating each variable, and a double nul terminating the environment.
157160814Ssimon */
158160814Ssimonvm_offset_t
159160814Ssimonbi_copyenv(vm_offset_t addr)
160160814Ssimon{
161160814Ssimon    struct env_var	*ep;
162160814Ssimon
163160814Ssimon    /* traverse the environment */
164160814Ssimon    for (ep = environ; ep != NULL; ep = ep->ev_next) {
165160814Ssimon	i386_copyin(ep->ev_name, addr, strlen(ep->ev_name));
16659191Skris	addr += strlen(ep->ev_name);
16759191Skris	i386_copyin("=", addr, 1);
168160814Ssimon	addr++;
16959191Skris	if (ep->ev_value != NULL) {
17059191Skris	    i386_copyin(ep->ev_value, addr, strlen(ep->ev_value));
171238405Sjkim	    addr += strlen(ep->ev_value);
172238405Sjkim	}
173238405Sjkim	i386_copyin("", addr, 1);
174238405Sjkim	addr++;
17559191Skris    }
176    i386_copyin("", addr, 1);
177    addr++;
178    return(addr);
179}
180