bootinfo.c revision 38465
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 * $Id$ 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 6038465Smsmith howto = 0; 6138465Smsmith if (kargs != NULL) { 6238465Smsmith cp = kargs; 6338465Smsmith active = 0; 6438465Smsmith while (*cp != 0) { 6538465Smsmith if (!active && (*cp == '-')) { 6638465Smsmith active = 1; 6738465Smsmith } else if (active) 6838465Smsmith switch (*cp) { 6938465Smsmith case 'a': 7038465Smsmith howto |= RB_ASKNAME; 7138465Smsmith break; 7238465Smsmith case 'c': 7338465Smsmith howto |= RB_CONFIG; 7438465Smsmith break; 7538465Smsmith case 'd': 7638465Smsmith howto |= RB_KDB; 7738465Smsmith break; 7838465Smsmith case 'g': 7938465Smsmith howto |= RB_GDB; 8038465Smsmith break; 8138465Smsmith case 'h': 8238465Smsmith howto |= RB_SERIAL; 8338465Smsmith break; 8438465Smsmith case 'r': 8538465Smsmith howto |= RB_DFLTROOT; 8638465Smsmith break; 8738465Smsmith case 's': 8838465Smsmith howto |= RB_SINGLE; 8938465Smsmith break; 9038465Smsmith case 'v': 9138465Smsmith howto |= RB_VERBOSE; 9238465Smsmith break; 9338465Smsmith default: 9438465Smsmith active = 0; 9538465Smsmith break; 9638465Smsmith } 9738465Smsmith } 9838465Smsmith cp++; 9938465Smsmith } 10038465Smsmith for (i = 0; howto_names[i].ev != NULL; i++) 10138465Smsmith if (getenv(howto_names[i].ev) != NULL) 10238465Smsmith howto |= howto_names[i].mask; 10338465Smsmith if (!strcmp(getenv("console"), "comconsole")) 10438465Smsmith howto |= RB_SERIAL; 10538465Smsmith return(howto); 10638465Smsmith} 10738465Smsmith 10838465Smsmith/* 10938465Smsmith * Copy the environment into the load area starting at (addr). 11038465Smsmith * Each variable is formatted as <name>=<value>, with a single nul 11138465Smsmith * separating each variable, and a double nul terminating the environment. 11238465Smsmith */ 11338465Smsmithvm_offset_t 11438465Smsmithbi_copyenv(vm_offset_t addr) 11538465Smsmith{ 11638465Smsmith struct env_var *ep; 11738465Smsmith 11838465Smsmith /* traverse the environment */ 11938465Smsmith for (ep = environ; ep != NULL; ep = ep->ev_next) { 12038465Smsmith vpbcopy(ep->ev_name, addr, strlen(ep->ev_name)); 12138465Smsmith addr += strlen(ep->ev_name); 12238465Smsmith vpbcopy("=", addr, 1); 12338465Smsmith addr++; 12438465Smsmith if (ep->ev_value != NULL) { 12538465Smsmith vpbcopy(ep->ev_value, addr, strlen(ep->ev_value)); 12638465Smsmith addr += strlen(ep->ev_value); 12738465Smsmith } 12838465Smsmith vpbcopy("", addr, 1); 12938465Smsmith addr++; 13038465Smsmith } 13138465Smsmith vpbcopy("", addr, 1); 13238465Smsmith addr++; 13338465Smsmith} 13438465Smsmith 13538465Smsmith/* 13638465Smsmith * Copy module-related data into the load area, where it can be 13738465Smsmith * used as a directory for loaded modules. 13838465Smsmith * 13938465Smsmith * Module data is presented in a self-describing format. Each datum 14038465Smsmith * is preceeded by a 16-bit identifier and a 16-bit size field. 14138465Smsmith * 14238465Smsmith * Currently, the following data are saved: 14338465Smsmith * 14438465Smsmith * MOD_NAME (variable) module name (string) 14538465Smsmith * MOD_TYPE (variable) module type (string) 14638465Smsmith * MOD_ADDR sizeof(vm_offset_t) module load address 14738465Smsmith * MOD_SIZE sizeof(size_t) module size 14838465Smsmith * MOD_METADATA (variable) type-specific metadata 14938465Smsmith */ 15038465Smsmith#define MOD_STR(t, a, s) { \ 15138465Smsmith u_int32_t ident = (t << 16) + strlen(s) + 1; \ 15238465Smsmith vpbcopy(&ident, a, sizeof(ident)); \ 15338465Smsmith a += sizeof(ident); \ 15438465Smsmith vpbcopy(s, a, strlen(s) + 1); \ 15538465Smsmith a += strlen(s) + 1; \ 15638465Smsmith} 15738465Smsmith 15838465Smsmith#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s) 15938465Smsmith#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s) 16038465Smsmith 16138465Smsmith#define MOD_VAR(t, a, s) { \ 16238465Smsmith u_int32_t ident = (t << 16) + sizeof(s); \ 16338465Smsmith vpbcopy(&ident, a, sizeof(ident)); \ 16438465Smsmith a += sizeof(ident); \ 16538465Smsmith vpbcopy(&s, a, sizeof(s)); \ 16638465Smsmith a += sizeof(s); \ 16738465Smsmith} 16838465Smsmith 16938465Smsmith#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s) 17038465Smsmith#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s) 17138465Smsmith 17238465Smsmith#define MOD_METADATA(a, mm) { \ 17338465Smsmith u_int32_t ident = ((MODINFO_METADATA | mm->md_type) << 16) + mm->md_size; \ 17438465Smsmith vpbcopy(&ident, a, sizeof(ident)); \ 17538465Smsmith a += sizeof(ident); \ 17638465Smsmith vpbcopy(mm->md_data, a, mm->md_size); \ 17738465Smsmith a += mm->md_size; \ 17838465Smsmith} 17938465Smsmith 18038465Smsmithvm_offset_t 18138465Smsmithbi_copymodules(vm_offset_t addr) 18238465Smsmith{ 18338465Smsmith struct loaded_module *mp; 18438465Smsmith struct module_metadata *md; 18538465Smsmith 18638465Smsmith /* start with the first module on the list, should be the kernel */ 18738465Smsmith for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) { 18838465Smsmith 18938465Smsmith MOD_NAME(addr, mp->m_name); 19038465Smsmith MOD_TYPE(addr, mp->m_type); 19138465Smsmith MOD_ADDR(addr, mp->m_addr); 19238465Smsmith MOD_SIZE(addr, mp->m_size); 19338465Smsmith for (md = mp->m_metadata; md != NULL; md = md->md_next) 19438465Smsmith MOD_METADATA(addr, md); 19538465Smsmith } 19638465Smsmith return(addr); 19738465Smsmith} 198