Add NetBSD/newsmips native boot loader.
This commit is contained in:
parent
e1ef4ddcb5
commit
95faaaec9d
|
@ -0,0 +1,5 @@
|
|||
# $NetBSD: Makefile,v 1.1 1999/07/08 11:48:03 tsubai Exp $
|
||||
|
||||
SUBDIR= boot bootxx installboot
|
||||
|
||||
.include <bsd.subdir.mk>
|
|
@ -0,0 +1,3 @@
|
|||
# $NetBSD: Makefile.inc,v 1.1 1999/07/08 11:48:04 tsubai Exp $
|
||||
|
||||
BINDIR= /usr/mdec
|
|
@ -0,0 +1,60 @@
|
|||
# $NetBSD: Makefile,v 1.1 1999/07/08 11:48:05 tsubai Exp $
|
||||
|
||||
.PATH: ../bootxx
|
||||
|
||||
S= ${.CURDIR}/../../../..
|
||||
|
||||
PROG= boot
|
||||
SRCS= locore.S romcalls.S boot.c devopen.c
|
||||
MKMAN= no
|
||||
STRIPFLAG=
|
||||
BINMODE= 444
|
||||
|
||||
OBJCOPY?= objcopy
|
||||
SIZE?= size
|
||||
STRIP?= strip
|
||||
|
||||
CLEANFILES+= ${PROG}.elf ${PROG}.tmp
|
||||
CLEANFILES+= ${.OBJDIR}/machine ${.OBJDIR}/mips
|
||||
|
||||
LDFLAGS= -x -N -Ttext a0700000
|
||||
CFLAGS= -Os -G 0 -mno-abicalls -Wall
|
||||
|
||||
CPPFLAGS+= -D_STANDALONE #-DBOOT_DEBUG
|
||||
CPPFLAGS+= -I. -I../../../..
|
||||
|
||||
AFLAGS= -D_LOCORE
|
||||
|
||||
### find out what to use for libkern
|
||||
#KERNDST= ${.OBJDIR}/../lib/kern
|
||||
KERN_AS= library
|
||||
.include "${S}/lib/libkern/Makefile.inc"
|
||||
LIBKERN= ${KERNLIB}
|
||||
|
||||
### find out what to use for libz
|
||||
#ZDST= ${.OBJDIR}/../lib/z
|
||||
Z_AS= library
|
||||
.include "${S}/lib/libz/Makefile.inc"
|
||||
LIBZ= ${ZLIB}
|
||||
|
||||
### find out what to use for libsa
|
||||
#SADST= ${.OBJDIR}/../lib/sa
|
||||
SA_AS= library
|
||||
SAMISCMAKEFLAGS= SA_USE_CREAD=yes SA_USE_LOADFILE=yes
|
||||
.include "${S}/lib/libsa/Makefile.inc"
|
||||
LIBSA= ${SALIB}
|
||||
|
||||
.BEGIN:
|
||||
@[ -h machine ] || ln -s ${S}/arch/${MACHINE}/include machine
|
||||
@[ -h mips ] || ln -s ${S}/arch/mips/include mips
|
||||
|
||||
${PROG}: ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN}
|
||||
${LD} ${LDFLAGS} -o ${PROG} ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN}
|
||||
-${SIZE} ${PROG}
|
||||
cp ${PROG} ${PROG}.elf
|
||||
${STRIP} ${PROG}
|
||||
tail -c +177 ${PROG} > ${PROG}.tmp
|
||||
mv ${PROG}.tmp ${PROG}
|
||||
# ${OBJCOPY} -O binary ${PROG}.elf ${PROG} # XXX
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -0,0 +1,123 @@
|
|||
/* $NetBSD: boot.c,v 1.1 1999/07/08 11:48:05 tsubai Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1999 Tsubai Masanari. 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 <lib/libkern/libkern.h>
|
||||
#include <lib/libsa/stand.h>
|
||||
#include <lib/libsa/loadfile.h>
|
||||
|
||||
#include <machine/romcall.h>
|
||||
|
||||
void flushicache __P((void *, int));
|
||||
extern char _edata[], _end[];
|
||||
|
||||
char *devs[] = { "sd", "fh", "fd", NULL, NULL, "rd", "st" };
|
||||
char *kernels[] = { "/netbsd", "/netbsd.gz", NULL };
|
||||
|
||||
#ifdef BOOT_DEBUG
|
||||
# define DPRINTF printf
|
||||
#else
|
||||
# define DPRINTF while (0) printf
|
||||
#endif
|
||||
|
||||
void
|
||||
boot(a0, a1, a2, a3, a4, a5)
|
||||
int a0, a1, a2, a3, a4, a5;
|
||||
{
|
||||
int fd, i;
|
||||
int ctlr, unit, part, type;
|
||||
int bootdev = a1;
|
||||
char *netbsd = (char *)a2;
|
||||
u_long marks[MARK_MAX];
|
||||
char devname[32], file[32];
|
||||
void (*entry)();
|
||||
|
||||
/* Clear BSS. */
|
||||
bzero(_edata, _end - _edata);
|
||||
|
||||
printf("\n");
|
||||
printf("NetBSD/newsmips Secondary Boot\n");
|
||||
|
||||
/* bootname is "/boot" by default. */
|
||||
if (netbsd == NULL || strcmp(netbsd, "/boot") == 0)
|
||||
netbsd = "";
|
||||
|
||||
DPRINTF("howto = 0x%x\n", a0);
|
||||
DPRINTF("bootdev = 0x%x\n", bootdev);
|
||||
DPRINTF("bootname = %s\n", netbsd);
|
||||
DPRINTF("maxmem = 0x%x\n", a3);
|
||||
|
||||
ctlr = BOOTDEV_CTLR(bootdev);
|
||||
unit = BOOTDEV_UNIT(bootdev);
|
||||
part = BOOTDEV_PART(bootdev);
|
||||
type = BOOTDEV_TYPE(bootdev);
|
||||
|
||||
marks[MARK_START] = 0;
|
||||
|
||||
if (devs[type] == NULL) {
|
||||
printf("unknown bootdev (0x%x)\n", bootdev);
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(devname, "%s(%d,%d,%d)", devs[type], ctlr, unit, part);
|
||||
printf("Booting %s%s\n", devname, netbsd);
|
||||
|
||||
/* use user specified kernel name if exists */
|
||||
if (*netbsd) {
|
||||
kernels[0] = netbsd;
|
||||
kernels[1] = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; kernels[i]; i++) {
|
||||
sprintf(file, "%s%s", devname, kernels[i]);
|
||||
DPRINTF("trying %s...\n", file);
|
||||
fd = loadfile(file, marks, LOAD_ALL);
|
||||
if (fd != -1)
|
||||
break;
|
||||
}
|
||||
if (fd == -1)
|
||||
return;
|
||||
|
||||
DPRINTF("entry = 0x%x\n", (int)marks[MARK_ENTRY]);
|
||||
DPRINTF("ssym = 0x%x\n", (int)marks[MARK_SYM]);
|
||||
DPRINTF("esym = 0x%x\n", (int)marks[MARK_END]);
|
||||
|
||||
entry = (void *)marks[MARK_ENTRY];
|
||||
flushicache(entry, marks[MARK_SYM] - marks[MARK_ENTRY]);
|
||||
|
||||
printf("\n");
|
||||
(*entry)(a0, a1, a2, a3, a4, a5);
|
||||
}
|
||||
|
||||
void
|
||||
putchar(x)
|
||||
int x;
|
||||
{
|
||||
char c = x;
|
||||
|
||||
rom_write(1, &c, 1);
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
/* $NetBSD: devopen.c,v 1.1 1999/07/08 11:48:05 tsubai Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1999 Tsubai Masanari. 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 <lib/libkern/libkern.h>
|
||||
#include <lib/libsa/stand.h>
|
||||
#include <lib/libsa/ufs.h>
|
||||
|
||||
#include <machine/romcall.h>
|
||||
|
||||
#ifdef BOOT_DEBUG
|
||||
# define DPRINTF printf
|
||||
#else
|
||||
# define DPRINTF while (0) printf
|
||||
#endif
|
||||
|
||||
int dkopen __P((struct open_file *, ...));
|
||||
int dkclose __P((struct open_file *));
|
||||
int dkstrategy __P((void *, int, daddr_t, size_t, void *, size_t *));
|
||||
|
||||
struct devsw devsw[] = {
|
||||
{ "dk", dkstrategy, dkopen, dkclose, noioctl }
|
||||
};
|
||||
int ndevs = sizeof(devsw) / sizeof(devsw[0]);
|
||||
|
||||
struct fs_ops file_system[] = {
|
||||
{ ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat }
|
||||
};
|
||||
int nfsys = sizeof(file_system) / sizeof(file_system[0]);
|
||||
|
||||
struct romdev {
|
||||
int fd;
|
||||
} romdev;
|
||||
|
||||
int
|
||||
devopen(f, fname, file)
|
||||
struct open_file *f;
|
||||
const char *fname;
|
||||
char **file; /* out */
|
||||
{
|
||||
int fd;
|
||||
char devname[32];
|
||||
char *cp;
|
||||
|
||||
DPRINTF("devopen: %s\n", fname);
|
||||
|
||||
strcpy(devname, fname);
|
||||
cp = strchr(devname, ')') + 1;
|
||||
*cp = 0;
|
||||
fd = rom_open(devname, 0);
|
||||
|
||||
DPRINTF("devname = %s, fd = %d\n", devname, fd);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
romdev.fd = fd;
|
||||
|
||||
f->f_dev = devsw;
|
||||
f->f_devdata = &romdev;
|
||||
*file = strchr(fname, ')') + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dkopen(struct open_file *f, ...)
|
||||
{
|
||||
DPRINTF("dkopen\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dkclose(f)
|
||||
struct open_file *f;
|
||||
{
|
||||
struct romdev *dev = f->f_devdata;
|
||||
|
||||
DPRINTF("dkclose\n");
|
||||
rom_close(dev->fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dkstrategy(devdata, rw, blk, size, buf, rsize)
|
||||
void *devdata;
|
||||
int rw;
|
||||
daddr_t blk;
|
||||
size_t size;
|
||||
void *buf;
|
||||
size_t *rsize; /* out: number of bytes transfered */
|
||||
{
|
||||
struct romdev *dev = devdata;
|
||||
|
||||
/* XXX should use partition offset */
|
||||
|
||||
rom_lseek(dev->fd, blk * 512, 0);
|
||||
rom_read(dev->fd, buf, size);
|
||||
*rsize = size;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/* $NetBSD: locore.S,v 1.1 1999/07/08 11:48:05 tsubai Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1999 Tsubai Masanari. 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 <mips/asm.h>
|
||||
#include <mips/cpuregs.h>
|
||||
|
||||
.set noreorder
|
||||
.text
|
||||
.align 2
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
j boot
|
||||
nop
|
||||
|
||||
/* void flushicache(addr, len); */
|
||||
|
||||
.globl flushicache
|
||||
flushicache:
|
||||
mfc0 v0, MIPS_COP_0_STATUS # save SR
|
||||
mtc0 zero, MIPS_COP_0_STATUS # disable interrupts
|
||||
|
||||
la v1, 1f
|
||||
or v1, MIPS_KSEG1_START # run uncached
|
||||
j v1
|
||||
nop
|
||||
1:
|
||||
li v1, MIPS_SR_ISOL_CACHES | MIPS_SR_SWAP_CACHES
|
||||
mtc0 v1, MIPS_COP_0_STATUS
|
||||
nop
|
||||
addu a1, a1, a0 # compute ending address
|
||||
2:
|
||||
sb zero, -4(a0)
|
||||
bne a0, a1, 2b
|
||||
addu a0, a0, 4
|
||||
|
||||
mtc0 v0, MIPS_COP_0_STATUS # enable interrupts
|
||||
j ra # return and run cached
|
||||
nop
|
|
@ -0,0 +1,24 @@
|
|||
# $NetBSD: Makefile,v 1.1 1999/07/08 11:48:06 tsubai Exp $
|
||||
|
||||
PROG= bootxx
|
||||
SRCS= start.S romcalls.S bootxx.c
|
||||
MKMAN= no
|
||||
STRIPFLAG=
|
||||
BINMODE= 444
|
||||
SIZE?= size
|
||||
|
||||
LDFLAGS= -x -N -Ttext a0000000
|
||||
CFLAGS= -Os -mno-abicalls -G 0 -Wall
|
||||
|
||||
CPPFLAGS+= -D_STANDALONE #-DBOOTXX_DEBUG
|
||||
CPPFLAGS+= -I../../../..
|
||||
AFLAGS= -D_LOCORE
|
||||
|
||||
L= ../boot/lib
|
||||
LIBS= ${L}/sa/libsa.a ${L}/kern/libkern.a
|
||||
|
||||
${PROG}: ${OBJS}
|
||||
${LD} ${LDFLAGS} -o ${PROG} ${OBJS} ${LIBS}
|
||||
${SIZE} ${PROG}
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -0,0 +1,118 @@
|
|||
/* $NetBSD: bootxx.c,v 1.1 1999/07/08 11:48:06 tsubai Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1999 Tsubai Masanari. 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 <lib/libkern/libkern.h>
|
||||
#include <lib/libsa/stand.h>
|
||||
#include <machine/romcall.h>
|
||||
|
||||
#define MAXBLOCKNUM 64
|
||||
|
||||
void (*entry_point)() = (void *)0;
|
||||
int block_size = 8192;
|
||||
int block_count = MAXBLOCKNUM;
|
||||
int block_table[MAXBLOCKNUM] = { 0 };
|
||||
|
||||
#ifdef BOOTXX_DEBUG
|
||||
# define DPRINTF printf
|
||||
#else
|
||||
# define DPRINTF while (0) printf
|
||||
#endif
|
||||
|
||||
char *devs[] = { "sd", "fh", "fd", NULL, NULL, "rd", "st" };
|
||||
|
||||
void
|
||||
bootxx(a0, a1, a2, a3, a4, a5)
|
||||
int a0, a1, a2, a3, a4, a5;
|
||||
{
|
||||
int fd, blk, bs;
|
||||
int ctlr, unit, part, type;
|
||||
int i;
|
||||
int bootdev = a1;
|
||||
char *addr;
|
||||
char devname[32];
|
||||
|
||||
printf("NetBSD/newsmips Primary Boot\n");
|
||||
|
||||
DPRINTF("\n");
|
||||
DPRINTF("a0 %x\n", a0);
|
||||
DPRINTF("a1 %x\n", a1);
|
||||
DPRINTF("a2 %x (%s)\n", a2, (char *)a2);
|
||||
DPRINTF("a3 %x\n", a3);
|
||||
DPRINTF("a4 %x\n", a4);
|
||||
DPRINTF("a5 %x\n", a5);
|
||||
|
||||
DPRINTF("block_size = %d\n", block_size);
|
||||
DPRINTF("block_count = %d\n", block_count);
|
||||
DPRINTF("entry_point = %x\n", (int)entry_point);
|
||||
|
||||
/* sd(ctlr, lun, part, bus?, host) */
|
||||
|
||||
ctlr = BOOTDEV_CTLR(bootdev);
|
||||
unit = BOOTDEV_UNIT(bootdev);
|
||||
part = BOOTDEV_PART(bootdev);
|
||||
type = BOOTDEV_TYPE(bootdev);
|
||||
|
||||
if (devs[type] == NULL) {
|
||||
printf("unknown bootdev (0x%x)\n", bootdev);
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(devname, "%s(%d,%d,%d)", devs[type], ctlr, unit, part);
|
||||
|
||||
fd = rom_open(devname, 0);
|
||||
if (fd == -1) {
|
||||
printf("cannot open %s\n", devname);
|
||||
return;
|
||||
}
|
||||
|
||||
addr = (char *)entry_point;
|
||||
bs = block_size;
|
||||
DPRINTF("reading block:");
|
||||
for (i = 0; i < block_count; i++) {
|
||||
blk = block_table[i];
|
||||
|
||||
DPRINTF(" %d", blk);
|
||||
|
||||
rom_lseek(fd, blk * 512, 0);
|
||||
rom_read(fd, addr, bs);
|
||||
addr += bs;
|
||||
}
|
||||
DPRINTF(" done\n");
|
||||
rom_close(fd);
|
||||
|
||||
(*entry_point)(a0, a1, a2, a3);
|
||||
}
|
||||
|
||||
void
|
||||
putchar(x)
|
||||
int x;
|
||||
{
|
||||
char c = x;
|
||||
|
||||
rom_write(1, &c, 1);
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
/* $NetBSD: romcalls.S,v 1.1 1999/07/08 11:48:07 tsubai Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1999 Tsubai Masanari. 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 <mips/asm.h>
|
||||
#include <mips/cpuregs.h>
|
||||
#include <machine/romcall.h>
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.set noreorder
|
||||
|
||||
.globl halt
|
||||
halt:
|
||||
addu sp, sp, -16
|
||||
li a0, 8 # RB_HALT
|
||||
sw a0, 0(sp)
|
||||
li a0, SYS_reboot
|
||||
move a1, sp
|
||||
syscall
|
||||
nop
|
||||
|
||||
.globl rom_open
|
||||
rom_open:
|
||||
addu sp, sp, -32
|
||||
sw ra, 28(sp)
|
||||
|
||||
sw a0, 16(sp)
|
||||
sw a1, 20(sp)
|
||||
|
||||
li a0, SYS_open
|
||||
addu a1, sp, 16
|
||||
syscall
|
||||
nop
|
||||
|
||||
lw ra, 28(sp)
|
||||
addu sp, sp, 32
|
||||
j ra
|
||||
nop
|
||||
|
||||
.globl rom_close
|
||||
rom_close:
|
||||
addu sp, sp, -32
|
||||
sw ra, 28(sp)
|
||||
|
||||
sw a0, 16(sp)
|
||||
|
||||
li a0, SYS_close
|
||||
addu a1, sp, 16
|
||||
syscall
|
||||
nop
|
||||
|
||||
lw ra, 28(sp)
|
||||
addu sp, sp, 32
|
||||
j ra
|
||||
nop
|
||||
|
||||
.globl rom_read
|
||||
rom_read:
|
||||
addu sp, sp, -32
|
||||
sw ra, 28(sp)
|
||||
|
||||
sw a0, 16(sp)
|
||||
sw a1, 20(sp)
|
||||
sw a2, 24(sp)
|
||||
|
||||
li a0, SYS_read
|
||||
addu a1, sp, 16
|
||||
syscall
|
||||
nop
|
||||
|
||||
lw ra, 28(sp)
|
||||
addu sp, sp, 32
|
||||
j ra
|
||||
nop
|
||||
|
||||
.globl rom_write
|
||||
rom_write:
|
||||
addu sp, sp, -32
|
||||
sw ra, 28(sp)
|
||||
|
||||
sw a0, 16(sp)
|
||||
sw a1, 20(sp)
|
||||
sw a2, 24(sp)
|
||||
|
||||
li a0, SYS_write
|
||||
addu a1, sp, 16
|
||||
syscall
|
||||
nop
|
||||
|
||||
lw ra, 28(sp)
|
||||
addu sp, sp, 32
|
||||
j ra
|
||||
nop
|
||||
|
||||
|
||||
.globl rom_lseek
|
||||
rom_lseek:
|
||||
addu sp, sp, -32
|
||||
sw ra, 28(sp)
|
||||
|
||||
sw a0, 16(sp)
|
||||
sw a1, 20(sp)
|
||||
sw a2, 24(sp)
|
||||
|
||||
li a0, SYS_lseek
|
||||
addu a1, sp, 16
|
||||
syscall
|
||||
nop
|
||||
|
||||
lw ra, 28(sp)
|
||||
addu sp, sp, 32
|
||||
j ra
|
||||
nop
|
|
@ -0,0 +1,54 @@
|
|||
/* $NetBSD: start.S,v 1.1 1999/07/08 11:48:07 tsubai Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (C) 1999 Tsubai Masanari. 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 <mips/asm.h>
|
||||
#include <mips/cpuregs.h>
|
||||
|
||||
.text
|
||||
.align 2
|
||||
.set noreorder
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
b 1f
|
||||
nop
|
||||
.word 0x19900106 /* version? */
|
||||
.word 0
|
||||
|
||||
/* disklabel here */
|
||||
.space 0x1f0
|
||||
|
||||
1:
|
||||
li sp, 0x7fff0000
|
||||
addu sp, sp, a3 /* sp = 0x7fff0000 + maxmem */
|
||||
|
||||
jal bootxx
|
||||
nop
|
||||
|
||||
jal halt
|
||||
nop
|
|
@ -0,0 +1,8 @@
|
|||
# $NetBSD: Makefile,v 1.1 1999/07/08 11:48:07 tsubai Exp $
|
||||
|
||||
PROG= installboot
|
||||
MKMAN= no
|
||||
|
||||
LDSTATIC= -static
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -0,0 +1,452 @@
|
|||
/* $NetBSD: installboot.c,v 1.1 1999/07/08 11:48:08 tsubai Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Paul Kranenburg.
|
||||
*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation 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 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/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <err.h>
|
||||
#ifdef BOOT_AOUT
|
||||
#include <a.out.h>
|
||||
#endif
|
||||
#include <sys/exec_elf.h>
|
||||
#include <fcntl.h>
|
||||
#include <nlist.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int verbose, nowrite;
|
||||
char *boot, *proto, *dev;
|
||||
|
||||
#define BOOTSECTOR_OFFSET 512
|
||||
|
||||
#ifndef DEFAULT_ENTRY
|
||||
#define DEFAULT_ENTRY 0xa0700000
|
||||
#endif
|
||||
|
||||
struct nlist nl[] = {
|
||||
#define X_BLOCKTABLE 0
|
||||
{"_block_table"},
|
||||
#define X_BLOCKCOUNT 1
|
||||
{"_block_count"},
|
||||
#define X_BLOCKSIZE 2
|
||||
{"_block_size"},
|
||||
#define X_ENTRY_POINT 3
|
||||
{"_entry_point"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
daddr_t *block_table; /* block number array in prototype image */
|
||||
int32_t *block_count_p; /* size of this array */
|
||||
int32_t *block_size_p; /* filesystem block size */
|
||||
int32_t *entry_point_p; /* entry point */
|
||||
int32_t max_block_count;
|
||||
|
||||
char *loadprotoblocks __P((char *, long *));
|
||||
int loadblocknums __P((char *, int));
|
||||
static void devread __P((int, void *, daddr_t, size_t, char *));
|
||||
static void usage __P((void));
|
||||
int main __P((int, char *[]));
|
||||
|
||||
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: installboot [-n] [-v] <boot> <proto> <device>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int c;
|
||||
int devfd;
|
||||
char *protostore;
|
||||
long protosize;
|
||||
size_t size;
|
||||
int boot00[512/4];
|
||||
|
||||
while ((c = getopt(argc, argv, "vn")) != EOF) {
|
||||
switch (c) {
|
||||
|
||||
case 'n':
|
||||
/* Do not actually write the bootblock to disk */
|
||||
nowrite = 1;
|
||||
break;
|
||||
case 'v':
|
||||
/* Chat */
|
||||
verbose = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (argc - optind < 3) {
|
||||
usage();
|
||||
}
|
||||
|
||||
boot = argv[optind];
|
||||
proto = argv[optind + 1];
|
||||
dev = argv[optind + 2];
|
||||
|
||||
if (verbose) {
|
||||
printf("boot: %s\n", boot);
|
||||
printf("proto: %s\n", proto);
|
||||
printf("device: %s\n", dev);
|
||||
}
|
||||
|
||||
/* Load proto blocks into core */
|
||||
if ((protostore = loadprotoblocks(proto, &protosize)) == NULL)
|
||||
exit(1);
|
||||
|
||||
/* Open and check raw disk device */
|
||||
if ((devfd = open(dev, O_RDONLY, 0)) < 0)
|
||||
err(1, "open: %s", dev);
|
||||
|
||||
/* Extract and load block numbers */
|
||||
if (loadblocknums(boot, devfd) != 0)
|
||||
exit(1);
|
||||
|
||||
(void)close(devfd);
|
||||
|
||||
if (nowrite)
|
||||
return 0;
|
||||
|
||||
/* Write patched proto bootblocks into the superblock */
|
||||
if (protosize > SBSIZE - DEV_BSIZE)
|
||||
errx(1, "proto bootblocks too big");
|
||||
|
||||
if ((devfd = open(dev, O_RDWR, 0)) < 0)
|
||||
err(1, "open: %s", dev);
|
||||
|
||||
if (lseek(devfd, BOOTSECTOR_OFFSET, SEEK_SET) != BOOTSECTOR_OFFSET)
|
||||
err(1, "lseek bootstrap");
|
||||
|
||||
/* Sync filesystems (to clean in-memory superblock?) */
|
||||
sync(); sync(); sync();
|
||||
|
||||
if (write(devfd, protostore, protosize) != protosize)
|
||||
err(1, "write bootstrap");
|
||||
|
||||
/* Write boot00 */
|
||||
if (lseek(devfd, 0, SEEK_SET) != 0)
|
||||
err(1, "lseek 0a");
|
||||
if (read(devfd, boot00, sizeof(boot00)) != sizeof(boot00))
|
||||
err(1, "read boot00");
|
||||
|
||||
bzero(boot00, 64);
|
||||
boot00[0] = 0x1000007f; /* b .+0x200 */
|
||||
boot00[2] = 0x19900106;
|
||||
if (lseek(devfd, 0, SEEK_SET) != 0)
|
||||
err(1, "lseek 0b");
|
||||
if (write(devfd, boot00, sizeof(boot00)) != sizeof(boot00))
|
||||
err(1, "write boot00");
|
||||
|
||||
(void)close(devfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
loadprotoblocks(fname, size)
|
||||
char *fname;
|
||||
long *size;
|
||||
{
|
||||
int fd, sz;
|
||||
char *bp;
|
||||
struct stat statbuf;
|
||||
#ifdef BOOT_AOUT
|
||||
struct exec *hp;
|
||||
#endif
|
||||
long off;
|
||||
Elf32_Ehdr *eh;
|
||||
Elf32_Phdr *ph;
|
||||
|
||||
/* Locate block number array in proto file */
|
||||
if (nlist(fname, nl) != 0) {
|
||||
warnx("nlist: %s: symbols not found", fname);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef BOOT_AOUT
|
||||
if (nl[X_BLOCKTABLE].n_type != N_DATA + N_EXT) {
|
||||
warnx("nlist: %s: wrong type", nl[X_BLOCKTABLE].n_un.n_name);
|
||||
return NULL;
|
||||
}
|
||||
if (nl[X_BLOCKCOUNT].n_type != N_DATA + N_EXT) {
|
||||
warnx("nlist: %s: wrong type", nl[X_BLOCKCOUNT].n_un.n_name);
|
||||
return NULL;
|
||||
}
|
||||
if (nl[X_BLOCKSIZE].n_type != N_DATA + N_EXT) {
|
||||
warnx("nlist: %s: wrong type", nl[X_BLOCKSIZE].n_un.n_name);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((fd = open(fname, O_RDONLY)) < 0) {
|
||||
warn("open: %s", fname);
|
||||
return NULL;
|
||||
}
|
||||
if (fstat(fd, &statbuf) != 0) {
|
||||
warn("fstat: %s", fname);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if ((bp = calloc(roundup(statbuf.st_size, DEV_BSIZE), 1)) == NULL) {
|
||||
warnx("malloc: %s: no memory", fname);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if (read(fd, bp, statbuf.st_size) != statbuf.st_size) {
|
||||
warn("read: %s", fname);
|
||||
free(bp);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
#ifdef BOOT_AOUT
|
||||
hp = (struct exec *)bp;
|
||||
#endif
|
||||
eh = (Elf32_Ehdr *)bp;
|
||||
ph = (Elf32_Phdr *)(bp + eh->e_phoff);
|
||||
sz = 1024*7;
|
||||
|
||||
/* Find first executable psect */
|
||||
while ((ph->p_flags & Elf_pf_x) == 0) {
|
||||
ph++; /* XXX check overrun (eh->e_phnum) */
|
||||
eh->e_phnum--;
|
||||
if (eh->e_phnum == 0) {
|
||||
warn("%s: no executable psect", fname);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate the symbols' location within the proto file */
|
||||
off = ph->p_offset - eh->e_entry;
|
||||
block_table = (daddr_t *)(bp + nl[X_BLOCKTABLE].n_value + off);
|
||||
block_count_p = (int32_t *)(bp + nl[X_BLOCKCOUNT].n_value + off);
|
||||
block_size_p = (int32_t *)(bp + nl[X_BLOCKSIZE].n_value + off);
|
||||
entry_point_p = (int32_t *)(bp + nl[X_ENTRY_POINT].n_value + off);
|
||||
|
||||
if ((int)block_table & 3) {
|
||||
warn("%s: invalid address: block_table = %x",
|
||||
fname, block_table);
|
||||
free(bp);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if ((int)block_count_p & 3) {
|
||||
warn("%s: invalid address: block_count_p = %x",
|
||||
fname, block_count_p);
|
||||
free(bp);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if ((int)block_size_p & 3) {
|
||||
warn("%s: invalid address: block_size_p = %x",
|
||||
fname, block_size_p);
|
||||
free(bp);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
if ((int)entry_point_p & 3) {
|
||||
warn("%s: invalid address: entry_point_p = %x",
|
||||
fname, entry_point_p);
|
||||
free(bp);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
max_block_count = *block_count_p;
|
||||
|
||||
if (verbose) {
|
||||
printf("proto bootblock size: %ld\n", sz);
|
||||
}
|
||||
|
||||
/*
|
||||
* We convert the a.out header in-vitro into something that
|
||||
* Sun PROMs understand.
|
||||
* Old-style (sun4) ROMs do not expect a header at all, so
|
||||
* we turn the first two words into code that gets us past
|
||||
* the 32-byte header where the actual code begins. In assembly
|
||||
* speak:
|
||||
* .word MAGIC ! a NOP
|
||||
* ba,a start !
|
||||
* .skip 24 ! pad
|
||||
* start:
|
||||
*/
|
||||
|
||||
*size = sz;
|
||||
return bp + ph->p_offset + 0x200; /* XXX 0x200 */
|
||||
}
|
||||
|
||||
static void
|
||||
devread(fd, buf, blk, size, msg)
|
||||
int fd;
|
||||
void *buf;
|
||||
daddr_t blk;
|
||||
size_t size;
|
||||
char *msg;
|
||||
{
|
||||
if (lseek(fd, dbtob(blk), SEEK_SET) != dbtob(blk))
|
||||
err(1, "%s: devread: lseek", msg);
|
||||
|
||||
if (read(fd, buf, size) != size)
|
||||
err(1, "%s: devread: read", msg);
|
||||
}
|
||||
|
||||
static char sblock[SBSIZE];
|
||||
|
||||
int
|
||||
loadblocknums(boot, devfd)
|
||||
char *boot;
|
||||
int devfd;
|
||||
{
|
||||
int i, fd;
|
||||
struct stat statbuf;
|
||||
struct statfs statfsbuf;
|
||||
struct fs *fs;
|
||||
char *buf;
|
||||
daddr_t blk, *ap;
|
||||
struct dinode *ip;
|
||||
int ndb;
|
||||
|
||||
/*
|
||||
* Open 2nd-level boot program and record the block numbers
|
||||
* it occupies on the filesystem represented by `devfd'.
|
||||
*/
|
||||
if ((fd = open(boot, O_RDONLY)) < 0)
|
||||
err(1, "open: %s", boot);
|
||||
|
||||
if (fstatfs(fd, &statfsbuf) != 0)
|
||||
err(1, "statfs: %s", boot);
|
||||
|
||||
if (strncmp(statfsbuf.f_fstypename, "ffs", MFSNAMELEN) &&
|
||||
strncmp(statfsbuf.f_fstypename, "ufs", MFSNAMELEN)) {
|
||||
errx(1, "%s: must be on an FFS filesystem", boot);
|
||||
}
|
||||
|
||||
if (fsync(fd) != 0)
|
||||
err(1, "fsync: %s", boot);
|
||||
|
||||
if (fstat(fd, &statbuf) != 0)
|
||||
err(1, "fstat: %s", boot);
|
||||
|
||||
close(fd);
|
||||
|
||||
/* Read superblock */
|
||||
devread(devfd, sblock, btodb(SBOFF), SBSIZE, "superblock");
|
||||
fs = (struct fs *)sblock;
|
||||
|
||||
/* Read inode */
|
||||
if ((buf = malloc(fs->fs_bsize)) == NULL)
|
||||
errx(1, "No memory for filesystem block");
|
||||
|
||||
blk = fsbtodb(fs, ino_to_fsba(fs, statbuf.st_ino));
|
||||
devread(devfd, buf, blk, fs->fs_bsize, "inode");
|
||||
ip = (struct dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino);
|
||||
|
||||
/*
|
||||
* Register filesystem block size.
|
||||
*/
|
||||
*block_size_p = fs->fs_bsize;
|
||||
|
||||
/*
|
||||
* Get the block numbers; we don't handle fragments
|
||||
*/
|
||||
ndb = howmany(ip->di_size, fs->fs_bsize);
|
||||
if (ndb > max_block_count)
|
||||
errx(1, "%s: Too many blocks", boot);
|
||||
|
||||
/*
|
||||
* Register block count.
|
||||
*/
|
||||
*block_count_p = ndb;
|
||||
|
||||
/*
|
||||
* Register entry point.
|
||||
*/
|
||||
*entry_point_p = DEFAULT_ENTRY;
|
||||
if (verbose)
|
||||
printf("entry point: 0x%08x\n", *entry_point_p);
|
||||
|
||||
if (verbose)
|
||||
printf("%s: block numbers: ", boot);
|
||||
ap = ip->di_db;
|
||||
for (i = 0; i < NDADDR && *ap && ndb; i++, ap++, ndb--) {
|
||||
blk = fsbtodb(fs, *ap);
|
||||
block_table[i] = blk;
|
||||
if (verbose)
|
||||
printf("%d ", blk);
|
||||
}
|
||||
if (verbose)
|
||||
printf("\n");
|
||||
|
||||
if (ndb == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Just one level of indirections; there isn't much room
|
||||
* for more in the 1st-level bootblocks anyway.
|
||||
*/
|
||||
if (verbose)
|
||||
printf("%s: block numbers (indirect): ", boot);
|
||||
blk = ip->di_ib[0];
|
||||
devread(devfd, buf, blk, fs->fs_bsize, "indirect block");
|
||||
ap = (daddr_t *)buf;
|
||||
for (; i < NINDIR(fs) && *ap && ndb; i++, ap++, ndb--) {
|
||||
blk = fsbtodb(fs, *ap);
|
||||
block_table[i] = blk;
|
||||
if (verbose)
|
||||
printf("%d ", blk);
|
||||
}
|
||||
if (verbose)
|
||||
printf("\n");
|
||||
|
||||
if (ndb)
|
||||
errx(1, "%s: Too many blocks", boot);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue