bootinfo32.c revision 39441
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 * 2639441Smsmith * $Id: bootinfo.c,v 1.3 1998/09/14 18:27:05 msmith Exp $ 2738465Smsmith */ 2838465Smsmith 2938465Smsmith#include <sys/reboot.h> 3038465Smsmith#include <stand.h> 3138465Smsmith#include "bootstrap.h" 3238465Smsmith 3338465Smsmith 3438465Smsmith/* 3538465Smsmith * Return a 'boothowto' value corresponding to the kernel arguments in 3638465Smsmith * (kargs) and any relevant environment variables. 3738465Smsmith */ 3838465Smsmithstatic struct 3938465Smsmith{ 4038465Smsmith char *ev; 4138465Smsmith int mask; 4238465Smsmith} howto_names[] = { 4338465Smsmith {"boot_askname", RB_ASKNAME}, 4438465Smsmith {"boot_userconfig", RB_CONFIG}, 4538465Smsmith {"boot_ddb", RB_KDB}, 4638465Smsmith {"boot_gdb", RB_GDB}, 4738465Smsmith {"boot_single", RB_SINGLE}, 4838465Smsmith {"boot_verbose", RB_VERBOSE}, 4938465Smsmith {NULL, 0} 5038465Smsmith}; 5138465Smsmith 5238465Smsmithint 5338465Smsmithbi_getboothowto(char *kargs) 5438465Smsmith{ 5538465Smsmith char *cp; 5638465Smsmith int howto; 5738465Smsmith int active; 5838465Smsmith int i; 5938465Smsmith 6039178Smsmith /* Parse kargs */ 6138465Smsmith howto = 0; 6238465Smsmith if (kargs != NULL) { 6338465Smsmith cp = kargs; 6438465Smsmith active = 0; 6538465Smsmith while (*cp != 0) { 6638465Smsmith if (!active && (*cp == '-')) { 6738465Smsmith active = 1; 6838465Smsmith } else if (active) 6938465Smsmith switch (*cp) { 7038465Smsmith case 'a': 7138465Smsmith howto |= RB_ASKNAME; 7238465Smsmith break; 7338465Smsmith case 'c': 7438465Smsmith howto |= RB_CONFIG; 7538465Smsmith break; 7638465Smsmith case 'd': 7738465Smsmith howto |= RB_KDB; 7838465Smsmith break; 7938465Smsmith case 'g': 8038465Smsmith howto |= RB_GDB; 8138465Smsmith break; 8238465Smsmith case 'h': 8338465Smsmith howto |= RB_SERIAL; 8438465Smsmith break; 8538465Smsmith case 'r': 8638465Smsmith howto |= RB_DFLTROOT; 8738465Smsmith break; 8838465Smsmith case 's': 8938465Smsmith howto |= RB_SINGLE; 9038465Smsmith break; 9138465Smsmith case 'v': 9238465Smsmith howto |= RB_VERBOSE; 9338465Smsmith break; 9438465Smsmith default: 9538465Smsmith active = 0; 9638465Smsmith break; 9738465Smsmith } 9839178Smsmith active = 0; 9939178Smsmith cp++; 10038465Smsmith } 10138465Smsmith } 10239178Smsmith /* get equivalents from the environment */ 10338465Smsmith for (i = 0; howto_names[i].ev != NULL; i++) 10438465Smsmith if (getenv(howto_names[i].ev) != NULL) 10538465Smsmith howto |= howto_names[i].mask; 10638465Smsmith if (!strcmp(getenv("console"), "comconsole")) 10738465Smsmith howto |= RB_SERIAL; 10838465Smsmith return(howto); 10938465Smsmith} 11038465Smsmith 11138465Smsmith/* 11238465Smsmith * Copy the environment into the load area starting at (addr). 11338465Smsmith * Each variable is formatted as <name>=<value>, with a single nul 11438465Smsmith * separating each variable, and a double nul terminating the environment. 11538465Smsmith */ 11638465Smsmithvm_offset_t 11738465Smsmithbi_copyenv(vm_offset_t addr) 11838465Smsmith{ 11938465Smsmith struct env_var *ep; 12038465Smsmith 12138465Smsmith /* traverse the environment */ 12238465Smsmith for (ep = environ; ep != NULL; ep = ep->ev_next) { 12339441Smsmith i386_copyin(ep->ev_name, addr, strlen(ep->ev_name)); 12438465Smsmith addr += strlen(ep->ev_name); 12539441Smsmith i386_copyin("=", addr, 1); 12638465Smsmith addr++; 12738465Smsmith if (ep->ev_value != NULL) { 12839441Smsmith i386_copyin(ep->ev_value, addr, strlen(ep->ev_value)); 12938465Smsmith addr += strlen(ep->ev_value); 13038465Smsmith } 13139441Smsmith i386_copyin("", addr, 1); 13238465Smsmith addr++; 13338465Smsmith } 13439441Smsmith i386_copyin("", addr, 1); 13538465Smsmith addr++; 13638465Smsmith} 13738465Smsmith 13838465Smsmith/* 13938465Smsmith * Copy module-related data into the load area, where it can be 14038465Smsmith * used as a directory for loaded modules. 14138465Smsmith * 14238465Smsmith * Module data is presented in a self-describing format. Each datum 14339178Smsmith * is preceeded by a 32-bit identifier and a 32-bit size field. 14438465Smsmith * 14538465Smsmith * Currently, the following data are saved: 14638465Smsmith * 14738465Smsmith * MOD_NAME (variable) module name (string) 14838465Smsmith * MOD_TYPE (variable) module type (string) 14938465Smsmith * MOD_ADDR sizeof(vm_offset_t) module load address 15038465Smsmith * MOD_SIZE sizeof(size_t) module size 15138465Smsmith * MOD_METADATA (variable) type-specific metadata 15238465Smsmith */ 15338465Smsmith#define MOD_STR(t, a, s) { \ 15438465Smsmith u_int32_t ident = (t << 16) + strlen(s) + 1; \ 15539441Smsmith i386_copyin(&ident, a, sizeof(ident)); \ 15638465Smsmith a += sizeof(ident); \ 15739441Smsmith i386_copyin(s, a, strlen(s) + 1); \ 15838465Smsmith a += strlen(s) + 1; \ 15938465Smsmith} 16038465Smsmith 16138465Smsmith#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s) 16238465Smsmith#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s) 16338465Smsmith 16438465Smsmith#define MOD_VAR(t, a, s) { \ 16538465Smsmith u_int32_t ident = (t << 16) + sizeof(s); \ 16639441Smsmith i386_copyin(&ident, a, sizeof(ident)); \ 16738465Smsmith a += sizeof(ident); \ 16839441Smsmith i386_copyin(&s, a, sizeof(s)); \ 16938465Smsmith a += sizeof(s); \ 17038465Smsmith} 17138465Smsmith 17238465Smsmith#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s) 17338465Smsmith#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s) 17438465Smsmith 17538465Smsmith#define MOD_METADATA(a, mm) { \ 17638465Smsmith u_int32_t ident = ((MODINFO_METADATA | mm->md_type) << 16) + mm->md_size; \ 17739441Smsmith i386_copyin(&ident, a, sizeof(ident)); \ 17838465Smsmith a += sizeof(ident); \ 17939441Smsmith i386_copyin(mm->md_data, a, mm->md_size); \ 18038465Smsmith a += mm->md_size; \ 18138465Smsmith} 18238465Smsmith 18339441Smsmith#define MOD_END(a) { \ 18439441Smsmith u_int32_t ident = 0; \ 18539441Smsmith i386_copyin(&ident, a, sizeof(ident)); \ 18639441Smsmith a += sizeof(ident); \ 18739441Smsmith i386_copyin(&ident, a, sizeof(ident)); \ 18839441Smsmith a += sizeof(ident); \ 18939178Smsmith} 19039178Smsmith 19138465Smsmithvm_offset_t 19238465Smsmithbi_copymodules(vm_offset_t addr) 19338465Smsmith{ 19438465Smsmith struct loaded_module *mp; 19538465Smsmith struct module_metadata *md; 19638465Smsmith 19738465Smsmith /* start with the first module on the list, should be the kernel */ 19838465Smsmith for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) { 19938465Smsmith 20039178Smsmith MOD_NAME(addr, mp->m_name); /* this field must come first */ 20138465Smsmith MOD_TYPE(addr, mp->m_type); 20238465Smsmith MOD_ADDR(addr, mp->m_addr); 20338465Smsmith MOD_SIZE(addr, mp->m_size); 20438465Smsmith for (md = mp->m_metadata; md != NULL; md = md->md_next) 20538764Smsmith if (!(md->md_type & MODINFOMD_NOCOPY)) 20638764Smsmith MOD_METADATA(addr, md); 20738465Smsmith } 20839178Smsmith MOD_END(addr); 20938465Smsmith return(addr); 21038465Smsmith} 211