/*
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1982, 1986, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)boot.c 8.1 (Berkeley) 6/10/93
*/
/*
* Copyright (c) 1996
* Matthias Drochner. All rights reserved.
* Copyright (c) 1996
* Perry E. Metzger. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)boot.c 8.1 (Berkeley) 6/10/93
*/
/*
* Starts a NetBSD ELF kernel. The low level startup is done in startprog.S.
*/
/*
* Add a /-separated list of module names to the boot list
*/
void
module_add_split(const char *name, uint8_t type)
{
char mod_name[MAXMODNAME];
int i;
const char *mp = name;
char *ep;
while (*mp) { /* scan list of module names */
i = MAXMODNAME;
ep = mod_name;
while (--i) { /* scan for end of first name */
*ep = *mp;
if (*ep == '/') /* NUL-terminate the name */
*ep = '\0';
if (*ep == 0 ) { /* add non-empty name */
if (ep != mod_name)
module_add_common(mod_name, type);
break;
}
ep++; mp++;
}
if (*ep != 0) {
printf("module name too long\n");
return;
}
if (*mp == '/') { /* skip separator if more */
mp++;
}
}
}
/*
* Gather some information for the kernel. Do this after the
* "point of no return" to avoid memory leaks.
*/
#ifdef PASS_BIOSGEOM
bi_getbiosgeom();
#endif
#ifdef PASS_MEMMAP
bi_getmemmap();
#endif
/* If the root fs type is unusual, load its module. */
if (fsmod != NULL)
module_add_split(fsmod, BM_TYPE_KMOD);
/*
* Gather some information for the kernel. Do this after the
* "point of no return" to avoid memory leaks.
*/
#ifdef PASS_BIOSGEOM
bi_getbiosgeom();
#endif
#ifdef PASS_MEMMAP
bi_getmemmap();
#endif
name = bm->bm_path;
for (name2 = name; *name2; ++name2) {
if (*name2 == ' ' || *name2 == '\t') {
strlcpy(name_buf, name, sizeof(name_buf));
if ((uintptr_t)name2 - (uintptr_t)name < sizeof(name_buf))
name_buf[name2 - name] = '\0';
name = name_buf;
break;
}
}
if ((p = strchr(name, ':')) != NULL) {
/* device specified, use it */
if (p[1] == '/')
snprintf(buf, sizeof(buf), "%s", name);
else {
p++;
extract_device(name, dev_buf, sizeof(dev_buf));
snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod",
dev_buf, base_path, p, p);
}
} else {
/* device not specified; load from kernel device if known */
if (name[0] == '/')
snprintf(buf, sizeof(buf), "%s%s", kdev, name);
else
snprintf(buf, sizeof(buf), "%s%s/%s/%s.kmod",
kdev, base_path, name, name);
}
return buf;
}
static int
module_open(boot_module_t *bm, int mode, const char *kdev,
const char *base_path, bool doload)
{
int fd;
const char *path;
/* check the expanded path first */
path = module_path(bm, kdev, base_path);
fd = open(path, mode);
if (fd != -1) {
if ((howto & AB_SILENT) == 0 && doload)
printf("Loading %s ", path);
} else {
/* now attempt the raw path provided */
fd = open(bm->bm_path, mode);
if (fd != -1 && (howto & AB_SILENT) == 0 && doload)
printf("Loading %s ", bm->bm_path);
}
if (!doload && fd == -1) {
printf("WARNING: couldn't open %s", bm->bm_path);
if (strcmp(bm->bm_path, path) != 0)
printf(" (%s)", path);
printf("\n");
}
return fd;
}
static void
module_base_path(char *buf, size_t bufsize, const char *kernel_path)
{
#ifdef KERNEL_DIR
/* we cheat here, because %.* does not work with the mini printf */
char *ptr = strrchr(kernel_path, '/');
if (ptr) *ptr = '\0';
snprintf(buf, bufsize, "%s/modules", kernel_path);
if (ptr) *ptr = '/';
#else
const char *machine;
#ifndef NO_MULTIBOOT2
printf("%s is not a multiboot kernel\n", file);
#else
printf("%s is not a multiboot 1 kernel "
"(multiboot 2 support is not built in)\n", file);
#endif
goto out;