From dfe0069034ac412d0d7d1244d1557c7235081d03 Mon Sep 17 00:00:00 2001 From: millert Date: Mon, 5 May 1997 06:01:44 +0000 Subject: [PATCH] Updates from NetBSD (cgd): - seriously clean up makefiles. use libsa/libkern/libz as appropriate, and don't build the various sources into objs locally by specifying them directly in the Makefiles. - move the secondary bootstrap down (to 0x20004000), and add a HEAP_LIMIT so that we don't exhaust our bootstrap address space (when using the new, not yet checked in, memory allocator). - clean up installboot, deal with secondary bootstrap programs not on 'a' partition or 'a' partition not starting at 0. - add padding to structures in bbinfo.h for future expansion. Add a netbbinfo structure to allow netboot information to be hard-coded in network boot blocks, so that they can be made to work even on systems with firmware which doesn't support the new "ethernet address in boot device" convention. - move the sync() calls to the correct place in installboot.c - remove a kludge in disk.c which was breaking multiple opens/closes of the disk - allow netboot ethernet address to be hard-coded into binary so that machines with old firmware which doesn't pass it in the boot device can work. Assume that if the ethernet address isn't passed in, it uses the old (dain-bramaged) 'read' interface works on my 3000/300LX. - Add setnetbootinfo, a program to hard code an ethernet address into a network boot. - move an 'int debug;' into boot.c (it was the only diff between boot.c and netboot.c), and nuke netboot.c (using boot.c instead for net boot blocks). - add cd9660 file system ops to the file system ops table in filesystem.c - if a file name is given (i.e. BOOTED_FILE) is set, boot only that file, but if not then try to boot "bsd", "bsd.bak", "bsd.old", and "obsd" (in that order) until one is found or until the list of names is exhausted. - add support for reading gzipped kernels. - use strerror() to print errors, rather than just printing error numbers - if no disk label exists, fake one up - slightly relax the block size checks in bootxx.c; they were a bit to paranoid And local changes: - don't build a copy of libsa/libkern/libz for each boot prog, just build a single copy and use it for everything. --- sys/arch/alpha/stand/Makefile | 6 +- sys/arch/alpha/stand/Makefile.inc | 16 +- sys/arch/alpha/stand/bbinfo.h | 32 ++- sys/arch/alpha/stand/boot/Makefile | 88 ++++--- sys/arch/alpha/stand/boot/boot.c | 33 ++- sys/arch/alpha/stand/boot/devopen.c | 6 +- sys/arch/alpha/stand/boot/disk.c | 17 +- sys/arch/alpha/stand/boot/filesystem.c | 7 +- sys/arch/alpha/stand/boot/version | 7 +- sys/arch/alpha/stand/bootxx.c | 7 +- sys/arch/alpha/stand/bootxx/Makefile | 68 ++--- sys/arch/alpha/stand/installboot.8 | 64 +++-- sys/arch/alpha/stand/installboot.c | 104 +++++--- sys/arch/alpha/stand/installboot/Makefile | 5 +- sys/arch/alpha/stand/libkern/Makefile | 5 + sys/arch/alpha/stand/libkern/Makefile.inc | 52 ++++ sys/arch/alpha/stand/libsa/Makefile | 5 + sys/arch/alpha/stand/libsa/Makefile.inc | 41 +++ sys/arch/alpha/stand/libz/Makefile | 5 + sys/arch/alpha/stand/libz/Makefile.inc | 71 +++++ sys/arch/alpha/stand/loadfile.c | 18 +- sys/arch/alpha/stand/netboot/Makefile | 98 +++---- sys/arch/alpha/stand/netboot/conf.c | 8 +- sys/arch/alpha/stand/netboot/dev_net.c | 12 +- sys/arch/alpha/stand/netboot/devopen.c | 6 +- sys/arch/alpha/stand/netboot/if_prom.c | 92 +++++-- sys/arch/alpha/stand/netboot/version | 12 +- sys/arch/alpha/stand/setnetbootinfo/Makefile | 15 ++ .../stand/setnetbootinfo/setnetbootinfo.8 | 128 +++++++++ .../stand/setnetbootinfo/setnetbootinfo.c | 249 ++++++++++++++++++ 30 files changed, 1005 insertions(+), 272 deletions(-) create mode 100644 sys/arch/alpha/stand/libkern/Makefile create mode 100644 sys/arch/alpha/stand/libkern/Makefile.inc create mode 100644 sys/arch/alpha/stand/libsa/Makefile create mode 100644 sys/arch/alpha/stand/libsa/Makefile.inc create mode 100644 sys/arch/alpha/stand/libz/Makefile create mode 100644 sys/arch/alpha/stand/libz/Makefile.inc create mode 100644 sys/arch/alpha/stand/setnetbootinfo/Makefile create mode 100644 sys/arch/alpha/stand/setnetbootinfo/setnetbootinfo.8 create mode 100644 sys/arch/alpha/stand/setnetbootinfo/setnetbootinfo.c diff --git a/sys/arch/alpha/stand/Makefile b/sys/arch/alpha/stand/Makefile index e2b081bc13b..bd0fd566147 100644 --- a/sys/arch/alpha/stand/Makefile +++ b/sys/arch/alpha/stand/Makefile @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile,v 1.4 1996/10/30 22:40:26 niklas Exp $ -# $NetBSD: Makefile,v 1.4 1996/09/23 04:28:23 cgd Exp $ +# $OpenBSD: Makefile,v 1.5 1997/05/05 06:01:44 millert Exp $ +# $NetBSD: Makefile,v 1.7 1997/04/10 23:03:38 cgd Exp $ -SUBDIR= boot bootxx installboot netboot +SUBDIR= boot bootxx installboot netboot setnetbootinfo .include diff --git a/sys/arch/alpha/stand/Makefile.inc b/sys/arch/alpha/stand/Makefile.inc index 351d0e2ef81..3c958d54528 100644 --- a/sys/arch/alpha/stand/Makefile.inc +++ b/sys/arch/alpha/stand/Makefile.inc @@ -1,17 +1,23 @@ -# $OpenBSD: Makefile.inc,v 1.3 1996/10/30 22:40:27 niklas Exp $ -# $NetBSD: Makefile.inc,v 1.3 1996/10/06 18:32:22 cgd Exp $ +# $OpenBSD: Makefile.inc,v 1.4 1997/05/05 06:01:45 millert Exp $ +# $NetBSD: Makefile.inc,v 1.8 1997/04/06 08:39:38 cgd Exp $ .include # for ELF_TOOLCHAIN definition BINDIR= /usr/mdec -PRIMARY_LOAD_ADDRESS= 20000000 -SECONDARY_LOAD_ADDRESS= 20020000 +# For descriptions of regions available to bootstrap programs, see +# section 3.4.1.2 (pp. III 3-14 - III 3-18) of the second edition of +# the Alpha AXP Architecture Reference Manual. + +PRIMARY_LOAD_ADDRESS= 20000000 # "Region 1 start" +SECONDARY_LOAD_ADDRESS= 20004000 # "Region 1 start" + 32k +HEAP_LIMIT= 20040000 # "Region 1 start" + 256k CPPFLAGS+= -DPRIMARY_LOAD_ADDRESS="0x${PRIMARY_LOAD_ADDRESS}" CPPFLAGS+= -DSECONDARY_LOAD_ADDRESS="0x${SECONDARY_LOAD_ADDRESS}" +XCPPFLAGS+= -DHEAP_LIMIT="0x${HEAP_LIMIT}" + .if !defined(ELF_TOOLCHAIN) CPPFLAGS+= -DECOFF_COMPAT .endif - diff --git a/sys/arch/alpha/stand/bbinfo.h b/sys/arch/alpha/stand/bbinfo.h index ee15a99b7aa..dd3b68d991a 100644 --- a/sys/arch/alpha/stand/bbinfo.h +++ b/sys/arch/alpha/stand/bbinfo.h @@ -1,5 +1,5 @@ -/* $OpenBSD: bbinfo.h,v 1.4 1996/10/30 22:40:28 niklas Exp $ */ -/* $NetBSD: bbinfo.h,v 1.2 1996/04/12 06:09:34 cgd Exp $ */ +/* $OpenBSD: bbinfo.h,v 1.5 1997/05/05 06:01:45 millert Exp $ */ +/* $NetBSD: bbinfo.h,v 1.2 1997/04/06 08:40:57 cgd Exp $ */ /* * Copyright (c) 1995, 1996 Carnegie-Mellon University. @@ -29,15 +29,27 @@ */ struct bbinfoloc { - u_int64_t magic1; - u_int64_t start; - u_int64_t end; - u_int64_t magic2; + u_int64_t magic1; + u_int64_t start; + u_int64_t end; + u_int64_t pad1[4]; + u_int64_t magic2; }; struct bbinfo { - int32_t cksum; - int32_t nblocks; - int32_t bsize; - int32_t blocks[1]; + int32_t cksum; + int32_t nblocks; + int32_t bsize; + int32_t pad1[8]; + int32_t blocks[1]; +}; + +struct netbbinfo { + u_int64_t magic1; + u_int8_t set; + u_int8_t ether_addr[6]; + u_int8_t force; + u_int64_t pad1[4]; + u_int64_t cksum; + u_int64_t magic2; }; diff --git a/sys/arch/alpha/stand/boot/Makefile b/sys/arch/alpha/stand/boot/Makefile index a4dc4aa2df2..46c63dfc077 100644 --- a/sys/arch/alpha/stand/boot/Makefile +++ b/sys/arch/alpha/stand/boot/Makefile @@ -1,55 +1,65 @@ -# $OpenBSD: Makefile,v 1.7 1997/04/05 04:26:54 millert Exp $ -# $NetBSD: Makefile,v 1.10 1996/10/18 06:01:41 thorpej Exp $ +# $OpenBSD: Makefile,v 1.8 1997/05/05 06:01:50 millert Exp $ +# $NetBSD: Makefile,v 1.17 1997/04/17 07:27:46 thorpej Exp $ -.PATH: ${.CURDIR}/.. ${.CURDIR}/../../../../lib/libsa +S= ${.CURDIR}/../../../.. -BOOT_PROG = boot -BOOT_RELOC = ${SECONDARY_LOAD_ADDRESS} +.PATH: ${.CURDIR}/.. -BOOT_SRCS = start.S boot.c loadfile.c disk.c conf.c prom.c prom_disp.S OSFpal.c +PROG = boot -BOOT_SRCS+= alloc.c bzero.c close.c dev.c devopen.c disklabel.c dkcksum.c -BOOT_SRCS+= getfile.c gets.c ioctl.c lseek.c open.c printf.c read.c -BOOT_SRCS+= strcmp.c ufs.c write.c filesystem.c strlen.c -BOOT_SRCS+= ntohl.c prom_swpal.S -BOOT_OBJS = ${BOOT_SRCS:N*.h:R:S/$/.o/g} +SRCS = start.S boot.c loadfile.c disk.c conf.c prom.c prom_disp.S OSFpal.c +SRCS+= devopen.c filesystem.c prom_swpal.S +NOMAN= +INSTALL_STRIP= +BINMODE= 444 +BOOT_RELOC = ${SECONDARY_LOAD_ADDRESS} HEADERSIZE_PROG = headersize +CLEANFILES+= vers.c vers.o ${PROG}.sym ${PROG}.nosym ${HEADERSIZE_PROG} + DEFNS= -DCOMPAT_UFS -DALPHA_BOOT_ECOFF # -DALPHA_BOOT_ELF AFLAGS += -DASSEMBLER ${DEFNS} -CPPFLAGS += -I${.CURDIR}/../.. -I${.CURDIR}/../../../.. -I${.CURDIR}/../../../../lib/libsa -CFLAGS = -Werror -mno-fp-regs -g ${DEFNS} +CPPFLAGS += -I${.CURDIR}/../.. -I${S} ${DEFNS} +CFLAGS = -Werror -mno-fp-regs + +${PROG}.nosym: ${PROG}.sym + cp ${PROG}.sym ${PROG}.nosym + strip ${PROG}.nosym + +${PROG}: ${PROG}.nosym ${HEADERSIZE_PROG} + dd if=${PROG}.nosym of=${PROG} \ + bs=`./${HEADERSIZE_PROG} ${BOOT_RELOC} ${PROG}.nosym` skip=1 + +# no lint here (yet?) +lint: + +.include -CLEANFILES+= vers.c vers.o +### find out what to use for libkern +KERN_AS= library +KERNDST= ${.CURDIR}/../libkern/${__objdir} +.include "${.CURDIR}/../libkern/Makefile.inc" +LIBKERN= ${KERNLIB} -.PATH: ${.CURDIR}/../../../../lib/libkern +### find out what to use for libz +Z_AS= library +ZDST= ${.CURDIR}/../libz/${__objdir} +.include "${.CURDIR}/../libz/Makefile.inc" +LIBZ= ${ZLIB} -all: ${BOOT_PROG} +### find out what to use for libsa +SA_AS= library +SADST= ${.CURDIR}/../libsa/${__objdir} +SAREL= +SA_ZLIB= yes +.include "${.CURDIR}/../libsa/Makefile.inc" +LIBSA= ${SALIB} -${BOOT_PROG}: ${BOOT_OBJS} ${HEADERSIZE_PROG} +${PROG}.sym: ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN} sh ${.CURDIR}/newvers.sh ${.CURDIR}/version ${COMPILE.c} vers.c - ${LD} -Ttext ${BOOT_RELOC} -N -e start -o ${BOOT_PROG}.hdr \ - ${BOOT_OBJS} vers.o -lc # XXX - size ${BOOT_PROG}.hdr - strip ${BOOT_PROG}.hdr - dd if=${BOOT_PROG}.hdr of=${BOOT_PROG} \ - bs=`./${HEADERSIZE_PROG} ${BOOT_RELOC} ${BOOT_PROG}.hdr` skip=1 - -install: - ${INSTALL} -c -o bin -g bin -m 444 ${BOOT_PROG} \ - ${DESTDIR}${BINDIR}/${BOOT_PROG} - -clean: _SUBDIRUSE - rm -f a.out [Ee]rrs mklog core *.core \ - ${BOOT_PROG} ${BOOT_OBJS} ${CLEANFILES} \ - ${BOOT_PROG}.hdr ${HEADERSIZE_PROG} - -cleandir: _SUBDIRUSE clean - -.include "${.CURDIR}/../Makefile.inc" -.include -.include -.include + ${LD} -Ttext ${BOOT_RELOC} -N -e start -o ${PROG}.sym \ + ${OBJS} vers.o ${LIBSA} ${LIBZ} ${LIBSA} ${LIBKERN} + size ${PROG}.sym diff --git a/sys/arch/alpha/stand/boot/boot.c b/sys/arch/alpha/stand/boot/boot.c index 2ddaef27e5d..5af7bdb9274 100644 --- a/sys/arch/alpha/stand/boot/boot.c +++ b/sys/arch/alpha/stand/boot/boot.c @@ -1,5 +1,5 @@ -/* $OpenBSD: boot.c,v 1.8 1996/11/27 19:54:52 niklas Exp $ */ -/* $NetBSD: boot.c,v 1.8 1996/09/17 22:00:26 cgd Exp $ */ +/* $OpenBSD: boot.c,v 1.9 1997/05/05 06:01:51 millert Exp $ */ +/* $NetBSD: boot.c,v 1.10 1997/01/18 01:58:33 cgd Exp $ */ /* * Copyright (c) 1992, 1993 @@ -61,10 +61,22 @@ extern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[]; vm_offset_t ffp_save, ptbr_save; +int debug; + +char *kernelnames[] = { + "bsd", + "bsd.bak", + "bsd.old", + "obsd", + NULL +}; + void main() { + char *name, **namep; u_int64_t entry; + int win; /* Init prom callback vector. */ init_prom_calls(); @@ -83,13 +95,20 @@ main() prom_getenv(PROM_E_BOOTED_FILE, boot_file, sizeof(boot_file)); prom_getenv(PROM_E_BOOTED_OSFLAGS, boot_flags, sizeof(boot_flags)); - if (boot_file[0] == '\0') - bcopy("bsd", boot_file, sizeof "bsd"); + if (boot_file[0] != 0) + (void)printf("Boot file: %s\n", boot_file); + (void)printf("Boot flags: %s\n", boot_flags); - (void)printf("Boot: %s %s\n", boot_file, boot_flags); + if (boot_file[0] != '\0') + win = (loadfile(name = boot_file, &entry) == 0); + else + for (namep = kernelnames, win = 0; *namep != NULL && !win; + namep++) + win = (loadfile(name = *namep, &entry) == 0); - if (!loadfile(boot_file, &entry)) { - (void)printf("Entering kernel at 0x%lx...\n", entry); + printf("\n"); + if (win) { + (void)printf("Entering %s at 0x%lx...\n", name, entry); (*(void (*)())entry)(ffp_save, ptbr_save, 0); } diff --git a/sys/arch/alpha/stand/boot/devopen.c b/sys/arch/alpha/stand/boot/devopen.c index 2e9cbc1951d..fc6de09d56c 100644 --- a/sys/arch/alpha/stand/boot/devopen.c +++ b/sys/arch/alpha/stand/boot/devopen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: devopen.c,v 1.3 1996/10/30 22:40:41 niklas Exp $ */ +/* $OpenBSD: devopen.c,v 1.4 1997/05/05 06:01:51 millert Exp $ */ /* $NetBSD: devopen.c,v 1.1 1995/11/23 02:39:37 cgd Exp $ */ /*- @@ -89,10 +89,6 @@ devopen(f, fname, file) cp++; } *ncp = '\0'; - /* - * XXX - * pulling strchr from the C library, should pull from libkern. - */ } else if (strchr(cp, '(')) { /* expect a string like 'rz(0,0,0)vmunix' */ while ((c = *cp) != '\0') { diff --git a/sys/arch/alpha/stand/boot/disk.c b/sys/arch/alpha/stand/boot/disk.c index 05d1c348068..73406487228 100644 --- a/sys/arch/alpha/stand/boot/disk.c +++ b/sys/arch/alpha/stand/boot/disk.c @@ -1,5 +1,5 @@ -/* $OpenBSD: disk.c,v 1.6 1997/04/07 06:23:10 millert Exp $ */ -/* $NetBSD: disk.c,v 1.3 1995/11/23 02:39:40 cgd Exp $ */ +/* $OpenBSD: disk.c,v 1.7 1997/05/05 06:01:52 millert Exp $ */ +/* $NetBSD: disk.c,v 1.6 1997/04/06 08:40:33 cgd Exp $ */ /* * Copyright (c) 1992, 1993 @@ -104,12 +104,7 @@ diskopen(f, ctlr, unit, part) size_t cnt; int devlen, i; char *msg, buf[DEV_BSIZE], devname[32]; - static struct disk_softc *sc; - - if (sc != NULL) { - f->f_devdata = (void *)sc; - return 0; - } + struct disk_softc *sc; if (unit >= 8 || part >= MAXPARTITIONS) return (ENXIO); @@ -148,6 +143,12 @@ diskopen(f, ctlr, unit, part) if (i || cnt != DEV_BSIZE) { printf("disk%d: error reading disk label\n", unit); goto bad; + } else if (lp->d_magic != DISKMAGIC) { + /* No label at all. Fake all partitions as whole disk. */ + for (i = 0; i < MAXPARTITIONS; i++) { + lp->d_partitions[part].p_offset = 0; + lp->d_partitions[part].p_size = 0x7fffffff; + } } else { msg = getdisklabel(buf, lp); if (msg) { diff --git a/sys/arch/alpha/stand/boot/filesystem.c b/sys/arch/alpha/stand/boot/filesystem.c index 1956f3504fa..25be97d2685 100644 --- a/sys/arch/alpha/stand/boot/filesystem.c +++ b/sys/arch/alpha/stand/boot/filesystem.c @@ -1,5 +1,5 @@ -/* $OpenBSD: filesystem.c,v 1.3 1996/10/30 22:40:43 niklas Exp $ */ -/* $NetBSD: filesystem.c,v 1.1 1995/11/23 02:39:46 cgd Exp $ */ +/* $OpenBSD: filesystem.c,v 1.4 1997/05/05 06:01:52 millert Exp $ */ +/* $NetBSD: filesystem.c,v 1.3 1997/04/06 08:40:35 cgd Exp $ */ /* * Copyright (c) 1993 Philip A. Nelson. @@ -36,10 +36,11 @@ #include #include +#include struct fs_ops file_system[] = { { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat }, + { cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek, cd9660_stat }, }; int nfsys = sizeof(file_system)/sizeof(struct fs_ops); - diff --git a/sys/arch/alpha/stand/boot/version b/sys/arch/alpha/stand/boot/version index 4343db37627..b502ad108f2 100644 --- a/sys/arch/alpha/stand/boot/version +++ b/sys/arch/alpha/stand/boot/version @@ -1,5 +1,5 @@ -$OpenBSD: version,v 1.5 1996/10/30 22:40:47 niklas Exp $ -$NetBSD: version,v 1.6 1996/06/14 20:03:07 cgd Exp $ +$OpenBSD: version,v 1.6 1997/05/05 06:01:53 millert Exp $ +$NetBSD: version,v 1.9 1997/01/23 23:10:38 cgd Exp $ 1.1: Initial version 1.2: don't forget the Id string! @@ -10,3 +10,6 @@ $NetBSD: version,v 1.6 1996/06/14 20:03:07 cgd Exp $ 1.6: Don't pass arguments to the kernel, trim unnecessary environment calls, kill 'ask' loop (i.e. if boot fails, halt), seperate ECOFF and a.out support into seperate options. +1.7: Use libsa and libkern rather than building the objects locally. +1.8: Search for a kernel, if none specified. +1.9: Add support for gzipped kernels. diff --git a/sys/arch/alpha/stand/bootxx.c b/sys/arch/alpha/stand/bootxx.c index 6e10ef53afa..09f1249e4ba 100644 --- a/sys/arch/alpha/stand/bootxx.c +++ b/sys/arch/alpha/stand/bootxx.c @@ -1,5 +1,5 @@ -/* $OpenBSD: bootxx.c,v 1.6 1996/11/27 19:54:47 niklas Exp $ */ -/* $NetBSD: bootxx.c,v 1.3 1996/06/14 20:04:45 cgd Exp $ */ +/* $OpenBSD: bootxx.c,v 1.7 1997/05/05 06:01:46 millert Exp $ */ +/* $NetBSD: bootxx.c,v 1.4 1997/01/18 00:28:59 cgd Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. @@ -40,6 +40,7 @@ struct bbinfoloc desc = { 0xbabefacedeadbeef, (u_int64_t)&start, (u_int64_t)&_end, + { 0, }, 0xdeadbeeffacebabe }; @@ -82,7 +83,7 @@ load_file(bbinfop, loadaddr) puts("invalid number of blocks in boot program description\n"); return 0; } - if (bbinfop->bsize < 4096 || bbinfop->bsize > MAXBSIZE) { + if (bbinfop->bsize < DEV_BSIZE || bbinfop->bsize > MAXBSIZE) { puts("invalid block size in boot program description\n"); return 0; } diff --git a/sys/arch/alpha/stand/bootxx/Makefile b/sys/arch/alpha/stand/bootxx/Makefile index f2a724efda2..47e2f85db19 100644 --- a/sys/arch/alpha/stand/bootxx/Makefile +++ b/sys/arch/alpha/stand/bootxx/Makefile @@ -1,45 +1,49 @@ -# $OpenBSD: Makefile,v 1.4 1996/10/30 22:40:48 niklas Exp $ -# $NetBSD: Makefile,v 1.6 1996/10/18 06:02:02 thorpej Exp $ +# $OpenBSD: Makefile,v 1.5 1997/05/05 06:01:53 millert Exp $ +# $NetBSD: Makefile,v 1.12 1997/04/17 07:27:49 thorpej Exp $ -.PATH: ${.CURDIR}/.. ${.CURDIR}/../../../../lib/libsa +S= ${.CURDIR}/../../../.. -BOOT_PROG = bootxx -BOOT_RELOC = ${PRIMARY_LOAD_ADDRESS} +.PATH: ${.CURDIR}/.. + +PROG = bootxx -BOOT_SRCS = start.S bootxx.c prom.c prom_disp.S bzero.c puts.c -BOOT_OBJS = ${BOOT_SRCS:N*.h:R:S/$/.o/g} +SRCS = start.S bootxx.c prom.c prom_disp.S puts.c +NOMAN= +INSTALL_STRIP= +BINMODE= 444 +BOOT_RELOC = ${PRIMARY_LOAD_ADDRESS} HEADERSIZE_PROG = headersize -AFLAGS += -DASSEMBLER -CPPFLAGS += -I${.CURDIR}/../.. -I${.CURDIR}/../../../.. -DPRIMARY_BOOTBLOCK -CFLAGS = -Werror -mno-fp-regs -g +CLEANFILES+= ${PROG}.sym ${PROG}.nosym ${HEADERSIZE_PROG} + +DEFNS= -DPRIMARY_BOOTBLOCK -.PATH: ${.CURDIR}/../../../../lib/libkern +AFLAGS += -DASSEMBLER ${DEFNS} +CPPFLAGS += -I${.CURDIR}/../.. -I${S} ${DEFNS} +CFLAGS = -Werror -mno-fp-regs -all: ${BOOT_PROG} +${PROG}.nosym: ${PROG}.sym + cp ${PROG}.sym ${PROG}.nosym + strip ${PROG}.nosym -${BOOT_PROG}: ${BOOT_OBJS} ${HEADERSIZE_PROG} - ${LD} -Ttext ${BOOT_RELOC} -N -e start -o ${BOOT_PROG}.hdr \ - ${BOOT_OBJS} - size ${BOOT_PROG}.hdr - strip ${BOOT_PROG}.hdr - dd if=${BOOT_PROG}.hdr of=${BOOT_PROG}.nohdr \ - bs=`./${HEADERSIZE_PROG} ${BOOT_RELOC} ${BOOT_PROG}.hdr` skip=1 - dd if=${BOOT_PROG}.nohdr of=${BOOT_PROG} bs=`expr 15 \* 512` conv=sync +${PROG}: ${PROG}.nosym ${HEADERSIZE_PROG} + dd if=${PROG}.nosym of=${PROG} \ + ibs=`./${HEADERSIZE_PROG} ${BOOT_RELOC} ${PROG}.nosym` skip=1 \ + obs=`expr 15 \* 512` conv=osync -install: - ${INSTALL} -c -o bin -g bin -m 444 ${BOOT_PROG} \ - ${DESTDIR}${BINDIR}/${BOOT_PROG} +# no lint here (yet?) +lint: -clean: _SUBDIRUSE - rm -f a.out [Ee]rrs mklog core *.core \ - ${BOOT_PROG} ${BOOT_OBJS} ${CLEANFILES} \ - ${BOOT_PROG}.hdr ${BOOT_PROG}.nohdr ${HEADERSIZE_PROG} +.include -cleandir: _SUBDIRUSE clean +### find out what to use for libkern +KERN_AS= library +KERNDST= ${.CURDIR}/../libkern/${__objdir} +.include "${.CURDIR}/../libkern/Makefile.inc" +LIBKERN= ${KERNLIB} -.include "${.CURDIR}/../Makefile.inc" -.include -.include -.include +${PROG}.sym: ${OBJS} ${LIBKERN} + ${LD} -Ttext ${BOOT_RELOC} -N -e start -o ${PROG}.sym ${OBJS} \ + ${LIBKERN} + size ${PROG}.sym diff --git a/sys/arch/alpha/stand/installboot.8 b/sys/arch/alpha/stand/installboot.8 index 98e49fbd0b3..f0e52b98598 100644 --- a/sys/arch/alpha/stand/installboot.8 +++ b/sys/arch/alpha/stand/installboot.8 @@ -1,7 +1,7 @@ -.\" $OpenBSD: installboot.8,v 1.2 1997/04/07 05:23:33 millert Exp $ -.\" $NetBSD: installboot.8,v 1.1 1996/11/06 23:07:55 cgd Exp $ +.\" $OpenBSD: installboot.8,v 1.3 1997/05/05 06:01:47 millert Exp $ +.\" $NetBSD: installboot.8,v 1.2 1997/04/06 08:41:11 cgd Exp $ .\" -.\" Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. +.\" Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. .\" Copyright (c) 1995 Paul Kranenburg .\" All rights reserved. .\" @@ -30,22 +30,22 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd November 6, 1996 +.Dd January 16, 1997 .Dt INSTALLBOOT 8 .Os .Sh NAME .Nm installboot -.Nd install bootstrap software on an FFS partition +.Nd install disk bootstrap software .Sh SYNOPSIS .Nm installboot .Op Fl nv .Ar boot .Ar bootxx -.Ar device +.Ar rawdiskdevice .Sh DESCRIPTION The .Nm installboot -utility prepares an FFS partition for bootstrapping. +utility prepares a disk for bootstrapping. .Pp The OpenBSD/alpha disk bootstrap software is split into two parts: a small first-stage boot program that is written into the disklabel @@ -90,38 +90,38 @@ Verbose mode. .El .Pp The arguments are: -.Bl -tag -width bootxx +.Bl -tag -width rawdiskdevice .It Ar boot The name of the second-stage boot program in the file system where the first-stage boot program is to be installed. .It Ar bootxx The name of the prototype file for the first-stage boot program. -.It Ar device -The name of the raw device in which the first-stage boot program -is to be installed. -This should be the raw device containing the file system -which holds -.Ar boot . +.It Ar rawdiskdevice +The name of the device corresponding to the raw whole-disk partition (the +.Dq raw partition ) +of the disk on which the first-stage boot program is to be installed. .El .Sh EXAMPLES -The following command will install the first-stage boot program in the -root filesystem -.Pq assumed to be mounted from Dq sd0a -using the file -.Pa /boot -as the second-stage boot program: +.Pa boot +resides in the FFS file system mounted on +.Pa / +from +.Dq sd0a , +you would install the first-stage boot program on the disk +(and therefore make the disk bootable) by using the command: .Bd -literal -offset indent -installboot /boot /usr/mdec/bootxx /dev/rsd0a +installboot /boot /usr/mdec/bootxx /dev/rsd0c .Ed .Sh BUGS -OpenBSD/alpha systems are only capable of booting off of disks' +The OpenBSD/alpha boot blocks can only load kernels from disks' .Dq a -partitions, and bootable partitions must start at the beginning -of the disk. +partitions. (However, the second-stage boot +program may be located on any FFS file system partition +on the disk.) .Pp .Nm Installboot requires simultaneous access to the mounted file system and -the raw device. +the disks' raw partition. That is not allowed with the kernel .Dv securelevel variable @@ -129,15 +129,11 @@ variable see .Xr sysctl 8 .Pc -set to a value greater than zero, so -.Nm installboot -only works when the system is in -an insecure mode (e.g. single-user mode; see -.Xr init 8 ). -Alternately, one can use the ``c'' partition of -the target device which avoids this problem since -the ``c'' partition spans the entire disk and -should not be mounted. +set to a value greater than one, or with +.Dv securelevel +set to one if the +.Dq boot +program resides in a file system on the disk's raw partition. .Sh "SEE ALSO" .Xr disklabel 8 , .Xr init 8 , diff --git a/sys/arch/alpha/stand/installboot.c b/sys/arch/alpha/stand/installboot.c index 49eb5d85b2a..c01835023a6 100644 --- a/sys/arch/alpha/stand/installboot.c +++ b/sys/arch/alpha/stand/installboot.c @@ -1,7 +1,8 @@ -/* $OpenBSD: installboot.c,v 1.6 1997/04/09 05:09:35 deraadt Exp $ */ -/* $NetBSD: installboot.c,v 1.2 1995/12/20 00:17:49 cgd Exp $ */ +/* $OpenBSD: installboot.c,v 1.7 1997/05/05 06:01:48 millert Exp $ */ +/* $NetBSD: installboot.c,v 1.2 1997/04/06 08:41:12 cgd Exp $ */ /* + * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved. * Copyright (c) 1994 Paul Kranenburg * All rights reserved. * @@ -39,12 +40,16 @@ #include #include #include +#include +#include #include +#include #include #include #include #include #include +#include #include "bbinfo.h" @@ -57,7 +62,7 @@ int max_block_count; char *loadprotoblocks __P((char *, long *)); -int loadblocknums __P((char *, int)); +int loadblocknums __P((char *, int, unsigned long)); static void devread __P((int, void *, daddr_t, size_t, char *)); static void usage __P((void)); int main __P((int, char *[])); @@ -66,7 +71,7 @@ int main __P((int, char *[])); static void usage() { - fprintf(stderr, + (void)fprintf(stderr, "usage: installboot [-n] [-v] \n"); exit(1); } @@ -82,8 +87,11 @@ main(argc, argv) long protosize; int mib[2]; size_t size; + struct stat disksb, bootsb; + struct disklabel dl; + unsigned long partoffset; - while ((c = getopt(argc, argv, "vn")) != -1) { + while ((c = getopt(argc, argv, "vn")) != EOF) { switch (c) { case 'n': /* Do not actually write the bootblock to disk */ @@ -107,9 +115,9 @@ main(argc, argv) dev = argv[optind + 2]; if (verbose) { - printf("boot: %s\n", boot); - printf("proto: %s\n", proto); - printf("device: %s\n", dev); + (void)printf("boot: %s\n", boot); + (void)printf("proto: %s\n", proto); + (void)printf("device: %s\n", dev); } /* Load proto blocks into core */ @@ -119,9 +127,46 @@ main(argc, argv) /* Open and check raw disk device */ if ((devfd = open(dev, O_RDONLY, 0)) < 0) err(1, "open: %s", dev); + if (fstat(devfd, &disksb) == -1) + err(1, "fstat: %s", dev); + if (!S_ISCHR(disksb.st_mode)) + errx(1, "%s must be a character device node", dev); + if ((minor(disksb.st_rdev) % getmaxpartitions()) != getrawpartition()) + errx(1, "%s must be the raw partition", dev); /* Extract and load block numbers */ - if (loadblocknums(boot, devfd) != 0) + if (stat(boot, &bootsb) == -1) + err(1, "stat: %s", boot); + if (!S_ISREG(bootsb.st_mode)) + errx(1, "%s must be a regular file", boot); + if ((minor(disksb.st_rdev) / getmaxpartitions()) != + (minor(bootsb.st_dev) / getmaxpartitions())) + errx(1, "%s must be somewhere on %s", boot, dev); + + /* + * Find the offset of the secondary boot block's partition + * into the disk. If disklabels not supported, assume zero. + */ + if (ioctl(devfd, DIOCGDINFO, &dl) != -1) { + partoffset = dl.d_partitions[minor(bootsb.st_dev) % + getmaxpartitions()].p_offset; + } else { + if (errno != ENOTTY) + err(1, "read disklabel: %s", dev); + warnx("couldn't read label from %s, using part offset of 0", + dev); + partoffset = 0; + } + if (verbose) + (void)printf("%s partition offset = 0x%lx\n", boot, partoffset); + + /* Sync filesystems (make sure boot's block numbers are stable) */ + sync(); + sleep(2); + sync(); + sleep(2); + + if (loadblocknums(boot, devfd, partoffset) != 0) exit(1); (void)close(devfd); @@ -141,10 +186,6 @@ main(argc, argv) if (lseek(devfd, DEV_BSIZE, SEEK_SET) != DEV_BSIZE) err(1, "lseek bootstrap"); - /* Sync filesystems (to clean in-memory superblock?) */ - sync(); - sleep(3); - if (write(devfd, protostore, protosize) != protosize) err(1, "write bootstrap"); @@ -249,11 +290,11 @@ loadprotoblocks(fname, size) ((char *)bbinfop->blocks - bp) / sizeof (bbinfop->blocks[0]); if (verbose) { - printf("boot block info locator at offset 0x%x\n", + (void)printf("boot block info locator at offset 0x%x\n", (char *)bbinfolocp - bp); - printf("boot block info at offset 0x%x\n", + (void)printf("boot block info at offset 0x%x\n", (char *)bbinfop - bp); - printf("max number of blocks: %d\n", max_block_count); + (void)printf("max number of blocks: %d\n", max_block_count); } *size = sz; @@ -278,9 +319,10 @@ devread(fd, buf, blk, size, msg) static char sblock[SBSIZE]; int -loadblocknums(boot, devfd) -char *boot; -int devfd; +loadblocknums(boot, devfd, partoffset) + char *boot; + int devfd; + unsigned long partoffset; { int i, fd; struct stat statbuf; @@ -314,7 +356,8 @@ int devfd; close(fd); /* Read superblock */ - devread(devfd, sblock, btodb(SBOFF), SBSIZE, "superblock"); + devread(devfd, sblock, btodb(SBOFF) + partoffset, SBSIZE, + "superblock"); fs = (struct fs *)sblock; /* Read inode */ @@ -322,7 +365,7 @@ int devfd; 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"); + devread(devfd, buf, blk + partoffset, fs->fs_bsize, "inode"); ip = (struct dinode *)(buf) + ino_to_fsbo(fs, statbuf.st_ino); /* @@ -343,16 +386,16 @@ int devfd; bbinfop->nblocks = ndb; if (verbose) - printf("%s: block numbers: ", boot); + (void)printf("%s: block numbers: ", boot); ap = ip->di_db; for (i = 0; i < NDADDR && *ap && ndb; i++, ap++, ndb--) { blk = fsbtodb(fs, *ap); - bbinfop->blocks[i] = blk; + bbinfop->blocks[i] = blk + partoffset; if (verbose) - printf("%d ", blk); + (void)printf("%d ", bbinfop->blocks[i]); } if (verbose) - printf("\n"); + (void)printf("\n"); if (ndb == 0) goto checksum; @@ -362,18 +405,19 @@ int devfd; * for more in the 1st-level bootblocks anyway. */ if (verbose) - printf("%s: block numbers (indirect): ", boot); + (void)printf("%s: block numbers (indirect): ", boot); blk = ip->di_ib[0]; - devread(devfd, buf, blk, fs->fs_bsize, "indirect block"); + devread(devfd, buf, blk + partoffset, fs->fs_bsize, + "indirect block"); ap = (daddr_t *)buf; for (; i < NINDIR(fs) && *ap && ndb; i++, ap++, ndb--) { blk = fsbtodb(fs, *ap); - bbinfop->blocks[i] = blk; + bbinfop->blocks[i] = blk + partoffset; if (verbose) - printf("%d ", blk); + (void)printf("%d ", bbinfop->blocks[i]); } if (verbose) - printf("\n"); + (void)printf("\n"); if (ndb) errx(1, "%s: Too many blocks", boot); diff --git a/sys/arch/alpha/stand/installboot/Makefile b/sys/arch/alpha/stand/installboot/Makefile index c2b837276ac..ab876f2740d 100644 --- a/sys/arch/alpha/stand/installboot/Makefile +++ b/sys/arch/alpha/stand/installboot/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.4 1996/12/08 00:20:54 niklas Exp $ +# $OpenBSD: Makefile,v 1.5 1997/05/05 06:01:54 millert Exp $ # $NetBSD: Makefile,v 1.2 1996/11/06 23:09:13 cgd Exp $ .PATH: ${.CURDIR}/.. @@ -9,6 +9,7 @@ BINDIR= /usr/mdec MAN= installboot.8 MANSUBDIR=/alpha -CFLAGS+= -g +DPADD+= ${LIBUTIL} +LDADD+= -lutil .include diff --git a/sys/arch/alpha/stand/libkern/Makefile b/sys/arch/alpha/stand/libkern/Makefile new file mode 100644 index 00000000000..87ff5fbe70a --- /dev/null +++ b/sys/arch/alpha/stand/libkern/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.1 1997/05/05 06:01:55 millert Exp $ + +.include +.include +.include diff --git a/sys/arch/alpha/stand/libkern/Makefile.inc b/sys/arch/alpha/stand/libkern/Makefile.inc new file mode 100644 index 00000000000..27c4fb0c431 --- /dev/null +++ b/sys/arch/alpha/stand/libkern/Makefile.inc @@ -0,0 +1,52 @@ +# $OpenBSD: Makefile.inc,v 1.1 1997/05/05 06:01:56 millert Exp $ +# $NetBSD: Makefile.inc,v 1.22 1996/09/30 15:54:35 ws Exp $ +# +# NOTE: $S must correspond to the top of the 'sys' tree + +KERNDIR= $S/lib/libkern + +KERNDST?= ${.OBJDIR}/lib/kern +KERN_AS?= obj + +.if (${KERN_AS} == "library") +KERNLIB= ${KERNDST}/libkern.a +KERNLIB_PROF= ${KERNDST}/libkern_p.a +.else +KERNLIB= ${KERNDST}/libkern.o +KERNLIB_PROF= ${KERNDST}/libkern.po +.endif + +KERNMAKE= \ + cd ${KERNDIR} && MAKEOBJDIR=${KERNDST} ${MAKE} \ + CC='${CC}' CFLAGS='${CFLAGS}' \ + AS='${AS}' AFLAGS='${AFLAGS}' \ + LD='${LD}' STRIP='${STRIP}' \ + MACHINE='${MACHINE}' MACHINE_ARCH='${MACHINE_ARCH}' \ + KERNCPPFLAGS='${CPPFLAGS:S@^-I.@-I../../.@g}' + +${KERNLIB}: .NOTMAIN __always_make_kernlib + @echo making sure the kern library is up to date... +.if (${KERN_AS} == "library") + @${KERNMAKE} libkern.a +.else + @${KERNMAKE} libkern.o +.endif + +${KERNLIB_PROF}: .NOTMAIN __always_make_kernlib + @echo making sure the profiled kern library is up to date... +.if (${KERN_AS} == "library") + @${KERNMAKE} libkern_p.a +.else + @${KERNMAKE} libkern.po +.endif + +clean: .NOTMAIN __always_make_kernlib + @echo cleaning the kern library objects + @${KERNMAKE} clean + +depend: .NOTMAIN __always_make_kernlib + @echo depending the kern library objects + @${KERNMAKE} depend + +__always_make_kernlib: .NOTMAIN + @mkdir -p ${KERNDST} diff --git a/sys/arch/alpha/stand/libsa/Makefile b/sys/arch/alpha/stand/libsa/Makefile new file mode 100644 index 00000000000..9ac4c9618dd --- /dev/null +++ b/sys/arch/alpha/stand/libsa/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.1 1997/05/05 06:01:57 millert Exp $ + +.include +.include +.include diff --git a/sys/arch/alpha/stand/libsa/Makefile.inc b/sys/arch/alpha/stand/libsa/Makefile.inc new file mode 100644 index 00000000000..6c4e21b9bca --- /dev/null +++ b/sys/arch/alpha/stand/libsa/Makefile.inc @@ -0,0 +1,41 @@ +# $OpenBSD: Makefile.inc,v 1.1 1997/05/05 06:01:57 millert Exp $ +# $NetBSD: Makefile.inc,v 1.5 1996/09/30 16:01:18 ws Exp $ +# +# NOTE: $S must correspond to the top of the 'sys' tree +SADIR= $S/lib/libsa + +SADST?= lib/sa +SAREL?= ../../ +SALIB?= ${SADST}/libsa.a + +SAMAKE= \ + cd ${SADST} && ${MAKE} -f ${SAREL}${SADIR}/Makefile \ + CC="${CC}" XCFLAGS="${CFLAGS}" \ + AS='${AS}' XAFLAGS='${AFLAGS}' \ + LD='${LD}' \ + XCPPFLAGS="${CPPFLAGS}" \ + SAREL="${SAREL}" \ + SADIR="${SADIR}" \ + EXTRACFLAGS="${EXTRACFLAGS}" +.if defined(NO_NET) +SAMAKE+= NO_NET="" +.endif +.if defined(SA_ZLIB) +SAMAKE+= SA_ZLIB="" +.endif + +${SALIB}: .NOTMAIN __always_make_salib + @echo making sure the stand-alone library is up to date... + @${SAMAKE} libsa.a + +clean: .NOTMAIN __always_make_salib + @echo cleaning the stand-alone library objects + @${SAMAKE} clean + +depend: .NOTMAIN __always_make_salib + @echo depending the standalone library objects + @${SAMAKE} depend + +__always_make_salib: .NOTMAIN + @([ -d ${SADST} ] || mkdir -p ${SADST}) + diff --git a/sys/arch/alpha/stand/libz/Makefile b/sys/arch/alpha/stand/libz/Makefile new file mode 100644 index 00000000000..48bcdedcd3a --- /dev/null +++ b/sys/arch/alpha/stand/libz/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.1 1997/05/05 06:01:58 millert Exp $ + +.include +.include +.include diff --git a/sys/arch/alpha/stand/libz/Makefile.inc b/sys/arch/alpha/stand/libz/Makefile.inc new file mode 100644 index 00000000000..205125fa1ff --- /dev/null +++ b/sys/arch/alpha/stand/libz/Makefile.inc @@ -0,0 +1,71 @@ +# $OpenBSD: Makefile.inc,v 1.1 1997/05/05 06:01:58 millert Exp $ +# $NetBSD: Makefile.inc,v 1.2 1997/01/23 22:29:09 cgd Exp $ +# +# Configuration variables (default values are below): +# +# S must be set to the top of the 'sys' tree. +# ZDST may be set to the location of the directory where library +# objects are to be built. Defaults to ${.OBJDIR}/lib/z. +# Z_AS may be set to 'obj' to build a object from the library's +# object files. (Otherwise, a library will be built.) +# Defaults to 'library'. +# ZMISCMAKEFLAGS +# Miscellaneous flags to be passed to the library's Makefile when +# building. See library's Makefile for more details about +# supported flags and their default values. + +# Default values: +ZDST?= ${.OBJDIR}/lib/z +Z_AS?= library + +ZDIR= $S/lib/libz +.if (${Z_AS} == "obj") +ZLIB= ${ZDST}/libz.o +ZLIB_PROF= ${ZDST}/libz.po +.else +ZLIB= ${ZDST}/libz.a +ZLIB_PROF= ${ZDST}/libz_p.a +.endif + +ZMAKE= \ + cd ${ZDIR} && MAKEOBJDIR=${ZDST} ${MAKE} \ + CC="${CC}" CFLAGS="${CFLAGS}" \ + AS=${AS} AFLAGS="${AFLAGS}" \ + LD=${LD} STRIP=${STRIP} \ + MACHINE=${MACHINE} MACHINE_ARCH=${MACHINE_ARCH} \ + ZCPPFLAGS="${CPPFLAGS:S@^-I.@-I../../.@g}" \ + ${ZMISCMAKEFLAGS} + +${ZLIB}: .NOTMAIN __always_make_zlib + @echo making sure the z library is up to date... +.if (${Z_AS} == "library") + ${ZMAKE} libz.a +.else + @${ZMAKE} libz.o +.endif + +${ZLIB_PROF}: .NOTMAIN __always_make_zlib + @echo making sure the profiled z library is up to date... +.if (${Z_AS} == "library") + @${ZMAKE} libz_p.a +.else + @${ZMAKE} libz.po +.endif + +clean: .NOTMAIN cleanzlib +cleanzlib: .NOTMAIN __always_make_zlib + @echo cleaning the z library objects + @${ZMAKE} clean + +cleandir: .NOTMAIN cleandirzlib +cleandirzlib: .NOTMAIN __always_make_zlib + @echo cleandiring the z library objects + @${ZMAKE} cleandir + +depend: .NOTMAIN dependzlib +dependzlib: .NOTMAIN __always_make_zlib + @echo depending the z library objects + @${ZMAKE} depend + +__always_make_zlib: .NOTMAIN + @mkdir -p ${ZDST} diff --git a/sys/arch/alpha/stand/loadfile.c b/sys/arch/alpha/stand/loadfile.c index 2dcf316f252..63951062504 100644 --- a/sys/arch/alpha/stand/loadfile.c +++ b/sys/arch/alpha/stand/loadfile.c @@ -1,5 +1,5 @@ -/* $OpenBSD: loadfile.c,v 1.2 1996/11/27 19:54:48 niklas Exp $ */ -/* $NetBSD: loadfile.c,v 1.3 1996/09/23 04:32:44 cgd Exp $ */ +/* $OpenBSD: loadfile.c,v 1.3 1997/05/05 06:01:49 millert Exp $ */ +/* $NetBSD: loadfile.c,v 1.3 1997/04/06 08:40:59 cgd Exp $ */ /* * Copyright (c) 1992, 1993 @@ -85,16 +85,18 @@ loadfile(fname, entryp) ssize_t nr; int fd, rval; + (void)printf("\nLoading %s...\n", fname); + /* Open the file. */ rval = 1; if ((fd = open(fname, 0)) < 0) { - (void)printf("open %s: error %d\n", fname, errno); + (void)printf("open %s: %s\n", fname, strerror(errno)); goto err; } /* Read the exec header. */ if ((nr = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) { - (void)printf("read header: error %d\n", errno); + (void)printf("read header: %s\n", strerror(errno)); goto err; } @@ -131,7 +133,7 @@ coff_exec(fd, coff, entryp) (void)lseek(fd, ECOFF_TXTOFF(coff), 0); if (read(fd, (void *)coff->a.text_start, coff->a.tsize) != coff->a.tsize) { - (void)printf("read text: %d\n", errno); + (void)printf("read text: %s\n", strerror(errno)); return (1); } @@ -140,7 +142,7 @@ coff_exec(fd, coff, entryp) (void)printf("+%lu", coff->a.dsize); if (read(fd, (void *)coff->a.data_start, coff->a.dsize) != coff->a.dsize) { - (void)printf("read data: %d\n", errno); + (void)printf("read data: %s\n", strerror(errno)); return (1); } } @@ -180,7 +182,7 @@ elf_exec(fd, elf, entryp) Elf_Phdr phdr; (void)lseek(fd, elf->e_phoff + sizeof(phdr) * i, 0); if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) { - (void)printf("read phdr: %d\n", errno); + (void)printf("read phdr: %s\n", strerror(errno)); return (1); } if (phdr.p_type != Elf_pt_load || @@ -192,7 +194,7 @@ elf_exec(fd, elf, entryp) (void)lseek(fd, phdr.p_offset, 0); if (read(fd, (void *)phdr.p_vaddr, phdr.p_filesz) != phdr.p_filesz) { - (void)printf("read text: %d\n", errno); + (void)printf("read text: %s\n", strerror(errno)); return (1); } if (first || ffp_save < phdr.p_vaddr + phdr.p_memsz) diff --git a/sys/arch/alpha/stand/netboot/Makefile b/sys/arch/alpha/stand/netboot/Makefile index d05d684b225..359b6be7d00 100644 --- a/sys/arch/alpha/stand/netboot/Makefile +++ b/sys/arch/alpha/stand/netboot/Makefile @@ -1,61 +1,67 @@ -# $OpenBSD: Makefile,v 1.2 1996/11/27 19:54:54 niklas Exp $ -# $NetBSD: Makefile,v 1.3 1996/10/18 06:02:24 thorpej Exp $ +# $OpenBSD: Makefile,v 1.3 1997/05/05 06:01:59 millert Exp $ +# $NetBSD: Makefile,v 1.11 1997/04/17 07:27:50 thorpej Exp $ -.PATH: ${.CURDIR}/.. ${.CURDIR}/../../../../lib/libsa +S= ${.CURDIR}/../../../.. + +.PATH: ${.CURDIR}/.. ${.CURDIR}/../boot + +PROG = netboot + +SRCS = start.S boot.c prom.c prom_disp.S OSFpal.c prom_swpal.S +SRCS+= rpcc.S +SRCS+= dev_net.c conf.c devopen.c +SRCS+= if_prom.c loadfile.c getsecs.c +NOMAN= +INSTALL_STRIP= +BINMODE= 444 -BOOT_PROG = netboot BOOT_RELOC = ${PRIMARY_LOAD_ADDRESS} +HEADERSIZE_PROG = headersize -BOOT_SRCS = start.S netboot.c prom.c prom_disp.S OSFpal.c prom_swpal.S -BOOT_SRCS+= printf.c bzero.c rpcc.S +CLEANFILES+= vers.c vers.o ${PROG}.sym ${PROG}.nosym ${HEADERSIZE_PROG} -BOOT_SRCS+= dev_net.c conf.c devopen.c -BOOT_SRCS+= nfs.c rpc.c alloc.c ntohl.c htonl.c ntohs.c htons.c net.c bootp.c -BOOT_SRCS+= strlen.c dev.c bcmp.c strerror.c rarp.c read.c lseek.c -BOOT_SRCS+= in_cksum.c exit.c closeall.c arp.c strncpy.c globals.c open.c -BOOT_SRCS+= close.c ether.c netif.c +DEFNS= -DPRIMARY_BOOTBLOCK -DALPHA_BOOT_ECOFF # -DALPHA_BOOT_ELF -BOOT_SRCS+= if_prom.c loadfile.c getsecs.c +AFLAGS += -DASSEMBLER ${DEFNS} +CPPFLAGS += -I${.CURDIR}/../.. -I${S} ${DEFNS} +CFLAGS = -Werror -mno-fp-regs -BOOT_OBJS = ${BOOT_SRCS:N*.h:R:S/$/.o/g} +${PROG}.nosym: ${PROG}.sym + cp ${PROG}.sym ${PROG}.nosym + strip ${PROG}.nosym -HEADERSIZE_PROG = headersize +${PROG}: ${PROG}.nosym ${HEADERSIZE_PROG} + dd if=${PROG}.nosym of=${PROG} \ + bs=`./${HEADERSIZE_PROG} ${BOOT_RELOC} ${PROG}.nosym` skip=1 + +# no lint here (yet?) +lint: -AFLAGS += -DASSEMBLER -CPPFLAGS += -I${.CURDIR}/../../../../ \ - -I${.CURDIR}/../../../../lib/libsa \ - -I${.CURDIR}/../.. -DPRIMARY_BOOTBLOCK \ - -DALPHA_BOOT_ECOFF # -DALPHA_BOOT_ELF -CFLAGS = -Werror -mno-fp-regs -g +.include -CLEANFILES+= vers.c vers.o +### find out what to use for libkern +KERN_AS= library +KERNDST= ${.CURDIR}/../libkern/${__objdir} +.include "${.CURDIR}/../libkern/Makefile.inc" +LIBKERN= ${KERNLIB} -.PATH: ${.CURDIR} ${.CURDIR}/../../../../lib/libkern ${.CURDIR}/../boot +### find out what to use for libz +Z_AS= library +ZDST= ${.CURDIR}/../libz/${__objdir} +.include "${.CURDIR}/../libz/Makefile.inc" +LIBZ= ${ZLIB} -all: ${BOOT_PROG} +### find out what to use for libsa +SA_AS= library +SADST= ${.CURDIR}/../libsa/${__objdir} +SAREL= +SA_ZLIB= yes +.include "${.CURDIR}/../libsa/Makefile.inc" +LIBSA= ${SALIB} -${BOOT_PROG}: ${BOOT_OBJS} ${HEADERSIZE_PROG} +${PROG}.sym: ${OBJS} ${LIBSA} ${LIBZ} ${LIBKERN} sh ${.CURDIR}/newvers.sh ${.CURDIR}/version ${COMPILE.c} vers.c - ${LD} -Ttext ${BOOT_RELOC} -N -e start -o ${BOOT_PROG}.hdr \ - ${BOOT_OBJS} vers.o -lc # XXX - size ${BOOT_PROG}.hdr - strip ${BOOT_PROG}.hdr - dd if=${BOOT_PROG}.hdr of=${BOOT_PROG} \ - bs=`./${HEADERSIZE_PROG} ${BOOT_RELOC} ${BOOT_PROG}.hdr` skip=1 - -install: - ${INSTALL} -c -o bin -g bin -m 444 ${BOOT_PROG} \ - ${DESTDIR}${BINDIR}/${BOOT_PROG} - -clean: _SUBDIRUSE - rm -f a.out [Ee]rrs mklog core *.core \ - ${BOOT_PROG} ${BOOT_OBJS} ${CLEANFILES} \ - ${BOOT_PROG}.hdr ${BOOT_PROG}.nohdr ${HEADERSIZE_PROG} - -cleandir: _SUBDIRUSE clean - -.include "${.CURDIR}/../Makefile.inc" -.include -.include -.include + ${LD} -Ttext ${BOOT_RELOC} -N -e start -o ${PROG}.sym \ + ${OBJS} vers.o ${LIBSA} ${LIBZ} ${LIBSA} ${LIBKERN} + size ${PROG}.sym diff --git a/sys/arch/alpha/stand/netboot/conf.c b/sys/arch/alpha/stand/netboot/conf.c index b40ffacf7be..119928698cc 100644 --- a/sys/arch/alpha/stand/netboot/conf.c +++ b/sys/arch/alpha/stand/netboot/conf.c @@ -1,11 +1,11 @@ -/* $OpenBSD: conf.c,v 1.1 1996/10/30 22:40:52 niklas Exp $ */ -/* $NetBSD: conf.c,v 1.2 1996/10/02 21:18:45 cgd Exp $ */ +/* $OpenBSD: conf.c,v 1.2 1997/05/05 06:01:59 millert Exp $ */ +/* $NetBSD: conf.c,v 1.4 1997/04/06 08:41:23 cgd Exp $ */ #include #include -#include "stand.h" -#include "nfs.h" +#include +#include #include "dev_net.h" struct fs_ops file_system[] = { diff --git a/sys/arch/alpha/stand/netboot/dev_net.c b/sys/arch/alpha/stand/netboot/dev_net.c index ddb84da844c..b3c533766d9 100644 --- a/sys/arch/alpha/stand/netboot/dev_net.c +++ b/sys/arch/alpha/stand/netboot/dev_net.c @@ -1,5 +1,5 @@ -/* $OpenBSD: dev_net.c,v 1.1 1996/10/30 22:40:53 niklas Exp $ */ -/* $NetBSD: dev_net.c,v 1.1 1996/09/18 20:03:07 cgd Exp $ */ +/* $OpenBSD: dev_net.c,v 1.2 1997/05/05 06:02:00 millert Exp $ */ +/* $NetBSD: dev_net.c,v 1.4 1997/04/06 08:41:24 cgd Exp $ */ /* * Copyright (c) 1995 Gordon W. Ross @@ -57,10 +57,10 @@ #include #include -#include "stand.h" -#include "net.h" -#include "netif.h" -#include "bootparam.h" +#include +#include +#include +#include #include "dev_net.h" extern int debug; diff --git a/sys/arch/alpha/stand/netboot/devopen.c b/sys/arch/alpha/stand/netboot/devopen.c index 601960fcef4..fd148aaa404 100644 --- a/sys/arch/alpha/stand/netboot/devopen.c +++ b/sys/arch/alpha/stand/netboot/devopen.c @@ -1,5 +1,5 @@ -/* $OpenBSD: devopen.c,v 1.1 1996/10/30 22:40:54 niklas Exp $ */ -/* $NetBSD: devopen.c,v 1.1 1996/09/18 20:03:09 cgd Exp $ */ +/* $OpenBSD: devopen.c,v 1.2 1997/05/05 06:02:00 millert Exp $ */ +/* $NetBSD: devopen.c,v 1.3 1997/04/06 08:41:25 cgd Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -39,7 +39,7 @@ * @(#)devopen.c 8.1 (Berkeley) 6/10/93 */ -#include +#include /* * Decode the string 'fname', open the device and return the remaining diff --git a/sys/arch/alpha/stand/netboot/if_prom.c b/sys/arch/alpha/stand/netboot/if_prom.c index b091d49ffff..74524589f36 100644 --- a/sys/arch/alpha/stand/netboot/if_prom.c +++ b/sys/arch/alpha/stand/netboot/if_prom.c @@ -1,9 +1,9 @@ -/* $OpenBSD: if_prom.c,v 1.2 1996/11/27 19:54:55 niklas Exp $ */ -/* $NetBSD: if_prom.c,v 1.4 1996/10/02 21:18:49 cgd Exp $ */ +/* $OpenBSD: if_prom.c,v 1.3 1997/05/05 06:02:01 millert Exp $ */ +/* $NetBSD: if_prom.c,v 1.9 1997/04/06 08:41:26 cgd Exp $ */ /* - * Copyright (c) 1993 Adam Glass - * All rights reserved. + * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved. + * Copyright (c) 1993 Adam Glass. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -38,11 +38,14 @@ #include #include -#include "netif.h" -#include "include/rpb.h" -#include "include/prom.h" -#include "lib/libkern/libkern.h" -#include "lib/libsa/stand.h" +#include +#include + +#include +#include +#include + +#include "stand/bbinfo.h" int prom_probe(); int prom_match(); @@ -60,6 +63,16 @@ struct netif_dif prom_ifs[] = { struct netif_stats prom_stats[NENTS(prom_ifs)]; +struct netbbinfo netbbinfo = { + 0xfeedbabedeadbeef, /* magic number */ + 0, /* set */ + 0, 0, 0, 0, 0, 0, /* ether address */ + 0, /* force */ + { 0, }, /* pad2 */ + 0, /* cksum */ + 0xfeedbeefdeadbabe, /* magic number */ +}; + struct netif_driver prom_netif_driver = { "prom", /* netif_bname */ prom_match, /* netif_match */ @@ -72,7 +85,7 @@ struct netif_driver prom_netif_driver = { NENTS(prom_ifs) /* netif_nifs */ }; -int netfd; +int netfd, broken_firmware; int prom_match(nif, machdep_hint) @@ -120,11 +133,17 @@ prom_get(desc, pkt, len, timeout) t = getsecs(); cc = 0; while (((getsecs() - t) < timeout) && !cc) { - ret.bits = prom_read(netfd, sizeof hate, hate, 0); + if (broken_firmware) + ret.bits = prom_read(netfd, 0, hate, 0); + else + ret.bits = prom_read(netfd, sizeof hate, hate, 0); if (ret.u.status == 0) - cc += ret.u.retval; + cc = ret.u.retval; } - cc = len; + if (broken_firmware) + cc = min(cc, len); + else + cc = len; bcopy(hate, pkt, cc); return cc; @@ -139,8 +158,28 @@ prom_init(desc, machdep_hint) { prom_return_t ret; char devname[64]; - int devlen, i; + int devlen, i, netbbinfovalid; char *enet_addr; + u_int64_t *qp, csum; + + broken_firmware = 0; + + csum = 0; + for (i = 0, qp = (u_int64_t *)&netbbinfo; + i < (sizeof netbbinfo / sizeof (u_int64_t)); i++, qp++) + csum += *qp; + netbbinfovalid = (csum == 0); + if (netbbinfovalid) + netbbinfovalid = netbbinfo.set; + +#if 0 + printf("netbbinfo "); + if (!netbbinfovalid) + printf("invalid\n"); + else + printf("valid: force = %d, ea = %s\n", netbbinfo.force, + ether_sprintf(netbbinfo.ether_addr)); +#endif ret.bits = prom_getenv(PROM_E_BOOTED_DEV, devname, sizeof(devname)); devlen = ret.u.retval; @@ -150,7 +189,7 @@ prom_init(desc, machdep_hint) for (i = 0; i < 8; i++) { enet_addr = strchr(enet_addr, ' '); if (enet_addr == NULL) { - printf("Boot device name does not contain ethernet address.\n"); + printf("boot: boot device name does not contain ethernet address.\n"); goto punt; } enet_addr++; @@ -168,7 +207,7 @@ prom_init(desc, machdep_hint) enet_addr++; if (hv == -1 || lv == -1) { - printf("Bogus ethernet address.\n"); + printf("boot: boot device name contains bogus ethernet address.\n"); goto punt; } @@ -177,20 +216,37 @@ prom_init(desc, machdep_hint) #undef dval } + if (netbbinfovalid && netbbinfo.force) { + printf("boot: using hard-coded ethernet address (forced).\n"); + bcopy(netbbinfo.ether_addr, desc->myea, sizeof desc->myea); + } + +gotit: printf("boot: ethernet address: %s\n", ether_sprintf(desc->myea)); ret.bits = prom_open(devname, devlen + 1); if (ret.u.status) { printf("prom_init: open failed: %d\n", ret.u.status); - goto punt; + goto reallypunt; } netfd = ret.u.retval; return; punt: + broken_firmware = 1; + if (netbbinfovalid) { + printf("boot: using hard-coded ethernet address.\n"); + bcopy(netbbinfo.ether_addr, desc->myea, sizeof desc->myea); + goto gotit; + } + +reallypunt: + printf("\n"); printf("Boot device name was: \"%s\"\n", devname); printf("\n"); - printf("Your firmware may be too old to network-boot OpenBSD/Alpha.\n"); + printf("Your firmware may be too old to network-boot OpenBSD/Alpha,\n"); + printf("or you might have to hard-code an ethernet address into\n"); + printf("your network boot block with setnetbootinfo(8).\n"); halt(); } diff --git a/sys/arch/alpha/stand/netboot/version b/sys/arch/alpha/stand/netboot/version index 16253a53f4d..78dd6c7767a 100644 --- a/sys/arch/alpha/stand/netboot/version +++ b/sys/arch/alpha/stand/netboot/version @@ -1,5 +1,9 @@ -$OpenBSD: version,v 1.1 1996/10/30 22:41:00 niklas Exp $ -$NetBSD: version,v 1.2 1996/10/02 21:26:17 cgd Exp $ +$OpenBSD: version,v 1.2 1997/05/05 06:02:02 millert Exp $ +$NetBSD: version,v 1.6 1997/01/23 23:10:41 cgd Exp $ -1.1 Initial version -1.2 Cleaned and polished a bit +1.1: Initial version +1.2: Cleaned and polished a bit +1.3: Use libsa and libkern rather than building the objects locally. +1.4: Allow ethernet address to be hardcoded with setnetbootinfo(8). +1.5: Search for a kernel, if none specified. +1.6: Add support for gzipped kernels. diff --git a/sys/arch/alpha/stand/setnetbootinfo/Makefile b/sys/arch/alpha/stand/setnetbootinfo/Makefile new file mode 100644 index 00000000000..293399e1da8 --- /dev/null +++ b/sys/arch/alpha/stand/setnetbootinfo/Makefile @@ -0,0 +1,15 @@ +# $OpenBSD: Makefile,v 1.1 1997/05/05 06:02:02 millert Exp $ +# $NetBSD: Makefile,v 1.4 1997/04/06 08:41:36 cgd Exp $ + +.PATH: ${.CURDIR}/.. + +PROG= setnetbootinfo +BINDIR= /usr/mdec + +MAN= setnetbootinfo.8 +MANSUBDIR=/alpha + +CFLAGS+= -I${.CURDIR}/.. +LDSTATIC=-static + +.include diff --git a/sys/arch/alpha/stand/setnetbootinfo/setnetbootinfo.8 b/sys/arch/alpha/stand/setnetbootinfo/setnetbootinfo.8 new file mode 100644 index 00000000000..6821b040d60 --- /dev/null +++ b/sys/arch/alpha/stand/setnetbootinfo/setnetbootinfo.8 @@ -0,0 +1,128 @@ +.\" $OpenBSD: setnetbootinfo.8,v 1.1 1997/05/05 06:02:03 millert Exp $ +.\" $NetBSD: setnetbootinfo.8,v 1.2 1997/04/06 08:41:36 cgd Exp $ +.\" +.\" Copyright (c) 1997 Christopher G. Demetriou. 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. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by Christopher G. Demetriou +.\" for the NetBSD Project. +.\" 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. +.\" +.Dd January 20, 1997 +.Dt SETNETBOOTINFO 8 +.Os +.Sh NAME +.Nm setnetbootinfo +.Nd configure network bootstrap program +.Sh SYNOPSIS +.Nm setnetbootinfo +.Op Fl vf +.Op Fl o Ar infile +.Oo +.Fl a Ar ether-address | Fl h Ar ether-host +.Oc +.Ar netboot +.Nm setnetbootinfo +.Op Fl v +.Fl u o Ar outfile Ar infile +.Sh DESCRIPTION +The +.Nm setnetbootinfo +utility configures the OpenBSD/alpha network bootstrap program so +that it can be used to bootstrap systems with old firmware revisions. +.Pp +The OpenBSD/alpha network bootstrap program needs to have the ethernet +address of the interface being used to boot the system available when +querying other hosts on the network for bootstrapping information. +Alpha systems with old firmware revisions provide no way for +network bootstrap programs to determine the ethernet address of +the interface that they are booting from, and so the OpenBSD/alpha +network bootstrap program must find that information in another way. +(Newer firmware revisions include the ethernet address in the name of +the device that is being booted from.) +The +.Nm +utility encodes an ethernet address (and other information) directly +into the network bootstrap program. +.Pp +The options recognized by +.Nm +are as follows: +.Bl -tag -width flag +.It Fl a Ar ether-address +Encode the given ethernet address into the network bootstrap program. +(This option and the +.Fl h +option are mutually exclusive.) +.It Fl f +Force the address information being encoded in the bootstrap +program to be used regardless of whether or not the bootstrap +program can get address information from the booting system's +firmware. +.It Fl h Ar ether-host +Encode the ethernet address of the specified host into the network +bootstrap program. The host's name is translated to an ethernet +address using the +.Xr ether_hostton 3 +function. +(This option and the +.Fl a +option are mutually exclusive.) +.It Fl o Ar outfile +Output the resulting bootstrap program into the file named by +.Ar outfile , +replacing it if it already exists. If the +.Fl o +flag is not specified, the output file name will be +the name of the input bootstrap program concatenated with a +period and the digits of the ethernet address being encoded. +For instance, if the input file is named +.Pa /usr/mdec/netboot +and is being configured to encode the ethernet address +.Li 08:00:2b:bd:5d:fd , +then the default output file name would be +.Pa /usr/mdec/netboot.08002bbd5dfd . +It is safe to set the output file name to be the same as the +input file name; the input file is read in its entirety before +the output file is modified. +.It Fl u +Remove configuration information from the specified network +bootstrap program. If this option is used, an output file name must be +specified with the +.Fl o +option, and neither the +.Fl a +or the +.Fl h +options may be specified. +.It Fl v +Verbose mode. +.El +.Sh "SEE ALSO" +.Xr bootpd 8 +.Sh HISTORY +The alpha +.Nm +command first appeared in +.Nx 1.2b . diff --git a/sys/arch/alpha/stand/setnetbootinfo/setnetbootinfo.c b/sys/arch/alpha/stand/setnetbootinfo/setnetbootinfo.c new file mode 100644 index 00000000000..114a7556f11 --- /dev/null +++ b/sys/arch/alpha/stand/setnetbootinfo/setnetbootinfo.c @@ -0,0 +1,249 @@ +/* $OpenBSD: setnetbootinfo.c,v 1.1 1997/05/05 06:02:03 millert Exp $ */ +/* $NetBSD: setnetbootinfo.c,v 1.5 1997/04/06 08:41:37 cgd Exp $ */ + +/* + * Copyright (c) 1997 Christopher G. Demetriou + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Christopher G. Demetriou + * for the NetBSD Project. + * 4. 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 +#include +#include +#include +#include +#include +#include +#include /* XXX */ +#include /* XXX */ +#include +#include + +#include "bbinfo.h" + +int verbose, force, unset; +char *netboot, *outfile, *addr, *host; + +char *outfilename; + +struct ether_addr *ether_addr, _ether_addr; + +static void +usage() +{ + + (void)fprintf(stderr, "usage:\n"); + (void)fprintf(stderr, "\tsetnetboot [-v] [-f] [-o outfile] \\\n"); + (void)fprintf(stderr, "\t [-a ether-address | -h ether-host] infile\n"); + (void)fprintf(stderr, "\tsetnetboot [-v] -u -o outfile infile\n"); + exit(1); +} + +int +main(argc, argv) + int argc; + char *argv[]; +{ + struct netbbinfo *netbbinfop; + struct stat sb; + u_int64_t *qp, csum; + char *netbb; + int c, fd, i; + + while ((c = getopt(argc, argv, "a:fh:o:uv")) != -1) { + switch (c) { + case 'a': + /* use the argument as an ethernet address */ + addr = optarg; + break; + case 'f': + /* set force flag in network boot block */ + force = 1; + break; + case 'h': + /* use the argument as a host to find in /etc/ethers */ + host = optarg; + break; + case 'o': + /* use the argument as the output file name */ + outfile = optarg; + break; + case 'u': + /* remove configuration information */ + unset = 1; + break; + case 'v': + /* Chat */ + verbose = 1; + break; + default: + usage(); + } + } + + if ((argc - optind) != 1) + usage(); + netboot = argv[optind]; + + if (unset && (force || host != NULL || addr != NULL)) + errx(1, "-u can't be used with -f, -h, or -a"); + + if (unset) { + if (force || host != NULL || addr != NULL) + errx(1, "-u can't be used with -f, -h, or -a"); + if (outfile == NULL) + errx(1, "-u cannot be used without -o"); + } else { + if ((host == NULL && addr == NULL) || + (host != NULL && addr != NULL)) + usage(); + + if (host != NULL) { + if (ether_hostton(host, &_ether_addr) == -1) + errx(1, "ethernet address couldn't be found for \"%s\"", + host); + ether_addr = &_ether_addr; + } else { /* addr != NULL */ + ether_addr = ether_aton(addr); + if (ether_addr == NULL) + errx(1, "ethernet address \"%s\" is invalid", + addr); + } + } + + if (outfile != NULL) + outfilename = outfile; + else { + /* name + 12 for enet addr + '.' before enet addr + NUL */ + outfilename = malloc(strlen(netboot) + 14); + if (outfilename == NULL) + err(1, "malloc of output file name failed"); + sprintf(outfilename, "%s.%02x%02x%02x%02x%02x%02x", netboot, + ether_addr->ether_addr_octet[0], + ether_addr->ether_addr_octet[1], + ether_addr->ether_addr_octet[2], + ether_addr->ether_addr_octet[3], + ether_addr->ether_addr_octet[4], + ether_addr->ether_addr_octet[5]); + } + + if (verbose) { + printf("netboot: %s\n", netboot); + if (unset) + printf("unsetting configuration\n"); + else + printf("ethernet address: %s (%s), force = %d\n", + ether_ntoa(ether_addr), host ? host : addr, force); + printf("output netboot: %s\n", outfilename); + } + + + if (verbose) + printf("opening %s...\n", netboot); + if ((fd = open(netboot, O_RDONLY, 0)) == -1) + err(1, "open: %s", netboot); + if (fstat(fd, &sb) == -1) + err(1, "fstat: %s", netboot); + if (!S_ISREG(sb.st_mode)) + errx(1, "%s must be a regular file", netboot); + + if (verbose) + printf("reading %s...\n", netboot); + netbb = malloc(sb.st_size); + if (netbb == NULL) + err(1, "malloc of %lu for %s failed", + (unsigned long)sb.st_size, netboot); + if (read(fd, netbb, sb.st_size) != sb.st_size) + err(1, "read of %lu from %s failed", + (unsigned long)sb.st_size, netboot); + + if (verbose) + printf("closing %s...\n", netboot); + close(fd); + + if (verbose) + printf("looking for netbbinfo...\n"); + netbbinfop = NULL; + for (qp = (u_int64_t *)netbb; qp < (u_int64_t *)(netbb + sb.st_size); + qp++) { + if (((struct netbbinfo *)qp)->magic1 == 0xfeedbabedeadbeef && + ((struct netbbinfo *)qp)->magic2 == 0xfeedbeefdeadbabe) { + netbbinfop = (struct netbbinfo *)qp; + break; + } + } + if (netbbinfop == NULL) + errx(1, "netboot information structure not found in %s", + netboot); + if (verbose) + printf("found netbbinfo structure at offset 0x%lx.\n", + (unsigned long)((char *)netbbinfop - netbb)); + + if (verbose) + printf("setting netbbinfo structure...\n"); + bzero(netbbinfop, sizeof *netbbinfop); + netbbinfop->magic1 = 0xfeedbabedeadbeef; + netbbinfop->magic2 = 0xfeedbeefdeadbabe; + netbbinfop->set = unset ? 0 : 1; + if (netbbinfop->set) { + for (i = 0; i < 6; i++) + netbbinfop->ether_addr[i] = + ether_addr->ether_addr_octet[i]; + netbbinfop->force = force; + } + netbbinfop->cksum = 0; + + if (verbose) + printf("setting netbbinfo checksum...\n"); + csum = 0; + for (i = 0, qp = (u_int64_t *)netbbinfop; + i < (sizeof *netbbinfop / sizeof (u_int64_t)); i++, qp++) + csum += *qp; + netbbinfop->cksum = -csum; + + if (verbose) + printf("opening %s...\n", outfilename); + if ((fd = open(outfilename, O_WRONLY | O_CREAT, 0666)) == -1) + err(1, "open: %s", outfilename); + + if (verbose) + printf("writing %s...\n", outfilename); + if (write(fd, netbb, sb.st_size) != sb.st_size) + err(1, "write of %lu to %s failed", + (unsigned long)sb.st_size, outfilename); + + if (verbose) + printf("closing %s...\n", outfilename); + close(fd); + + free(netbb); + if (outfile == NULL) + free(outfilename); + + exit (0); +} -- 2.20.1