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