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