Added zboot from OpenBSD.

This commit is contained in:
nonaka 2009-03-02 09:33:01 +00:00
parent 3a16d1fa6d
commit af901e6821
29 changed files with 3120 additions and 108 deletions

View File

@ -1,8 +1,83 @@
/* $NetBSD: bootinfo.h,v 1.2 2006/12/17 16:07:11 peter Exp $ */
/* $NetBSD: bootinfo.h,v 1.3 2009/03/02 09:33:01 nonaka Exp $ */
/*-
* Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
* 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.
*/
#ifndef _ZAURUS_BOOTINFO_H_
#define _ZAURUS_BOOTINFO_H_
#define BOOTARGS_BUFSIZ 256
#define BOOTARGS_MAGIC 0x4f425344
#define BOOTINFO_MAXSIZE (BOOTARGS_BUFSIZ - sizeof(uint32_t)) /* uint32_t for magic */
#define BTINFO_BOOTDISK 0
#define BTINFO_HOWTO 1
#define BTINFO_CONSDEV 2
#define BTINFO_MAX 3
#ifndef _LOCORE
struct btinfo_common {
int len;
int type;
};
struct btinfo_bootdisk {
struct btinfo_common common;
int labelsector; /* label valid if != -1 */
struct {
uint16_t type, checksum;
char packname[16];
} label;
int biosdev;
int partition;
};
struct btinfo_howto {
struct btinfo_common common;
u_int howto;
};
struct btinfo_console {
struct btinfo_common common;
char devname[16];
int addr;
int speed;
};
struct bootinfo {
int nentries;
char info[BOOTINFO_MAXSIZE - sizeof(int)];
};
#endif /* _LOCORE */
#ifdef _KERNEL
void *lookup_bootinfo(int type);
#endif
#endif /* _ZAURUS_BOOTINFO_H_ */

View File

@ -0,0 +1,53 @@
/* $NetBSD: loadfile_machdep.h,v 1.1 2009/03/02 09:33:01 nonaka Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* 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.
*/
#define BOOT_ELF32
#define LOAD_KERNEL (LOAD_ALL & ~LOAD_TEXTA)
#define COUNT_KERNEL (COUNT_ALL & ~COUNT_TEXTA)
#define LOADADDR(a) (((u_long)(a)) + offset)
#define ALIGNENTRY(a) ((u_long)(a))
#define READ(f, b, c) read((f), (void *)LOADADDR(b), (c))
#define BCOPY(s, d, c) memcpy((void *)LOADADDR(d), (void *)(s), (c))
#define BZERO(d, c) memset((void *)LOADADDR(d), 0, (c))
#define WARN(a) (void)(printf a, \
printf((errno ? ": %s\n" : "\n"), \
strerror(errno)))
#define PROGRESS(a) (void) printf a
#ifdef _STANDALONE
#define ALLOC(a) alloc(a)
#define DEALLOC(a, b) dealloc(a, b)
#else
#define ALLOC(a) alloc(a)
#define DEALLOC(a, b) free(a, b)
#endif

View File

@ -1,5 +1,5 @@
# $NetBSD: Makefile,v 1.1 2007/08/09 16:08:59 nonaka Exp $
# $NetBSD: Makefile,v 1.2 2009/03/02 09:33:02 nonaka Exp $
SUBDIR= zbsdmod
SUBDIR= zbsdmod zboot
.include <bsd.subdir.mk>

View File

@ -0,0 +1,76 @@
# $NetBSD: Makefile,v 1.1 2009/03/02 09:33:02 nonaka Exp $
PROG= zboot
S= ${.CURDIR}/../../../..
SRCS= crt0.c
SRCS+= boot.c bootinfo.c bootmenu.c conf.c devopen.c diskprobe.c
SRCS+= loadfile_zboot.c
SRCS+= getsecs.c termios.c unixcons.c unixdev.c unixsys.S
NOMAN= # defined
CFLAGS+= -Wall -Wno-main
CFLAGS+= -Wmissing-prototypes -Wstrict-prototypes -Wpointer-arith
CFLAGS+= -fno-stack-protector -fno-builtin -ffreestanding
CPPFLAGS+= -nostdinc -I. -I${.CURDIR} -I${.OBJDIR} -I${S}
CPPFLAGS+= -D_STANDALONE -DHEAP_VARIABLE
AFLAGS+= -D_LOCORE
LDFLAGS+= -nostdlib -Bstatic
CLEANFILES+= vers.c vers.o
LIBCRT0= crt0.o
LIBC= # nothing
LIBCRTBEGIN= # nothing
LIBCRTEND= # nothing
NEWVERSWHAT?= "Boot"
VERSIONFILE?= ${.CURDIR}/version
.if !make(obj) && !make(clean) && !make(cleandir) && !make(release)
.BEGIN: machine arm
.NOPATH: machine arm
machine::
-rm -f $@
ln -s ${S}/arch/${MACHINE}/include $@
arm::
-rm -f $@
ln -s ${S}/arch/arm/include $@
.endif
CLEANFILES+= machine arm
### find out what to use for libkern
KERN_AS= library
.include "${S}/lib/libkern/Makefile.inc"
LIBKERN= ${KERNLIB}
### find out what to use for libz
Z_AS= library
.include "${S}/lib/libz/Makefile.inc"
LIBZ= ${ZLIB}
### find out what to use for libsa
SA_AS= library
SAMISCMAKEFLAGS= SA_USE_CREAD=yes SA_USE_LOADFILE=yes
.include "${S}/lib/libsa/Makefile.inc"
LIBSA= ${SALIB}
${PROG}: ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN}
${HOST_SH} ${S}/conf/newvers_stand.sh ${VERSIONFILE} ${MACHINE} ${NEWVERSWHAT}
${CC} -c vers.c
${LD} ${LDFLAGS} -o ${PROG} ${OBJS} vers.o ${LIBSA} ${LIBZ} ${LIBKERN}
.include <bsd.prog.mk>
cleandir distclean: cleanlibdir
cleanlibdir:
-rm -rf lib
release: check_RELEASEDIR
${HOST_INSTALL_FILE} -m ${BINMODE} ${OBJS} \
${RELEASEDIR}/${MACHINE}/installation

View File

@ -0,0 +1,514 @@
/* $NetBSD: boot.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/*
* Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
* 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 AUTHOR ``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 AUTHOR 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.
*/
#include <sys/types.h>
#include <sys/bootblock.h>
#include <sys/boot_flag.h>
#include "boot.h"
#include "bootinfo.h"
#include "bootmenu.h"
#include "disk.h"
#include "unixdev.h"
#include "pathnames.h"
#include <lib/libsa/loadfile.h>
#include <lib/libsa/ufs.h>
#include "compat_linux.h"
static const char * const names[][2] = {
{ "netbsd", "netbsd.gz" },
{ "netbsd.old", "netbsd.old.gz", },
{ "onetbsd", "onetbsd.gz" },
};
char *default_devname;
uint default_unit, default_partition;
const char *default_filename;
int default_timeout = 5;
static char probed_disks[256];
static void bootcmd_help(char *);
static void bootcmd_ls(char *);
static void bootcmd_quit(char *);
static void bootcmd_boot(char *);
static void bootcmd_disk(char *);
#ifdef SUPPORT_CONSDEV
static void bootcmd_consdev(char *);
#endif
static const struct bootblk_command {
const char *c_name;
void (*c_fn)(char *arg);
} bootcmds[] = {
{ "help", bootcmd_help },
{ "?", bootcmd_help },
{ "quit", bootcmd_quit },
{ "ls", bootcmd_ls },
{ "boot", bootcmd_boot },
{ "disk", bootcmd_disk },
#ifdef SUPPORT_CONSDEV
{ "consdev", bootcmd_consdev },
#endif
{ NULL, NULL },
};
static struct btinfo_howto bi_howto;
static void print_banner(void);
static int exec_netbsd(const char *file, int howto);
int
parsebootfile(const char *fname, char **fsname, char **devname,
uint *unit, uint *partition, const char **file)
{
const char *col;
*fsname = "ufs";
*devname = default_devname;
*unit = default_unit;
*partition = default_partition;
*file = default_filename;
if (fname == NULL)
return 0;
if ((col = strchr(fname, ':'))) { /* device given */
static char savedevname[MAXDEVNAME+1];
int devlen;
unsigned int u = 0, p = 0;
int i = 0;
devlen = col - fname;
if (devlen > MAXDEVNAME)
return EINVAL;
#define isvalidname(c) ((c) >= 'a' && (c) <= 'z')
if (!isvalidname(fname[i]))
return EINVAL;
do {
savedevname[i] = fname[i];
i++;
} while (isvalidname(fname[i]));
savedevname[i] = '\0';
#define isnum(c) ((c) >= '0' && (c) <= '9')
if (i < devlen) {
if (!isnum(fname[i]))
return (EUNIT);
do {
u *= 10;
u += fname[i++] - '0';
} while (isnum(fname[i]));
}
#define isvalidpart(c) ((c) >= 'a' && (c) <= 'a' + MAXPARTITIONS)
if (i < devlen) {
if (!isvalidpart(fname[i]))
return (EPART);
p = fname[i++] - 'a';
}
if (i != devlen)
return ENXIO;
*devname = savedevname;
*unit = u;
*partition = p;
fname = col + 1;
}
if (*fname)
*file = fname;
return 0;
}
char *
sprint_bootsel(const char *filename)
{
static char buf[80];
char *fsname, *devname;
uint unit, partition;
const char *file;
if (parsebootfile(filename, &fsname, &devname, &unit, &partition,
&file) == 0) {
snprintf(buf, sizeof(buf), "%s%d%c:%s", devname, unit,
'a' + partition, file);
return buf;
}
return "(invalid)";
}
static void
print_banner(void)
{
extern const char bootprog_name[];
extern const char bootprog_rev[];
extern const char bootprog_date[];
extern const char bootprog_maker[];
printf("\n");
printf(">> %s, Revision %s\n", bootprog_name, bootprog_rev);
printf(">> (%s, %s)\n", bootprog_maker, bootprog_date);
}
void
boot(dev_t bootdev)
{
extern char twiddle_toggle;
int currname;
int c;
consinit(CONSDEV_GLASS, -1);
twiddle_toggle = 1; /* no twiddling until we're ready */
/* set default value: hd0a:netbsd */
default_devname = "hd";
default_unit = 0;
default_partition = 0;
default_filename = names[0][0];
diskprobe(probed_disks, sizeof(probed_disks));
parsebootconf(_PATH_BOOTCONF);
#ifdef SUPPORT_CONSDEV
/*
* If console set in boot.cfg, switch to it.
* This will print the banner, so we don't need to explicitly do it
*/
if (bootconf.consdev)
bootcmd_consdev(bootconf.consdev);
else
#endif
print_banner();
printf("\ndisks: %s\n", probed_disks);
/* Display the menu, if applicable */
twiddle_toggle = 0;
if (bootconf.nummenu > 0) {
/* Does not return */
doboottypemenu();
}
printf("Press return to boot now, any other key for boot menu\n");
currname = 0;
for (currname = 0; currname < __arraycount(names); currname++) {
printf("booting %s - starting in ",
sprint_bootsel(names[currname][0]));
c = awaitkey((bootconf.timeout < 0) ? 0 : bootconf.timeout, 1);
if ((c != '\r') && (c != '\n') && (c != '\0')) {
printf("type \"?\" or \"help\" for help.\n");
bootmenu(); /* does not return */
}
/*
* try pairs of names[] entries, foo and foo.gz
*/
/* don't print "booting..." again */
bootit(names[currname][0], 0, 0);
/* since it failed, try compressed bootfile. */
bootit(names[currname][1], 0, 1);
}
bootmenu(); /* does not return */
}
void
bootit(const char *filename, int howto, int tell)
{
if (tell) {
printf("booting %s", sprint_bootsel(filename));
if (howto)
printf(" (howto 0x%x)", howto);
printf("\n");
}
if (exec_netbsd(filename, howto) < 0) {
printf("boot: %s: %s\n", sprint_bootsel(filename),
strerror(errno));
} else {
printf("boot returned\n");
}
}
static int
exec_netbsd(const char *file, int howto)
{
u_long marks[MARK_MAX];
BI_ALLOC(BTINFO_MAX);
bi_howto.howto = howto;
BI_ADD(&bi_howto, BTINFO_HOWTO, sizeof(bi_howto));
if (loadfile_zboot(file, marks, LOAD_KERNEL) == -1)
goto out;
/*NOTREACHED*/
return 0;
out:
BI_FREE();
bootinfo = 0;
return -1;
}
/*
* bootmenu
*/
static char *gettrailer(char *arg);
static int parseopts(const char *opts, int *howto);
static int parseboot(char *arg, char **filename, int *howto);
/* ARGSUSED */
static void
bootcmd_help(char *arg)
{
printf("commands are:\n"
"boot [xdNx:][filename] [-acdqsv]\n"
" (ex. \"hd0a:netbsd.old -s\"\n"
"ls [path]\n"
#ifdef SUPPORT_CONSDEV
"consdev {glass|com [speed]}\n"
#endif
"disk\n"
"help|?\n"
"quit\n");
}
/* ARGSUSED */
static void
bootcmd_quit(char *arg)
{
printf("Exiting...\n");
exit(0);
/*NOTREACHED*/
}
static void
bootcmd_ls(char *arg)
{
const char *save = default_filename;
default_filename = "/";
ufs_ls(arg);
default_filename = save;
}
static void
bootcmd_boot(char *arg)
{
char *filename;
int howto;
if (parseboot(arg, &filename, &howto)) {
bootit(filename, howto, 1);
}
}
/* ARGSUSED */
static void
bootcmd_disk(char *arg)
{
printf("disks: %s\n", probed_disks);
}
#ifdef SUPPORT_CONSDEV
static const struct cons_devs {
const char *name;
int tag;
} cons_devs[] = {
{ "glass", CONSDEV_GLASS },
{ "com", CONSDEV_COM0 },
{ "com0", CONSDEV_COM0 },
{ NULL, 0 }
};
static void
bootcmd_consdev(char *arg)
{
const struct cons_devs *cdp;
char *p;
int speed = 9600;
p = strchr(arg, ' ');
if (p != NULL) {
*p++ = '\0';
speed = atoi(p);
}
for (cdp = cons_devs; cdp->name != NULL; cdp++) {
if (strcmp(arg, cdp->name) == 0) {
consinit(cdp->tag, speed);
print_banner();
return;
}
}
printf("invalid console device.\n");
}
#endif
void
docommand(char *arg)
{
char *options;
int i;
options = gettrailer(arg);
for (i = 0; bootcmds[i].c_name != NULL; i++) {
if (strcmp(arg, bootcmds[i].c_name) == 0) {
(*bootcmds[i].c_fn)(options);
return;
}
}
printf("unknown command\n");
bootcmd_help(NULL);
}
void
bootmenu(void)
{
char input[256];
char *c;
for (;;) {
c = input;
input[0] = '\0';
printf("> ");
gets(input);
/*
* Skip leading whitespace.
*/
while (*c == ' ') {
c++;
}
if (*c != '\0') {
docommand(c);
}
}
}
/*
* chops the head from the arguments and returns the arguments if any,
* or possibly an empty string.
*/
static char *
gettrailer(char *arg)
{
char *options;
if ((options = strchr(arg, ' ')) == NULL)
return ("");
else
*options++ = '\0';
/* trim leading blanks */
while (*options && *options == ' ')
options++;
return options;
}
static int
parseopts(const char *opts, int *howto)
{
int r, tmpopt = 0;
opts++; /* skip - */
while (*opts && *opts != ' ') {
r = 0;
BOOT_FLAG(*opts, r);
if (r == 0) {
printf("-%c: unknown flag\n", *opts);
bootcmd_help(NULL);
return 0;
}
tmpopt |= r;
opts++;
}
*howto = tmpopt;
return 1;
}
static int
parseboot(char *arg, char **filename, int *howto)
{
char *opts = NULL;
*filename = 0;
*howto = 0;
/* if there were no arguments */
if (arg == NULL || *arg == '\0')
return 1;
/* format is... */
/* [[xxNx:]filename] [-adqsv] */
/* check for just args */
if (arg[0] == '-') {
opts = arg;
} else {
/* there's a file name */
*filename = arg;
opts = gettrailer(arg);
if (opts == NULL || *opts == '\0') {
opts = NULL;
} else if (*opts != '-') {
printf("invalid arguments\n");
bootcmd_help(NULL);
return 0;
}
}
/* at this point, we have dealt with filenames. */
/* now, deal with options */
if (opts) {
if (parseopts(opts, howto) == 0) {
return 0;
}
}
return 1;
}

View File

@ -0,0 +1,59 @@
/* $NetBSD: boot.h,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/*
* Copyright (c) 2009 NONAKA Kimihiro
* 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 AUTHOR ``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 AUTHOR 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.
*/
#ifndef _STAND_BOOT_H_
#define _STAND_BOOT_H_
#include <sys/param.h>
#include <lib/libsa/stand.h>
#include <lib/libkern/libkern.h>
extern int debug;
/* boot.c */
char *default_devname;
uint default_unit, default_partition;
const char *default_filename;
extern int default_timeout;
void boot(dev_t);
int parsebootfile(const char *fname, char **fsname, char **devname,
uint *unit, uint *partition, const char **file);
char *sprint_bootsel(const char *filename);
void bootit(const char *filename, int howto, int tell);
void docommand(char *arg);
void bootmenu(void);
/* conf.c */
extern char devname_hd[];
extern char devname_mmcd[];
/* loadfile_zboot.c */
int loadfile_zboot(const char *fname, u_long *marks, int flags);
#endif /* _STAND_BOOT_H_ */

View File

@ -0,0 +1,81 @@
/* $NetBSD: bootinfo.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/*
* Copyright (c) 1997
* Matthias Drochner. 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 AUTHOR ``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 AUTHOR 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.
*
*/
#include "boot.h"
#include "bootinfo.h"
struct btinfo *bootinfo;
static int
bi_find(int type)
{
struct btinfo_common *btinfo;
int i;
for (i = 0; i < bootinfo->nentries; i++) {
btinfo = (struct btinfo_common *)(bootinfo->entry[i]);
if (btinfo->type == type) {
return i;
}
}
return -1;
}
void
bi_add(struct btinfo_common *what, int type, int size)
{
int idx;
what->len = size;
what->type = type;
if (bootinfo) {
idx = bi_find(type);
if (idx < 0) {
idx = bootinfo->nentries++;
}
bootinfo->entry[idx] = (u_long)what;
}
}
void
bi_del(int type)
{
int idx;
int i;
if (bootinfo) {
idx = bi_find(type);
if (idx >= 0) {
for (i = idx + 1; i < bootinfo->nentries; i++) {
bootinfo->entry[i - 1] = bootinfo->entry[i];
}
bootinfo->entry[--bootinfo->nentries] = 0L;
}
}
}

View File

@ -0,0 +1,53 @@
/* $NetBSD: bootinfo.h,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/*
* Copyright (c) 1997
* Matthias Drochner. 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 AUTHOR ``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 AUTHOR 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.
*
*/
#ifndef _STAND_BOOTINFO_H_
#define _STAND_BOOTINFO_H_
#include <machine/bootinfo.h>
struct btinfo {
int nentries;
u_long entry[1];
};
extern struct btinfo *bootinfo;
#define BI_ALLOC(max) (bootinfo = ALLOC(sizeof(struct btinfo) \
+ ((max) - 1) * sizeof(u_long))) \
->nentries = 0
#define BI_FREE() DEALLOC(bootinfo, 0)
#define BI_ADD(x, type, size) bi_add((struct btinfo_common *)(x), type, size)
#define BI_DEL(type) bi_del(type)
void bi_add(struct btinfo_common *, int, int);
void bi_del(int);
#endif /* _STAND_BOOTINFO_H_ */

View File

@ -0,0 +1,337 @@
/* $NetBSD: bootmenu.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/*-
* Copyright (c) 2008 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.
*/
#include <sys/types.h>
#include <sys/reboot.h>
#include <sys/bootblock.h>
#include "boot.h"
#include "unixdev.h"
#include "bootmenu.h"
#include "pathnames.h"
#define isnum(c) ((c) >= '0' && (c) <= '9')
#define MENUFORMAT_AUTO 0
#define MENUFORMAT_NUMBER 1
#define MENUFORMAT_LETTER 2
struct bootconf_def bootconf;
int
atoi(const char *in)
{
char *c;
int ret;
ret = 0;
c = (char *)in;
if (*c == '-')
c++;
for (; isnum(*c); c++)
ret = (ret * 10) + (*c - '0');
return (*in == '-') ? -ret : ret;
}
/*
* This function parses a boot.cfg file in the root of the filesystem
* (if present) and populates the global boot configuration.
*
* The file consists of a number of lines each terminated by \n
* The lines are in the format keyword=value. There should not be spaces
* around the = sign.
*
* The recognised keywords are:
* banner: text displayed instead of the normal welcome text
* menu: Descriptive text:command to use
* timeout: Timeout in seconds (overrides that set by installboot)
* default: the default menu option to use if Return is pressed
* consdev: the console device to use
* format: how menu choices are displayed: (a)utomatic, (n)umbers or (l)etters
* clear: whether to clear the screen or not
*
* Example boot.cfg file:
* banner=Welcome to NetBSD
* banner=Please choose the boot type from the following menu
* menu=Boot NetBSD:boot netbsd
* menu=Boot into single user mode:boot netbsd -s
* menu=:boot hd1a:netbsd -cs
* menu=Goto boot comand line:prompt
* timeout=10
* consdev=com0
* default=1
*/
void
parsebootconf(const char *conf)
{
char *bc, *c;
int cmenu, cbanner, len;
int fd, err, off;
struct stat st;
char *key, *value, *v2;
/* Clear bootconf structure */
memset(&bootconf, 0, sizeof(bootconf));
/* Set timeout to configured */
bootconf.timeout = default_timeout;
/* automatically switch between letter and numbers on menu */
bootconf.menuformat = MENUFORMAT_AUTO;
fd = open(_PATH_BOOTCONF, 0);
if (fd < 0)
return;
err = fstat(fd, &st);
if (err == -1) {
close(fd);
return;
}
bc = alloc(st.st_size + 1);
if (bc == NULL) {
printf("Could not allocate memory for boot configuration\n");
return;
}
off = 0;
do {
len = read(fd, bc + off, 1024);
if (len <= 0)
break;
off += len;
} while (len > 0);
bc[off] = '\0';
close(fd);
/* bc now contains the whole boot.cfg file */
cmenu = 0;
cbanner = 0;
for (c = bc; *c; c++) {
key = c;
/* Look for = separator between key and value */
for (; *c && *c != '='; c++)
continue;
if (*c == '\0')
break; /* break if at end of data */
/* zero terminate key which points to keyword */
*c++ = 0;
value = c;
/* Look for end of line (or file) and zero terminate value */
for (; *c && *c != '\n'; c++)
continue;
*c = 0;
if (!strncmp(key, "menu", 4)) {
/*
* Parse "menu=<description>:<command>". If the
* description is empty ("menu=:<command>)",
* then re-use the command as the description.
* Note that the command may contain embedded
* colons.
*/
if (cmenu >= MAXMENU)
continue;
bootconf.desc[cmenu] = value;
for (v2 = value; *v2 && *v2 != ':'; v2++)
continue;
if (*v2) {
*v2++ = 0;
bootconf.command[cmenu] = v2;
if (! *value)
bootconf.desc[cmenu] = v2;
cmenu++;
} else {
/* No delimiter means invalid line */
bootconf.desc[cmenu] = NULL;
}
} else if (!strncmp(key, "banner", 6)) {
if (cbanner < MAXBANNER)
bootconf.banner[cbanner++] = value;
} else if (!strncmp(key, "timeout", 7)) {
if (!isnum(*value))
bootconf.timeout = -1;
else
bootconf.timeout = atoi(value);
} else if (!strncmp(key, "default", 7)) {
bootconf.def = atoi(value) - 1;
} else if (!strncmp(key, "consdev", 7)) {
bootconf.consdev = value;
} else if (!strncmp(key, "format", 6)) {
printf("value:%c\n", *value);
switch (*value) {
case 'a':
case 'A':
bootconf.menuformat = MENUFORMAT_AUTO;
break;
case 'n':
case 'N':
case 'd':
case 'D':
bootconf.menuformat = MENUFORMAT_NUMBER;
break;
case 'l':
case 'L':
bootconf.menuformat = MENUFORMAT_LETTER;
break;
}
} else if (!strncmp(key, "clear", 5)) {
bootconf.clear = !!atoi(value);
}
}
switch (bootconf.menuformat) {
case MENUFORMAT_AUTO:
if (cmenu > 9 && bootconf.timeout > 0)
bootconf.menuformat = MENUFORMAT_LETTER;
else
bootconf.menuformat = MENUFORMAT_NUMBER;
break;
case MENUFORMAT_NUMBER:
if (cmenu > 9 && bootconf.timeout > 0)
cmenu = 9;
break;
}
bootconf.nummenu = cmenu;
if (bootconf.def < 0)
bootconf.def = 0;
if (bootconf.def >= cmenu)
bootconf.def = cmenu - 1;
}
/*
* doboottypemenu will render the menu and parse any user input
*/
static int
getchoicefrominput(char *input, int def)
{
int choice = -1;
if (*input == '\0' || *input == '\r' || *input == '\n')
choice = def;
else if (*input >= 'A' && *input < bootconf.nummenu + 'A')
choice = (*input) - 'A';
else if (*input >= 'a' && *input < bootconf.nummenu + 'a')
choice = (*input) - 'a';
else if (isnum(*input)) {
choice = atoi(input) - 1;
if (choice < 0 || choice >= bootconf.nummenu)
choice = -1;
}
return choice;
}
void
doboottypemenu(void)
{
char input[80], *ic, *oc;
int choice;
printf("\n");
/* Display menu */
if (bootconf.menuformat == MENUFORMAT_LETTER) {
for (choice = 0; choice < bootconf.nummenu; choice++)
printf(" %c. %s\n", choice + 'A',
bootconf.desc[choice]);
} else {
/* Can't use %2d format string with libsa */
for (choice = 0; choice < bootconf.nummenu; choice++)
printf(" %s%d. %s\n",
(choice < 9) ? " " : "",
choice + 1,
bootconf.desc[choice]);
}
choice = -1;
for (;;) {
input[0] = '\0';
if (bootconf.timeout < 0) {
if (bootconf.menuformat == MENUFORMAT_LETTER)
printf("\nOption: [%c]:",
bootconf.def + 'A');
else
printf("\nOption: [%d]:",
bootconf.def + 1);
gets(input);
choice = getchoicefrominput(input, bootconf.def);
} else if (bootconf.timeout == 0)
choice = bootconf.def;
else {
printf("\nChoose an option; RETURN for default; "
"SPACE to stop countdown.\n");
if (bootconf.menuformat == MENUFORMAT_LETTER)
printf("Option %c will be chosen in ",
bootconf.def + 'A');
else
printf("Option %d will be chosen in ",
bootconf.def + 1);
input[0] = awaitkey(bootconf.timeout, 1);
input[1] = '\0';
choice = getchoicefrominput(input, bootconf.def);
/* If invalid key pressed, drop to menu */
if (choice == -1)
bootconf.timeout = -1;
}
if (choice < 0)
continue;
if (!strcmp(bootconf.command[choice], "prompt")) {
printf("type \"?\" or \"help\" for help.\n");
bootmenu(); /* does not return */
} else {
ic = bootconf.command[choice];
/* Split command string at ; into separate commands */
do {
oc = input;
/* Look for ; separator */
for (; *ic && *ic != COMMAND_SEPARATOR; ic++)
*oc++ = *ic;
if (*input == '\0')
continue;
/* Strip out any trailing spaces */
oc--;
for (; *oc == ' ' && oc > input; oc--);
*++oc = '\0';
if (*ic == COMMAND_SEPARATOR)
ic++;
/* Stop silly command strings like ;;; */
if (*input != '\0')
docommand(input);
/* Skip leading spaces */
for (; *ic == ' '; ic++);
} while (*ic);
}
}
}

View File

@ -0,0 +1,52 @@
/* $NetBSD: bootmenu.h,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/*-
* Copyright (c) 2008 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.
*/
#ifndef _BOOTMENU_H
#define _BOOTMENU_H
#define MAXMENU 20
#define MAXBANNER 12
#define COMMAND_SEPARATOR ';'
void parsebootconf(const char *);
void doboottypemenu(void);
int atoi(const char *);
struct bootconf_def {
char *banner[MAXBANNER]; /* Banner text */
char *command[MAXMENU]; /* Menu commands per entry*/
char *consdev; /* Console device */
int def; /* Default menu option */
char *desc[MAXMENU]; /* Menu text per entry */
int nummenu; /* Number of menu items */
int timeout; /* Timeout in seconds */
int menuformat; /* Print letters instead of numbers? */
int clear; /* Clear the screen? */
} extern bootconf;
#endif /* !_BOOTMENU_H */

View File

@ -0,0 +1,66 @@
/* $NetBSD: compat_linux.h,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/* $OpenBSD: compat_linux.h,v 1.8 2007/06/16 00:26:33 deraadt Exp $ */
/*
* Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* This file must be included late, for redefinitions to take effect. */
#ifndef _LOCORE
#include <sys/param.h>
#include <sys/termios.h>
#include <sys/fd_set.h>
struct lwp;
struct vnode;
#include <compat/linux/common/linux_types.h>
#include <compat/linux/common/linux_fcntl.h>
#include <compat/linux/common/linux_util.h>
#include <compat/linux/common/linux_ioctl.h>
#include <compat/linux/common/linux_errno.h>
#define INT_LIMIT(x) (~((x)1 << (sizeof(x) * 8 - 1)))
#define OFFSET_MAX INT_LIMIT(long long)
#define OFFT_OFFSET_MAX INT_LIMIT(long)
#undef SEEK_SET
#undef SEEK_CUR
#define SEEK_SET 0
#define SEEK_CUR 1
#define LINUX_EOVERFLOW 75
#endif /* !_LOCORE */
#include <compat/linux/linux_syscall.h>
/* linux/asm/unistd.h */
#define __NR_SYSCALL_BASE 0x900000
#define __NR_exit (__NR_SYSCALL_BASE + LINUX_SYS_exit)
#define __NR_read (__NR_SYSCALL_BASE + LINUX_SYS_read)
#define __NR_write (__NR_SYSCALL_BASE + LINUX_SYS_write)
#define __NR_open (__NR_SYSCALL_BASE + LINUX_SYS_open)
#define __NR_close (__NR_SYSCALL_BASE + LINUX_SYS_close)
#define __NR_time (__NR_SYSCALL_BASE + LINUX_SYS_time)
#define __NR_lseek32 (__NR_SYSCALL_BASE + LINUX_SYS_lseek)
#define __NR_ioctl (__NR_SYSCALL_BASE + LINUX_SYS_ioctl)
#define __NR_select (__NR_SYSCALL_BASE + LINUX_SYS_select)
#define __NR_stat (__NR_SYSCALL_BASE + LINUX_SYS_stat)
#define __NR_syscall (__NR_SYSCALL_BASE + 113)
#undef SYS_select
#define SYS_select __NR_select

View File

@ -0,0 +1,49 @@
/* $NetBSD: conf.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/*
* Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
* 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 AUTHOR ``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 AUTHOR 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.
*/
#include "boot.h"
#include "unixdev.h"
#include <lib/libsa/ufs.h>
#include <lib/libsa/ext2fs.h>
char devname_hd[] = "hd";
char devname_mmcd[] = "mmcd";
struct devsw devsw[] = {
{ devname_hd, unixstrategy, unixopen, unixclose, unixioctl},
{ devname_mmcd, unixstrategy, unixopen, unixclose, unixioctl},
};
int ndevs = __arraycount(devsw);
struct fs_ops file_system[] = {
FS_OPS(ufs),
FS_OPS(ffsv1),
FS_OPS(ffsv2),
FS_OPS(ext2fs),
};
int nfsys = __arraycount(file_system);

View File

@ -0,0 +1,56 @@
/* $NetBSD: crt0.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/*
* Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
* 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 AUTHOR ``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 AUTHOR 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.
*/
#include "boot.h"
#include "unixdev.h"
#define HEAP_SIZE (4 * 1024 * 1024) /* heap: 4MB */
char heap_area[HEAP_SIZE];
int debug = 1;
void _start(void);
void
_start(void)
{
setheap(heap_area, heap_area + HEAP_SIZE);
boot(0);
uexit(0);
/*NOTREACHED*/
}
void
_rtt(void)
{
uexit(1);
/*NOTREACHED*/
}

View File

@ -0,0 +1,137 @@
/* $NetBSD: devopen.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/*-
* Copyright (c) 1993 John Brezak
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR `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 AUTHOR 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.
*/
#include <sys/param.h>
#include <sys/disklabel.h>
#include "boot.h"
#include "bootinfo.h"
#include "disk.h"
#include "unixdev.h"
static int dev2bios(char *devname, unsigned int unit, int *biosdev);
static int devlookup(char *d);
static int
dev2bios(char *devname, unsigned int unit, int *biosdev)
{
if (strcmp(devname, devname_hd) == 0) {
*biosdev = 0x80 + unit;
return 0;
} else if (strcmp(devname, devname_mmcd) == 0) {
*biosdev = 0x00 + unit;
return 0;
}
return ENXIO;
}
static int
devlookup(char *d)
{
struct devsw *dp = devsw;
int i;
for (i = 0; i < ndevs; i++, dp++) {
if ((dp->dv_name != NULL) && (strcmp(dp->dv_name, d) == 0)) {
return i;
}
}
printf("No such device - Configured devices are:\n");
for (dp = devsw, i = 0; i < ndevs; i++, dp++) {
if (dp->dv_name != NULL) {
printf(" %s", dp->dv_name);
}
}
printf("\n");
return -1;
}
int
devopen(struct open_file *f, const char *fname, char **file)
{
struct devsw *dp;
char *fsname, *devname;
unsigned int dev, ctlr, unit, partition;
int biosdev;
int error;
#if defined(UNIX_DEBUG)
printf("devopen: fname = %s\n", fname ? fname : "(null)");
#endif
ctlr = 0;
if ((error = parsebootfile(fname, &fsname, &devname, &unit, &partition,
(const char **)file)) != 0) {
return error;
}
#if defined(UNIX_DEBUG)
printf("devopen: devname = %s\n", devname);
#endif
dev = devlookup(devname);
if (dev == -1) {
#if defined(UNIX_DEBUG)
printf("devopen: devlookup failed\n");
#endif
return ENXIO;
}
dp = &devsw[dev];
if (dp->dv_open == NULL) {
#if defined(UNIX_DEBUG)
printf("devopen: dev->dv_open() == NULL\n");
#endif
return ENODEV;
}
f->f_dev = dp;
if (dev2bios(devname, unit, &biosdev) == 0) {
#if defined(UNIX_DEBUG)
printf("devopen: bios disk\n");
#endif
return (unixopen(f, biosdev, devname, unit, partition, *file));
}
#if defined(UNIX_DEBUG)
printf("devopen: dev->dv_open()\n");
#endif
if ((error = (*dp->dv_open)(f, ctlr, unit, partition)) == 0) {
#if defined(UNIX_DEBUG)
printf("devopen: dev->dv_open() opened\n");
#endif
return 0;
}
printf("%s%d%c:%s : %s\n", dp->dv_name, unit, partition + 'a', *file,
strerror(error));
return error;
}

View File

@ -0,0 +1,86 @@
/* $NetBSD: disk.h,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/* $OpenBSD: disk.h,v 1.1 2005/05/24 20:38:20 uwe Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
* 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 AUTHOR ``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.
*
*/
#ifndef _STAND_DISK_H
#define _STAND_DISK_H
#include <sys/disklabel.h>
#include <sys/queue.h>
#define MAXDEVNAME 16
/* XXX snatched from <i386/biosdev.h> */
#if 1
/* Info about disk from the bios, plus the mapping from
* BIOS numbers to BSD major (driver?) number.
*
* Also, do not bother with BIOSN*() macros, just parcel
* the info out, and use it like this. This makes for less
* of a dependance on BIOSN*() macros having to be the same
* across /boot, /bsd, and userland.
*/
#define BOOTARG_DISKINFO 1
typedef struct _bios_diskinfo {
/* BIOS section */
int bios_number; /* BIOS number of drive (or -1) */
/* Misc. flags */
uint32_t flags;
#define BDI_INVALID 0x00000001 /* I/O error during checksumming */
#define BDI_GOODLABEL 0x00000002 /* Had SCSI or ST506/ESDI disklabel */
#define BDI_BADLABEL 0x00000004 /* Had another disklabel */
#define BDI_EL_TORITO 0x00000008 /* 2,048-byte sectors */
#define BDI_PICKED 0x80000000 /* kernel-only: cksum matched */
} bios_diskinfo_t;
#define BOOTARG_CKSUMLEN 3 /* uint32_t */
#endif /* 1 */
/* All the info on a disk we've found */
struct diskinfo {
bios_diskinfo_t bios_info;
struct disklabel disklabel;
char devname[MAXDEVNAME];
TAILQ_ENTRY(diskinfo) list;
};
TAILQ_HEAD(disklist_lh, diskinfo);
/* diskprobe.c */
void diskprobe(char *buf, size_t bufsiz);
struct diskinfo *dkdevice(const char *, uint);
int bios_devname(int, char *, int);
void bios_devpath(int, int, char *);
char *bios_getdiskinfo(int, bios_diskinfo_t *);
int bios_getdospart(bios_diskinfo_t *);
char *bios_getdisklabel(bios_diskinfo_t *, struct disklabel *);
void dump_diskinfo(void);
#endif /* _STAND_DISK_H */

View File

@ -0,0 +1,309 @@
/* $NetBSD: diskprobe.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/* $OpenBSD: diskprobe.c,v 1.3 2006/10/13 00:00:55 krw Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
* 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 AUTHOR ``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.
*
*/
/* We want the disk type names from disklabel.h */
#undef DKTYPENAMES
#include <sys/param.h>
#include <sys/bootblock.h>
#include <sys/disklabel.h>
#include <sys/queue.h>
#include <sys/reboot.h>
#include "boot.h"
#include "disk.h"
#include "unixdev.h"
#include "compat_linux.h"
/* Disk spin-up wait timeout. */
static u_int timeout = 10;
/* Local Prototypes */
static void hardprobe(char *buf, size_t bufsiz);
/* List of disk devices we found/probed */
struct disklist_lh disklist;
static char disk_devname[MAXDEVNAME];
/*
* Probe for all hard disks.
*/
static void
hardprobe(char *buf, size_t bufsiz)
{
/* XXX probe disks in this order */
static const int order[] = { 0x80, 0x82, 0x00 };
char devname[MAXDEVNAME];
struct diskinfo *dip;
u_int disk = 0;
u_int hd_disk = 0;
u_int mmcd_disk = 0;
uint unit = 0;
int first = 1;
int i;
buf[0] = '\0';
/* Hard disks */
for (i = 0; i < __arraycount(order); i++) {
dip = alloc(sizeof(struct diskinfo));
memset(dip, 0, sizeof(*dip));
if (bios_getdiskinfo(order[i], &dip->bios_info) != NULL) {
dealloc(dip, 0);
continue;
}
bios_devname(order[i], devname, sizeof(devname));
if (order[i] & 0x80) {
unit = hd_disk;
snprintf(dip->devname, sizeof(dip->devname), "%s%d",
devname, hd_disk++);
} else {
unit = mmcd_disk;
snprintf(dip->devname, sizeof(dip->devname), "%s%d",
devname, mmcd_disk++);
}
strlcat(buf, dip->devname, bufsiz);
disk++;
/* Try to find the label, to figure out device type. */
if (bios_getdisklabel(&dip->bios_info, &dip->disklabel)
== NULL) {
strlcat(buf, "*", bufsiz);
if (first) {
first = 0;
strlcpy(disk_devname, devname,
sizeof(disk_devname));
default_devname = disk_devname;
default_unit = unit;
}
} else {
/* Best guess */
switch (dip->disklabel.d_type) {
case DTYPE_SCSI:
case DTYPE_ESDI:
case DTYPE_ST506:
dip->bios_info.flags |= BDI_GOODLABEL;
break;
default:
dip->bios_info.flags |= BDI_BADLABEL;
}
}
/* Add to queue of disks. */
TAILQ_INSERT_TAIL(&disklist, dip, list);
strlcat(buf, " ", bufsiz);
}
if (disk == 0)
strlcat(buf, "none...", bufsiz);
}
/* Probe for all BIOS supported disks */
void
diskprobe(char *buf, size_t bufsiz)
{
/* Init stuff */
TAILQ_INIT(&disklist);
/* Do probes */
hardprobe(buf, bufsiz);
}
/*
* Find info on the disk given by major + unit number.
*/
struct diskinfo *
dkdevice(const char *devname, uint unit)
{
char name[MAXDEVNAME];
struct diskinfo *dip;
snprintf(name, sizeof(name), "%s%d", devname, unit);
for (dip = TAILQ_FIRST(&disklist); dip != NULL;
dip = TAILQ_NEXT(dip, list)) {
if (strcmp(name, dip->devname) == 0) {
return dip;
}
}
return NULL;
}
int
bios_devname(int biosdev, char *devname, int size)
{
if ((biosdev & 0x80) != 0) {
strlcpy(devname, devname_hd, size);
} else {
strlcpy(devname, devname_mmcd, size);
}
return 0;
}
/*
* Find the Linux device path that corresponds to the given "BIOS" disk,
* where 0x80 corresponds to /dev/hda, 0x81 to /dev/hdb, and so on.
*/
void
bios_devpath(int dev, int part, char *p)
{
char devname[MAXDEVNAME];
const char *q;
*p++ = '/';
*p++ = 'd';
*p++ = 'e';
*p++ = 'v';
*p++ = '/';
bios_devname(dev, devname, sizeof(devname));
q = devname;
while (*q != '\0')
*p++ = *q++;
*p++ = 'a' + (dev & 0x7f);
if (part >= 0)
*p++ = '1' + part;
*p = '\0';
}
/*
* Fill out a bios_diskinfo_t for this device.
*/
char *
bios_getdiskinfo(int dev, bios_diskinfo_t *bdi)
{
static char path[PATH_MAX];
struct linux_stat sb;
memset(bdi, 0, sizeof *bdi);
bdi->bios_number = -1;
bios_devpath(dev, -1, path);
if (ustat(path, &sb) != 0)
return "no device node";
bdi->bios_number = dev;
if (bios_getdospart(bdi) < 0)
return "no NetBSD partition";
return NULL;
}
int
bios_getdospart(bios_diskinfo_t *bdi)
{
char path[PATH_MAX];
char buf[DEV_BSIZE];
struct mbr_partition *mp;
int fd;
u_int part;
size_t rsize;
bios_devpath(bdi->bios_number, -1, path);
/*
* Give disk devices some time to become ready when the first open
* fails. Even when open succeeds the disk is sometimes not ready.
*/
if ((fd = uopen(path, LINUX_O_RDONLY)) == -1 && errno == ENXIO) {
while (fd == -1 && timeout > 0) {
timeout--;
sleep(1);
fd = uopen(path, LINUX_O_RDONLY);
}
if (fd != -1)
sleep(2);
}
if (fd == -1)
return -1;
/* Read the disk's MBR. */
if (unixstrategy((void *)fd, F_READ, MBR_BBSECTOR, DEV_BSIZE, buf,
&rsize) != 0 || rsize != DEV_BSIZE) {
uclose(fd);
errno = EIO;
return -1;
}
/* Find NetBSD primary partition in the disk's MBR. */
mp = (struct mbr_partition *)&buf[MBR_PART_OFFSET];
for (part = 0; part < MBR_PART_COUNT; part++) {
if (mp[part].mbrp_type == MBR_PTYPE_NETBSD)
break;
}
if (part == MBR_PART_COUNT) {
uclose(fd);
errno = ERDLAB;
return -1;
}
uclose(fd);
return part;
}
char *
bios_getdisklabel(bios_diskinfo_t *bdi, struct disklabel *label)
{
char path[PATH_MAX];
char buf[DEV_BSIZE];
int part;
int fd;
size_t rsize;
part = bios_getdospart(bdi);
if (part < 0)
return "no NetBSD partition";
bios_devpath(bdi->bios_number, part, path);
/* Test if the NetBSD partition has a valid disklabel. */
if ((fd = uopen(path, LINUX_O_RDONLY)) != -1) {
char *msg = "failed to read disklabel";
if (unixstrategy((void *)fd, F_READ, LABELSECTOR,
DEV_BSIZE, buf, &rsize) == 0 && rsize == DEV_BSIZE)
msg = getdisklabel(buf, label);
uclose(fd);
/* Don't wait for other disks if this label is ok. */
if (msg == NULL)
timeout = 0;
return msg;
}
return "failed to open partition";
}

View File

@ -0,0 +1,53 @@
/* $NetBSD: getsecs.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/*
* Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
* 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 AUTHOR ``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 AUTHOR 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.
*/
#include "boot.h"
#include "unixdev.h"
#include <lib/libsa/net.h>
#include "compat_linux.h"
satime_t
getsecs(void)
{
return (satime_t)syscall(__NR_time, NULL);
}
int
sleep(int seconds)
{
int start;
start = getsecs();
while (getsecs() - start < seconds)
continue;
return 0;
}

View File

@ -0,0 +1,176 @@
/* $NetBSD: loadfile_zboot.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/*
* Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
* 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 AUTHOR ``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 AUTHOR 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.
*/
#include <sys/types.h>
#include <sys/bootblock.h>
#include "boot.h"
#include "bootinfo.h"
#include "disk.h"
#include "unixdev.h"
#include "pathnames.h"
#include <lib/libsa/loadfile.h>
#include "compat_linux.h"
static int fdloadfile_zboot(int fd, u_long *marks, int flags);
static int zboot_exec(int fd, u_long *marks, int flags);
int
loadfile_zboot(const char *fname, u_long *marks, int flags)
{
int fd, error;
/* Open the file. */
if ((fd = open(fname, 0)) < 0) {
WARN(("open %s", fname ? fname : "<default>"));
return -1;
}
/* Load it; save the value of errno across the close() call */
if ((error = fdloadfile_zboot(fd, marks, flags)) != 0) {
(void)close(fd);
errno = error;
return -1;
}
return fd;
}
static int
fdloadfile_zboot(int fd, u_long *marks, int flags)
{
Elf32_Ehdr elf32;
ssize_t nr;
int rval;
/* Read the exec header. */
if (lseek(fd, 0, SEEK_SET) == (off_t)-1)
goto err;
nr = read(fd, &elf32, sizeof(elf32));
if (nr == -1) {
WARN(("read header failed"));
goto err;
}
if (nr != sizeof(elf32)) {
WARN(("read header short"));
errno = EFTYPE;
goto err;
}
if (memcmp(elf32.e_ident, ELFMAG, SELFMAG) == 0 &&
elf32.e_ident[EI_CLASS] == ELFCLASS32) {
rval = zboot_exec(fd, marks, flags);
} else {
rval = 1;
errno = EFTYPE;
}
if (rval == 0)
return 0;
err:
return errno;
}
static int
zboot_exec(int fd, u_long *marks, int flags)
{
static char bibuf[BOOTINFO_MAXSIZE];
char buf[512];
struct btinfo_common *help;
char *p;
int tofd;
int sz;
int i;
/*
* set bootargs
*/
p = bibuf;
memcpy(p, &bootinfo->nentries, sizeof(bootinfo->nentries));
p += sizeof(bootinfo->nentries);
for (i = 0; i < bootinfo->nentries; i++) {
help = (struct btinfo_common *)(bootinfo->entry[i]);
if ((p - bibuf) + help->len > BOOTINFO_MAXSIZE)
break;
memcpy(p, help, help->len);
p += help->len;
}
tofd = uopen(_PATH_ZBOOT, LINUX_O_WRONLY);
if (tofd == -1) {
printf("%s: can't open (errno %d)\n", _PATH_ZBOOT, errno);
return 1;
}
if (uwrite(tofd, bibuf, p - bibuf) != p - bibuf)
printf("setbootargs: argument write error\n");
/* Commit boot arguments. */
uclose(tofd);
/*
* load kernel
*/
tofd = uopen(_PATH_ZBOOT, LINUX_O_WRONLY);
if (tofd == -1) {
printf("%s: can't open (errno %d)\n", _PATH_ZBOOT, errno);
return 1;
}
if (lseek(fd, 0, SEEK_SET) != 0) {
printf("%s: seek error\n", _PATH_ZBOOT);
goto err;
}
while ((sz = read(fd, buf, sizeof(buf))) == sizeof(buf)) {
if ((sz = uwrite(tofd, buf, sz)) != sizeof(buf)) {
printf("%s: write error\n", _PATH_ZBOOT);
goto err;
}
}
if (sz < 0) {
printf("zboot_exec: read error\n");
goto err;
}
if (sz >= 0 && uwrite(tofd, buf, sz) != sz) {
printf("zboot_exec: write error\n");
goto err;
}
uclose(tofd);
/*NOTREACHED*/
return 0;
err:
uclose(tofd);
return 1;
}

View File

@ -0,0 +1,21 @@
/* $NetBSD: pathnames.h,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/* $OpenBSD: pathnames.h,v 1.3 2005/01/14 08:10:16 uwe Exp $ */
/*
* Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define _PATH_BOOTCONF "/boot.cfg"
#define _PATH_ZBOOT "/proc/zboot"

View File

@ -0,0 +1,117 @@
/* $NetBSD: termios.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/* $OpenBSD: termios.c,v 1.2 2005/05/24 20:38:20 uwe Exp $ */
/*-
* Copyright (c) 1989, 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.
*/
#include "boot.h"
#include "unixdev.h"
#include "compat_linux.h"
#include "termios.h"
int
linux_cfsetspeed(struct linux_termios *t, linux_speed_t speed)
{
int mask;
int i;
mask = LINUX_B9600; /* XXX default value should this be 0? */
for (i = 0; i < __arraycount(linux_speeds); i++) {
if (speed == linux_speeds[i]) {
mask = linux_spmasks[i];
break;
}
}
if (i == __arraycount(linux_speeds))
return -1;
t->c_cflag &= ~LINUX_CBAUD;
t->c_cflag |= mask;
return 0;
}
void
linux_cfmakeraw(struct linux_termios *t)
{
t->c_iflag &= ~(LINUX_IMAXBEL
|LINUX_IGNBRK
|LINUX_BRKINT
|LINUX_PARMRK
|LINUX_ISTRIP
|LINUX_INLCR
|LINUX_IGNCR
|LINUX_ICRNL
|LINUX_IXON);
t->c_oflag &= ~LINUX_OPOST;
t->c_lflag &= ~(LINUX_ECHO
|LINUX_ECHONL
|LINUX_ICANON
|LINUX_ISIG
|LINUX_IEXTEN);
t->c_cflag &= ~(LINUX_CSIZE|LINUX_PARENB);
t->c_cflag |= LINUX_CS8;
}
int
linux_tcgetattr(int fd, struct linux_termios *t)
{
return uioctl(fd, LINUX_TCGETS, t);
}
/* This function differs slightly from tcsetattr() in libc. */
int
linux_tcsetattr(int fd, int action, struct linux_termios *t)
{
switch (action) {
case LINUX_TCSETS:
case LINUX_TCSETSW:
case LINUX_TCSETSF:
break;
default:
errno = EINVAL;
return -1;
}
return uioctl(fd, action, t);
}
void dummycall(void);
void
dummycall(void)
{
(void)linux_termio_to_bsd_termios;
(void)bsd_termios_to_linux_termio;
(void)linux_termios_to_bsd_termios;
(void)bsd_termios_to_linux_termios;
}

View File

@ -0,0 +1,35 @@
/* $NetBSD: termios.h,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/*
* Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
* 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 AUTHOR ``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 AUTHOR 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.
*/
/* This file must be included late, for redefinitions to take effect. */
#include <compat/linux/common/linux_termios.h>
int linux_cfsetspeed(struct linux_termios *t, linux_speed_t speed);
void linux_cfmakeraw(struct linux_termios *);
int linux_tcgetattr(int, struct linux_termios *);
int linux_tcsetattr(int, int, struct linux_termios *);

View File

@ -0,0 +1,207 @@
/* $NetBSD: unixcons.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/*
* Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
* 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 AUTHOR ``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 AUTHOR 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.
*/
#include "boot.h"
#include "bootinfo.h"
#include "unixdev.h"
#include "compat_linux.h"
#include "termios.h"
struct btinfo_console bi_cons;
static int iodev = CONSDEV_GLASS;
static int infd = 0;
static int outfd = 1;
static const char *comdevname[] = {
"/dev/ttyS0",
};
static void common_putc(int fd, int c);
static int common_getc(int fd, int timo);
void
consinit(int dev, int speed)
{
struct linux_termios termios;
int fd;
switch (dev) {
case CONSDEV_COM0:
iodev = dev;
break;
case CONSDEV_GLASS:
default:
glass_console:
iodev = CONSDEV_GLASS;
break;
}
if (infd >= 0 && infd == outfd) {
uclose(infd);
infd = 0;
outfd = 1;
}
if (iodev == CONSDEV_GLASS) {
infd = 0;
outfd = 1;
strlcpy(bi_cons.devname, "glass", sizeof(bi_cons.devname));
bi_cons.addr = -1;
bi_cons.speed = -1;
} else {
fd = uopen(comdevname[iodev - CONSDEV_COM0], LINUX_O_RDWR);
if (fd < 0)
goto glass_console;
infd = outfd = fd;
/* set speed */
linux_tcgetattr(fd, &termios);
if (linux_cfsetspeed(&termios, speed) < 0) {
speed = 9600;
if (linux_cfsetspeed(&termios, speed) < 0)
goto glass_console;
}
if (linux_tcsetattr(fd, LINUX_TCSETS, &termios) < 0)
goto glass_console;
snprintf(bi_cons.devname, sizeof(bi_cons.devname), "com%d",
iodev - CONSDEV_COM0);
bi_cons.addr = -1;
bi_cons.speed = speed;
}
BI_ADD(&bi_cons, BTINFO_CONSDEV, sizeof(bi_cons));
}
void
putchar(int c)
{
common_putc(outfd, c);
}
int
getchar(void)
{
return common_getc(infd, 1);
}
static void
common_putc(int fd, int c)
{
(void)uwrite(fd, &c, 1);
}
static int
common_getc(int fd, int timo)
{
struct linux_timeval tv;
fd_set fdset;
int nfds, n;
char c;
for (; timo < 0 || timo > 0; --timo) {
tv.tv_sec = 1;
tv.tv_usec = 0;
FD_ZERO(&fdset);
nfds = 1;
FD_SET(fd, &fdset);
n = uselect(nfds, &fdset, NULL, NULL, &tv);
if (n > 0)
break;
}
if (timo > 0) {
for (fd = 0; fd < nfds; fd++) {
if (FD_ISSET(fd, &fdset)) {
return (uread(fd, &c, 1) < 1 ? -1 : c);
}
}
}
return -1;
}
int
awaitkey(int timeout, int tell)
{
struct linux_termios orig_termios, raw_termios;
int c = 0;
int i;
/* set raw mode */
linux_tcgetattr(infd, &orig_termios);
raw_termios = orig_termios;
linux_cfmakeraw(&raw_termios);
linux_tcsetattr(infd, LINUX_TCSETS, &raw_termios);
for (i = timeout; i > 0; i--) {
if (tell) {
char numbuf[20];
int len, j;
sprintf(numbuf, "%d ", i);
len = strlen(numbuf);
for (j = 0; j < len; j++)
numbuf[len + j] = '\b';
numbuf[len + j] = '\0';
printf(numbuf);
}
c = common_getc(infd, 1);
if (c == 0)
c = -1;
if (c >= 0)
break;
}
if (i == 0)
c = '\0';
/* set original mode */
linux_tcsetattr(infd, LINUX_TCSETS, &orig_termios);
if (tell)
printf("0 \n");
return c;
}
void dummycall2(void);
void
dummycall2(void)
{
(void)linux_termio_to_bsd_termios;
(void)bsd_termios_to_linux_termio;
(void)linux_termios_to_bsd_termios;
(void)bsd_termios_to_linux_termios;
}

View File

@ -0,0 +1,168 @@
/* $NetBSD: unixdev.c,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/* $OpenBSD: unixdev.c,v 1.6 2007/06/16 00:26:33 deraadt Exp $ */
/*
* Copyright (c) 1996-1998 Michael Shalayeff
* 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 AUTHOR ``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.
*
*/
#include <sys/param.h>
#include <sys/reboot.h>
#include <machine/stdarg.h>
#include "boot.h"
#include "bootinfo.h"
#include "disk.h"
#include "unixdev.h"
#include "compat_linux.h"
static struct btinfo_bootdisk bi_disk;
int
unixstrategy(void *devdata, int rw, daddr_t blk, size_t size, void *buf,
size_t *rsize)
{
off_t off;
int fd = (int)devdata;
int rc = 0;
#ifdef UNIX_DEBUG
printf("unixstrategy: %s %d bytes @ %d\n",
((rw == F_READ) ? "reading" : "writing"), (int)size, (int)blk);
#endif
off = (off_t)blk * DEV_BSIZE;
if ((rc = ulseek(fd, off, SEEK_SET)) >= 0)
rc = (rw == F_READ) ? uread(fd, buf, size) :
uwrite(fd, buf, size);
if (rc >= 0) {
*rsize = (size_t)rc;
rc = 0;
} else
rc = errno;
return rc;
}
int
unixopen(struct open_file *f, ...)
{
va_list ap;
char path[PATH_MAX];
struct diskinfo *dip;
char *devname;
const char *fname;
int dev;
u_int unit, partition;
int dospart;
va_start(ap, f);
dev = va_arg(ap, int);
devname = va_arg(ap, char *);
unit = va_arg(ap, u_int);
partition = va_arg(ap, u_int);
fname = va_arg(ap, char *);
va_end(ap);
f->f_devdata = NULL;
/* Find device. */
dip = dkdevice(devname, unit);
if (dip == NULL)
return ENOENT;
/* Try for disklabel again (might be removable media). */
if (dip->bios_info.flags & BDI_BADLABEL) {
const char *st = bios_getdisklabel(&dip->bios_info,
&dip->disklabel);
#ifdef UNIX_DEBUG
if (debug && st)
printf("%s\n", st);
#endif
if (!st) {
dip->bios_info.flags &= ~BDI_BADLABEL;
dip->bios_info.flags |= BDI_GOODLABEL;
} else
return ERDLAB;
}
dospart = bios_getdospart(&dip->bios_info);
bios_devpath(dip->bios_info.bios_number, dospart, path);
f->f_devdata = (void *)uopen(path, LINUX_O_RDONLY);
if ((int)f->f_devdata == -1)
return errno;
bi_disk.biosdev = dip->bios_info.bios_number;
bi_disk.partition = partition;
bi_disk.labelsector =
dip->disklabel.d_partitions[partition].p_offset + LABELSECTOR;
bi_disk.label.type = dip->disklabel.d_type;
memcpy(bi_disk.label.packname, dip->disklabel.d_packname, 16);
bi_disk.label.checksum = dip->disklabel.d_checksum;
BI_ADD(&bi_disk, BTINFO_BOOTDISK, sizeof(bi_disk));
return 0;
}
int
unixclose(struct open_file *f)
{
return uclose((int)f->f_devdata);
}
int
unixioctl(struct open_file *f, u_long cmd, void *data)
{
return uioctl((int)f->f_devdata, cmd, data);
}
off_t
ulseek(int fd, off_t off, int wh)
{
extern long ulseek32(int, long, int);
off_t r;
/* XXX only SEEK_SET is used, so anything else can fail for now. */
if (wh == SEEK_SET) {
if (ulseek32(fd, 0, SEEK_SET) != 0)
return -1;
while (off > OFFT_OFFSET_MAX) {
off -= OFFT_OFFSET_MAX;
if (ulseek32(fd, OFFT_OFFSET_MAX, SEEK_CUR) < 0 &&
errno != LINUX_EOVERFLOW)
return -1;
}
r = ulseek32(fd, (long)off, SEEK_CUR);
if (r == -1 && errno == LINUX_EOVERFLOW)
r = off;
} else
r = ulseek32(fd, (long)off, wh);
return r;
}

View File

@ -0,0 +1,65 @@
/* $NetBSD: unixdev.h,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/* $OpenBSD: unixdev.h,v 1.1 2005/05/24 20:38:20 uwe Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
* 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 AUTHOR ``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.
*
*/
#ifndef _STAND_UNIXDEV_H_
#define _STAND_UNIXDEV_H_
struct linux_timeval;
struct linux_stat;
/* unixcons.c */
#define CONSDEV_GLASS 0
#define CONSDEV_COM0 1
void consinit(int, int);
int awaitkey(int, int);
/* unixdev.c */
int unixopen(struct open_file *, ...);
int unixclose(struct open_file *);
int unixioctl(struct open_file *, u_long, void *);
int unixstrategy(void *, int, daddr_t, size_t, void *, size_t *);
int sleep(int seconds);
/* unixsys.S */
extern int errno;
int uopen(const char *, int, ...);
int uread(int, void *, size_t);
int uwrite(int, void *, size_t);
int uioctl(int, u_long, void *);
int uclose(int);
off_t ulseek(int, off_t, int);
void uexit(int) __attribute__((noreturn));
int uselect(int, fd_set *, fd_set *, fd_set *, struct linux_timeval *);
int ustat(const char *, struct linux_stat *);
int syscall(int, ...);
int __syscall(quad_t, ...);
#endif /* _STAND_UNIXDEV_H_ */

View File

@ -0,0 +1,76 @@
/* $NetBSD: unixsys.S,v 1.1 2009/03/02 09:33:02 nonaka Exp $ */
/* $OpenBSD: unixsys.S,v 1.6 2005/05/24 20:38:20 uwe Exp $ */
/*
* Copyright (c) 2005 Uwe Stuehler <uwe@bsdx.de>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <machine/asm.h>
#include "compat_linux.h"
.text
#define RSYSCALL(x) \
ENTRY(__CONCAT(u,x)) \
swi __CONCAT(__NR_,x); \
b 1f
RSYSCALL(exit)
RSYSCALL(read)
RSYSCALL(write)
RSYSCALL(open)
RSYSCALL(close)
RSYSCALL(lseek32)
RSYSCALL(ioctl)
RSYSCALL(stat)
1:
cmn r0, #4096
movcc pc, lr
rsb r0, r0, #0
ldr r1, .Lerrno /* XXX clobbers arg1 */
str r0, [r1]
mvn r0, #0
mov pc, lr
.Lerrno:
.word errno
/* XXX only works for up to four arguments. */
ENTRY(syscall)
swi __NR_syscall
b 1b
ENTRY(uselect)
str r4, [sp, #-4]!
ldr r4, [sp, #4]
swi __NR_select
ldr r4, [sp], #4
cmn r0, #4096
movcc pc, lr
rsb r0, r0, #0
str r1, [sp, #-4]!
ldr r1, .Lerrno
str r0, [r1]
ldr r1, [sp], #4
mvn r0, #0
mov pc, lr
.data
.global errno
errno:
.word 0

View File

@ -0,0 +1,7 @@
$NetBSD: version,v 1.1 2009/03/02 09:33:02 nonaka Exp $
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important - make sure the entries are appended on end, last item
is taken as the current.
1.0: Initial version.

View File

@ -1,4 +1,4 @@
/* $NetBSD: zbsdmod.c,v 1.3 2008/11/12 12:36:09 ad Exp $ */
/* $NetBSD: zbsdmod.c,v 1.4 2009/03/02 09:33:02 nonaka Exp $ */
/* $OpenBSD: zbsdmod.c,v 1.7 2005/05/02 02:45:29 uwe Exp $ */
/*
@ -25,8 +25,6 @@
#include <machine/bootinfo.h>
#define BOOTARGS_BUFSIZ 256
#define ZBOOTDEV_MAJOR 99
#define ZBOOTDEV_MODE 0222
#define ZBOOTDEV_NAME "zboot"
@ -351,14 +349,12 @@ zbsdmod_close(struct inode *ino, struct file *f)
printk("%s: loaded %d bytes\n", ZBOOTDEV_NAME,
position);
if (position < BOOTARGS_BUFSIZ) {
if (position < BOOTINFO_MAXSIZE) {
*(u_int *)bootargs = BOOTARGS_MAGIC;
bootargs[position + sizeof(u_int)] = '\0';
memcpy(bootargs + sizeof(u_int), bsdimage,
position);
memcpy(bootargs + sizeof(u_int), bsdimage, position);
} else {
elf32bsdboot();
printk("%s: boot failed\n", ZBOOTDEV_NAME);
printk("%s: boot failed\n", ZBOOTDEV_NAME);
}
}
isopen = 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: autoconf.c,v 1.6 2008/04/28 20:23:41 martin Exp $ */
/* $NetBSD: autoconf.c,v 1.7 2009/03/02 09:33:02 nonaka Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -27,31 +27,31 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.6 2008/04/28 20:23:41 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.7 2009/03/02 09:33:02 nonaka Exp $");
#include "opt_md.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/reboot.h>
#include <sys/disklabel.h>
#include <sys/device.h>
#include <sys/disklabel.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/vnode.h>
#include <sys/fcntl.h>
#include <sys/proc.h>
#include <sys/disk.h>
#include <sys/kauth.h>
#include <machine/intr.h>
#include <machine/bootconfig.h>
#include <machine/bootinfo.h>
#include <machine/config_hook.h>
void
cpu_rootconf(void)
{
aprint_normal("boot device: %s\n",
(booted_device != NULL) ? booted_device->dv_xname : "<unknown>");
setroot(booted_device, booted_partition);
}
static void handle_wedges(struct device *dv, int par);
static int is_valid_disk(struct device *dv);
static int match_bootdisk(struct device *dv, struct btinfo_bootdisk *bid);
static void findroot(void);
void
cpu_configure(void)
@ -69,6 +69,140 @@ cpu_configure(void)
spl0();
}
static void
handle_wedges(struct device *dv, int par)
{
if (config_handle_wedges(dv, par) == 0)
return;
booted_device = dv;
booted_partition = par;
}
static int
is_valid_disk(struct device *dv)
{
if (device_class(dv) != DV_DISK)
return 0;
return (device_is_a(dv, "dk") ||
device_is_a(dv, "sd") ||
device_is_a(dv, "wd") ||
device_is_a(dv, "ld"));
}
/*
* Helper function for findroot():
* Return non-zero if disk device matches bootinfo.
*/
static int
match_bootdisk(struct device *dv, struct btinfo_bootdisk *bid)
{
struct vnode *tmpvn;
int error;
struct disklabel label;
int found = 0;
if (device_is_a(dv, "dk"))
return 0;
/*
* A disklabel is required here. The boot loader doesn't refuse
* to boot from a disk without a label, but this is normally not
* wanted.
*/
if (bid->labelsector == -1)
return 0;
if ((tmpvn = opendisk(dv)) == NULL)
return 0;
error = VOP_IOCTL(tmpvn, DIOCGDINFO, &label, FREAD, NOCRED);
if (error) {
/*
* XXX Can't happen -- open() would have errored out
* or faked one up.
*/
printf("match_bootdisk: can't get label for dev %s (%d)\n",
device_xname(dv), error);
goto closeout;
}
/* Compare with our data. */
if (label.d_type == bid->label.type &&
label.d_checksum == bid->label.checksum &&
strncmp(label.d_packname, bid->label.packname, 16) == 0)
found = 1;
closeout:
VOP_CLOSE(tmpvn, FREAD, NOCRED);
vput(tmpvn);
return found;
}
static void
findroot(void)
{
struct btinfo_bootdisk *bid;
device_t dv;
if (booted_device)
return;
if ((bid = lookup_bootinfo(BTINFO_BOOTDISK)) != NULL) {
/*
* Scan all disk devices for ones that match the passed data.
* Don't break if one is found, to get possible multiple
* matches - for problem tracking. Use the first match anyway
* because lower device numbers are more likely to be the
* boot device.
*/
TAILQ_FOREACH(dv, &alldevs, dv_list) {
if (device_class(dv) != DV_DISK)
continue;
if (is_valid_disk(dv)) {
/*
* Don't trust BIOS device numbers, try
* to match the information passed by the
* boot loader instead.
*/
if ((bid->biosdev & 0x80) == 0 ||
match_bootdisk(dv, bid) == 0)
continue;
goto bootdisk_found;
}
continue;
bootdisk_found:
if (booted_device) {
printf("WARNING: double match for boot "
"device (%s, %s)\n",
device_xname(booted_device),
device_xname(dv));
continue;
}
handle_wedges(dv, bid->partition);
}
if (booted_device)
return;
}
}
void
cpu_rootconf(void)
{
findroot();
aprint_normal("boot device: %s\n",
booted_device ? device_xname(booted_device) : "<unknown>");
setroot(booted_device, booted_partition);
}
void
device_register(struct device *dev, void *aux)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.12 2009/02/13 22:41:04 apb Exp $ */
/* $NetBSD: machdep.c,v 1.13 2009/03/02 09:33:02 nonaka Exp $ */
/* $OpenBSD: zaurus_machdep.c,v 1.25 2006/06/20 18:24:04 todd Exp $ */
/*
@ -107,7 +107,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.12 2009/02/13 22:41:04 apb Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.13 2009/03/02 09:33:02 nonaka Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@ -240,12 +240,13 @@ struct user *proc0paddr;
const char *console = "glass";
int glass_console = 0;
char bootargs[MAX_BOOT_STRING];
struct bootinfo _bootinfo;
struct bootinfo *bootinfo;
struct btinfo_howto *bi_howto;
/* Prototypes */
void consinit(void);
void dumpsys(void);
void process_kernel_args(char *);
#ifdef KGDB
void kgdb_port_init(void);
#endif
@ -556,6 +557,7 @@ initarm(void *arg)
paddr_t memstart;
psize_t memsize;
struct pxa2x0_gpioconf **zaurus_gpioconf;
u_int *magicaddr;
/* Get ready for zaurus_restart() */
pxa2x0_memctl_bootstrap(PXA2X0_MEMCTL_BASE);
@ -584,12 +586,25 @@ initarm(void *arg)
* Examine the boot args string for options we need to know about
* now.
*/
/* XXX should really be done after setting up the console, but we
* XXX need to parse the console selection flags right now. */
process_kernel_args((char *)0xa0200000 - MAX_BOOT_STRING - 1);
magicaddr = (void *)(0xa0200000 - BOOTARGS_BUFSIZ);
if (*magicaddr == BOOTARGS_MAGIC) {
bootinfo = &_bootinfo;
memcpy(bootinfo,
(char *)0xa0200000 - BOOTINFO_MAXSIZE, BOOTINFO_MAXSIZE);
bi_howto = lookup_bootinfo(BTINFO_HOWTO);
if (bi_howto)
boothowto = bi_howto->howto;
} else {
boothowto = RB_AUTOBOOT;
}
*magicaddr = 0xdeadbeef;
#ifdef RAMDISK_HOOKS
boothowto |= RB_DFLTROOT;
#endif /* RAMDISK_HOOKS */
if (boothowto & RB_MD1) {
/* serial console */
console = "ffuart";
}
/*
* This test will work for now but has to be revised when support
@ -613,8 +628,10 @@ initarm(void *arg)
kgdb_port_init();
#endif
#ifdef VERBOSE_INIT_ARM
/* Talk to the user */
printf("\nNetBSD/zaurus booting ...\n");
#endif
{
/* XXX - all Zaurus have this for now, fix memory sizing */
@ -987,86 +1004,23 @@ initarm(void *arg)
return (kernelstack.pv_va + USPACE_SVC_STACK_TOP);
}
void
process_kernel_args(char *args)
void *
lookup_bootinfo(int type)
{
char *cp = args;
struct btinfo_common *help;
int n;
if (cp == NULL || *(u_int *)cp != BOOTARGS_MAGIC) {
boothowto = RB_AUTOBOOT;
return;
}
/* Eat the cookie */
*(u_int *)cp = 0;
cp += sizeof(u_int);
boothowto = 0;
/* Make a local copy of the bootargs */
strncpy(bootargs, cp, MAX_BOOT_STRING - sizeof(u_int));
cp = bootargs;
boot_file = bootargs;
for (;;) {
/* Skip white-space */
while (*cp == ' ')
++cp;
if (*cp == '\0')
break;
if (*cp != '-') {
/* kernel image filename */
if (boot_file == NULL)
boot_file = cp;
/* Skip the kernel image filename */
while (*cp != ' ' && *cp != '\0')
++cp;
if (*cp == '\0')
break;
*cp++ = '\0';
continue;
}
/* options */
if (*++cp != '\0') {
int fl = 0;
switch (*cp) {
case 'a':
fl |= RB_ASKNAME;
break;
case 'c':
fl |= RB_USERCONF;
break;
case 'd':
fl |= RB_KDB;
break;
case 's':
fl |= RB_SINGLE;
break;
/* XXX undocumented console switching flags */
case '0':
console = "ffuart";
break;
case '1':
console = "btuart";
break;
case '2':
console = "stuart";
break;
default:
printf("unknown option `%c'\n", *cp);
break;
}
boothowto |= fl;
}
++cp;
if (bootinfo == NULL)
return (NULL);
n = bootinfo->nentries;
help = (struct btinfo_common *)(bootinfo->info);
while (n--) {
if (help->type == type)
return (help);
help = (struct btinfo_common *)((char *)help + help->len);
}
return (NULL);
}
/*