bootinfo.c revision 146698
138465Smsmith/*-
238465Smsmith * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
338465Smsmith * All rights reserved.
438465Smsmith *
538465Smsmith * Redistribution and use in source and binary forms, with or without
638465Smsmith * modification, are permitted provided that the following conditions
738465Smsmith * are met:
838465Smsmith * 1. Redistributions of source code must retain the above copyright
938465Smsmith *    notice, this list of conditions and the following disclaimer.
1038465Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1138465Smsmith *    notice, this list of conditions and the following disclaimer in the
1238465Smsmith *    documentation and/or other materials provided with the distribution.
1338465Smsmith *
1438465Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1538465Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1638465Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1738465Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1838465Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1938465Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2038465Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2138465Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2238465Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2338465Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2438465Smsmith * SUCH DAMAGE.
2538465Smsmith */
2638465Smsmith
27119482Sobrien#include <sys/cdefs.h>
28119482Sobrien__FBSDID("$FreeBSD: head/sys/boot/i386/libi386/bootinfo.c 146698 2005-05-27 19:31:00Z jhb $");
29119482Sobrien
3039902Smsmith#include <stand.h>
3139902Smsmith#include <sys/param.h>
3238465Smsmith#include <sys/reboot.h>
3340146Speter#include <sys/linker.h>
3438465Smsmith#include "bootstrap.h"
3539902Smsmith#include "libi386.h"
3639902Smsmith#include "btxv86.h"
3738465Smsmith
3838465Smsmith/*
3938465Smsmith * Return a 'boothowto' value corresponding to the kernel arguments in
4038465Smsmith * (kargs) and any relevant environment variables.
4138465Smsmith */
4238465Smsmithstatic struct
4338465Smsmith{
4464187Sjhb    const char	*ev;
4538465Smsmith    int		mask;
4638465Smsmith} howto_names[] = {
4738465Smsmith    {"boot_askname",	RB_ASKNAME},
4847727Sghelmer    {"boot_cdrom",	RB_CDROM},
4938465Smsmith    {"boot_ddb",	RB_KDB},
5038465Smsmith    {"boot_gdb",	RB_GDB},
5138465Smsmith    {"boot_single",	RB_SINGLE},
5238465Smsmith    {"boot_verbose",	RB_VERBOSE},
5398472Speter    {"boot_multicons",	RB_MULTIPLE},
5498472Speter    {"boot_serial",	RB_SERIAL},
5538465Smsmith    {NULL,	0}
5638465Smsmith};
5738465Smsmith
5838465Smsmithint
5938465Smsmithbi_getboothowto(char *kargs)
6038465Smsmith{
6138465Smsmith    char	*cp;
62146698Sjhb    char	*curpos, *next, *string;
6338465Smsmith    int		howto;
6438465Smsmith    int		active;
6538465Smsmith    int		i;
66146698Sjhb    int		vidconsole;
67146698Sjhb
6839178Smsmith    /* Parse kargs */
6938465Smsmith    howto = 0;
7038465Smsmith    if (kargs  != NULL) {
7138465Smsmith	cp = kargs;
7238465Smsmith	active = 0;
7338465Smsmith	while (*cp != 0) {
7438465Smsmith	    if (!active && (*cp == '-')) {
7538465Smsmith		active = 1;
7638465Smsmith	    } else if (active)
7738465Smsmith		switch (*cp) {
7838465Smsmith		case 'a':
7938465Smsmith		    howto |= RB_ASKNAME;
8038465Smsmith		    break;
8147727Sghelmer		case 'C':
8247727Sghelmer		    howto |= RB_CDROM;
8347727Sghelmer		    break;
8438465Smsmith		case 'd':
8538465Smsmith		    howto |= RB_KDB;
8638465Smsmith		    break;
8785376Sjlemon		case 'D':
8885376Sjlemon		    howto |= RB_MULTIPLE;
8985376Sjlemon		    break;
9066133Sarchie		case 'm':
9166133Sarchie		    howto |= RB_MUTE;
9266133Sarchie		    break;
9338465Smsmith		case 'g':
9438465Smsmith		    howto |= RB_GDB;
9538465Smsmith		    break;
9638465Smsmith		case 'h':
9738465Smsmith		    howto |= RB_SERIAL;
9838465Smsmith		    break;
9987620Sguido		case 'p':
10087620Sguido		    howto |= RB_PAUSE;
10187620Sguido		    break;
10238465Smsmith		case 'r':
10338465Smsmith		    howto |= RB_DFLTROOT;
10438465Smsmith		    break;
10538465Smsmith		case 's':
10638465Smsmith		    howto |= RB_SINGLE;
10738465Smsmith		    break;
10838465Smsmith		case 'v':
10938465Smsmith		    howto |= RB_VERBOSE;
11038465Smsmith		    break;
11138465Smsmith		default:
11238465Smsmith		    active = 0;
11338465Smsmith		    break;
11438465Smsmith		}
11539178Smsmith	    cp++;
11638465Smsmith	}
11738465Smsmith    }
11839178Smsmith    /* get equivalents from the environment */
11938465Smsmith    for (i = 0; howto_names[i].ev != NULL; i++)
12038465Smsmith	if (getenv(howto_names[i].ev) != NULL)
12138465Smsmith	    howto |= howto_names[i].mask;
122146698Sjhb
123146698Sjhb    /* Enable selected consoles */
124146698Sjhb    string = next = strdup(getenv("console"));
125146698Sjhb    vidconsole = 0;
126146698Sjhb    while (next != NULL) {
127146698Sjhb	curpos = strsep(&next, " ,");
128146698Sjhb	if (*curpos == '\0')
129146698Sjhb		continue;
130146698Sjhb	if (!strcmp(curpos, "vidconsole"))
131146698Sjhb	    vidconsole = 1;
132146698Sjhb	else if (!strcmp(curpos, "comconsole"))
133146698Sjhb	    howto |= RB_SERIAL;
134146698Sjhb	else if (!strcmp(curpos, "nullconsole"))
135146698Sjhb	    howto |= RB_MUTE;
136146698Sjhb    }
137146698Sjhb
138146698Sjhb    if (vidconsole && (howto & RB_SERIAL))
139146698Sjhb	howto |= RB_MULTIPLE;
140146698Sjhb
141146698Sjhb    /*
142146698Sjhb     * XXX: Note that until the kernel is ready to respect multiple consoles
143146698Sjhb     * for the boot messages, the first named console is the primary console
144146698Sjhb     */
145146698Sjhb    if (!strcmp(string, "vidconsole"))
146146698Sjhb	howto &= ~RB_SERIAL;
147146698Sjhb
148146698Sjhb    free(string);
149146698Sjhb
15038465Smsmith    return(howto);
15138465Smsmith}
15238465Smsmith
15338465Smsmith/*
15438465Smsmith * Copy the environment into the load area starting at (addr).
15538465Smsmith * Each variable is formatted as <name>=<value>, with a single nul
15638465Smsmith * separating each variable, and a double nul terminating the environment.
15738465Smsmith */
15838465Smsmithvm_offset_t
15938465Smsmithbi_copyenv(vm_offset_t addr)
16038465Smsmith{
16138465Smsmith    struct env_var	*ep;
16238465Smsmith
16338465Smsmith    /* traverse the environment */
16438465Smsmith    for (ep = environ; ep != NULL; ep = ep->ev_next) {
16539441Smsmith	i386_copyin(ep->ev_name, addr, strlen(ep->ev_name));
16638465Smsmith	addr += strlen(ep->ev_name);
16739441Smsmith	i386_copyin("=", addr, 1);
16838465Smsmith	addr++;
16938465Smsmith	if (ep->ev_value != NULL) {
17039441Smsmith	    i386_copyin(ep->ev_value, addr, strlen(ep->ev_value));
17138465Smsmith	    addr += strlen(ep->ev_value);
17238465Smsmith	}
17339441Smsmith	i386_copyin("", addr, 1);
17438465Smsmith	addr++;
17538465Smsmith    }
17639441Smsmith    i386_copyin("", addr, 1);
17738465Smsmith    addr++;
17839730Speter    return(addr);
17938465Smsmith}
180