bootinfo.c revision 150470
1/*- 2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/sys/boot/i386/libi386/bootinfo.c 150470 2005-09-22 15:14:13Z ru $"); 29 30#include <stand.h> 31#include <sys/param.h> 32#include <sys/reboot.h> 33#include <sys/linker.h> 34#include "bootstrap.h" 35#include "libi386.h" 36#include "btxv86.h" 37 38/* 39 * Return a 'boothowto' value corresponding to the kernel arguments in 40 * (kargs) and any relevant environment variables. 41 */ 42static struct 43{ 44 const char *ev; 45 int mask; 46} howto_names[] = { 47 {"boot_askname", RB_ASKNAME}, 48 {"boot_cdrom", RB_CDROM}, 49 {"boot_ddb", RB_KDB}, 50 {"boot_dfltroot", RB_DFLTROOT}, 51 {"boot_gdb", RB_GDB}, 52 {"boot_multicons", RB_MULTIPLE}, 53 {"boot_mute", RB_MUTE}, 54 {"boot_pause", RB_PAUSE}, 55 {"boot_serial", RB_SERIAL}, 56 {"boot_single", RB_SINGLE}, 57 {"boot_verbose", RB_VERBOSE}, 58 {NULL, 0} 59}; 60 61int 62bi_getboothowto(char *kargs) 63{ 64 char *cp; 65 char *curpos, *next, *string; 66 int howto; 67 int active; 68 int i; 69 int vidconsole; 70 71 /* Parse kargs */ 72 howto = 0; 73 if (kargs != NULL) { 74 cp = kargs; 75 active = 0; 76 while (*cp != 0) { 77 if (!active && (*cp == '-')) { 78 active = 1; 79 } else if (active) 80 switch (*cp) { 81 case 'a': 82 howto |= RB_ASKNAME; 83 break; 84 case 'C': 85 howto |= RB_CDROM; 86 break; 87 case 'd': 88 howto |= RB_KDB; 89 break; 90 case 'D': 91 howto |= RB_MULTIPLE; 92 break; 93 case 'm': 94 howto |= RB_MUTE; 95 break; 96 case 'g': 97 howto |= RB_GDB; 98 break; 99 case 'h': 100 howto |= RB_SERIAL; 101 break; 102 case 'p': 103 howto |= RB_PAUSE; 104 break; 105 case 'r': 106 howto |= RB_DFLTROOT; 107 break; 108 case 's': 109 howto |= RB_SINGLE; 110 break; 111 case 'v': 112 howto |= RB_VERBOSE; 113 break; 114 default: 115 active = 0; 116 break; 117 } 118 cp++; 119 } 120 } 121 /* get equivalents from the environment */ 122 for (i = 0; howto_names[i].ev != NULL; i++) 123 if (getenv(howto_names[i].ev) != NULL) 124 howto |= howto_names[i].mask; 125 126 /* Enable selected consoles */ 127 string = next = strdup(getenv("console")); 128 vidconsole = 0; 129 while (next != NULL) { 130 curpos = strsep(&next, " ,"); 131 if (*curpos == '\0') 132 continue; 133 if (!strcmp(curpos, "vidconsole")) 134 vidconsole = 1; 135 else if (!strcmp(curpos, "comconsole")) 136 howto |= RB_SERIAL; 137 else if (!strcmp(curpos, "nullconsole")) 138 howto |= RB_MUTE; 139 } 140 141 if (vidconsole && (howto & RB_SERIAL)) 142 howto |= RB_MULTIPLE; 143 144 /* 145 * XXX: Note that until the kernel is ready to respect multiple consoles 146 * for the boot messages, the first named console is the primary console 147 */ 148 if (!strcmp(string, "vidconsole")) 149 howto &= ~RB_SERIAL; 150 151 free(string); 152 153 return(howto); 154} 155 156void 157bi_setboothowto(int howto) 158{ 159 int i; 160 161 for (i = 0; howto_names[i].ev != NULL; i++) 162 if (howto & howto_names[i].mask) 163 setenv(howto_names[i].ev, "YES", 1); 164} 165 166/* 167 * Copy the environment into the load area starting at (addr). 168 * Each variable is formatted as <name>=<value>, with a single nul 169 * separating each variable, and a double nul terminating the environment. 170 */ 171vm_offset_t 172bi_copyenv(vm_offset_t addr) 173{ 174 struct env_var *ep; 175 176 /* traverse the environment */ 177 for (ep = environ; ep != NULL; ep = ep->ev_next) { 178 i386_copyin(ep->ev_name, addr, strlen(ep->ev_name)); 179 addr += strlen(ep->ev_name); 180 i386_copyin("=", addr, 1); 181 addr++; 182 if (ep->ev_value != NULL) { 183 i386_copyin(ep->ev_value, addr, strlen(ep->ev_value)); 184 addr += strlen(ep->ev_value); 185 } 186 i386_copyin("", addr, 1); 187 addr++; 188 } 189 i386_copyin("", addr, 1); 190 addr++; 191 return(addr); 192} 193