diff --git a/sys/arch/pmax/stand/smallnet/Makefile b/sys/arch/pmax/stand/smallnet/Makefile new file mode 100644 index 000000000000..f371a4a1bf4d --- /dev/null +++ b/sys/arch/pmax/stand/smallnet/Makefile @@ -0,0 +1,20 @@ +# $NetBSD: Makefile,v 1.1 1999/05/13 08:38:05 simonb Exp $ +# @(#)Makefile 8.3 (Berkeley) 2/16/94 + +S= ${.CURDIR}/../../../.. + +KERNELSIZE!= expr 400 \* 1024 + +SUBDIR= setnetimage + +PROG= smallnet +RELOC= 80300000 # 3MB - should work on 4MB machines +SRCS= start.S smallnet.c +BOOTDEFADD= -DBOOT_TYPE_NAME='"Compressed Kernel Network"' \ + -DRELOC=0x${RELOC} -DKERNELSIZE=${KERNELSIZE} +VERSIONFILE= ${.CURDIR}/version +.PATH: ${.CURDIR}/../lib + +.include +.include +.include "../Makefile.booters" diff --git a/sys/arch/pmax/stand/smallnet/README b/sys/arch/pmax/stand/smallnet/README new file mode 100644 index 000000000000..b790128ea615 --- /dev/null +++ b/sys/arch/pmax/stand/smallnet/README @@ -0,0 +1,8 @@ +$NetBSD: README,v 1.1 1999/05/13 08:38:05 simonb Exp $ + +The smallnet network loader is meant to be a short term solution for +machines that can't netboot full size kernels until a proper two stage +netboot is available. It isn't the prettiest code around, but it gets +us out of a bind. + +simonb, March-May 1999. diff --git a/sys/arch/pmax/stand/smallnet/setnetimage/Makefile b/sys/arch/pmax/stand/smallnet/setnetimage/Makefile new file mode 100644 index 000000000000..e276c8d37b2a --- /dev/null +++ b/sys/arch/pmax/stand/smallnet/setnetimage/Makefile @@ -0,0 +1,32 @@ +# $NetBSD: Makefile,v 1.1 1999/05/13 08:38:05 simonb Exp $ + +PROG= setnetimage +MKMAN= no +WARNS?= 1 + +MDSIDIR=${.CURDIR}/../../../../../../usr.sbin/mdsetimage + +SRCS= setnetimage.c exec_elf32.c +CPPFLAGS+=-I${MDSIDIR} +LDADD+= -lz +DPADD+= ${LIBZ} + +.PATH: ${MDSIDIR} + +.if !defined(KERNEL) +kernel: + @echo set KERNEL first! + @false +.else +SNDIR!= cd ${.CURDIR}/.. ; make print-objdir + +smallnet.elf: ${SNDIR}/smallnet + cp -p ${.ALLSRC} ${.TARGET} + +kernel: smallnet.elf + ./${PROG} ${KERNEL} ${.ALLSRC} + elf2ecoff smallnet.elf smallnet +.endif + + +.include diff --git a/sys/arch/pmax/stand/smallnet/setnetimage/setnetimage.c b/sys/arch/pmax/stand/smallnet/setnetimage/setnetimage.c new file mode 100644 index 000000000000..e7da0a7bf9a0 --- /dev/null +++ b/sys/arch/pmax/stand/smallnet/setnetimage/setnetimage.c @@ -0,0 +1,224 @@ +/* $NetBSD: setnetimage.c,v 1.1 1999/05/13 08:38:05 simonb Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Simon Burge. + * + * 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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "extern.h" + +#define MAX_SEGMENTS 10 /* We can load up to 10 segments */ + +struct nlist nl[] = { +#define X_KERNEL_ENTRY 0 + { "_kernel_entry" }, +#define X_KERNEL_IMAGE 1 + { "_kernel_image" }, +#define X_KERNEL_LOADADDR 2 + { "_kernel_loadaddr" }, +#define X_KERNEL_SIZE 3 + { "_kernel_size" }, +#define X_MAXKERNEL_SIZE 4 + { "_maxkernel_size" }, + { NULL } +}; +#define X_NSYMS ((sizeof(nl) / sizeof(struct nlist)) - 1) + +struct seglist { + Elf32_Addr addr; + Elf32_Off f_offset; + Elf32_Word f_size; +}; + +#define NLADDR(x) (mappedbfile + offsets[(x)]) +#define NLVAR(x) (*(u_long *)(NLADDR(x))) + +extern const char *__progname; + +int main __P((int, char **)); + +int +main(argc, argv) + int argc; + char **argv; +{ + int ifd, ofd, i, nsegs; + size_t offsets[X_NSYMS]; + const char *kernel, *bootfile; + char *mappedbfile; + char *uncomp_kernel, *comp_kernel; + Elf32_Addr lowaddr, highaddr; + Elf32_Ehdr ehdr; + Elf32_Phdr phdr; + uLongf destlen; + struct stat osb; + struct seglist seglist[MAX_SEGMENTS]; + + if (argc != 3) { + fprintf(stderr, "usage: %s kernel bootfile\n", __progname); + exit(1); + } + + kernel = argv[1]; + bootfile = argv[2]; + + if ((ifd = open(kernel, O_RDONLY)) < 0) + err(1, "%s", kernel); + + if ((ofd = open(bootfile, O_RDWR)) < 0) + err(1, "%s", bootfile); + + if (nlist(bootfile, nl) != 0) + errx(1, "Could not find symbols in %s", bootfile); + + if (fstat(ofd, &osb) == -1) + err(1, "fstat %s", bootfile); + if (osb.st_size > SIZE_T_MAX) + errx(1, "%s too big to map", bootfile); + + if ((mappedbfile = mmap(NULL, osb.st_size, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, ofd, 0)) == (caddr_t)-1) + err(1, "mmap %s", bootfile); + printf("mapped %s\n", bootfile); + + if (check_elf32(mappedbfile, osb.st_size) != 0) + errx(1, "No ELF header in %s", bootfile); + + for (i = 0; i < X_NSYMS; i++) { + if (findoff_elf32(mappedbfile, osb.st_size, nl[i].n_value, &offsets[i]) != 0) + errx(1, "Couldn't find offset for %s in %s\n", nl[i].n_name, bootfile); +#ifdef DEBUG + printf("%s is at offset %#x in %s\n", nl[i].n_name, offsets[i], bootfile); +#endif + } + + /* read the exec header */ + i = read(ifd, (char *)&ehdr, sizeof(ehdr)); + if ((i != sizeof(ehdr)) || + (memcmp(ehdr.e_ident, Elf32_e_ident, Elf32_e_siz) != 0)) { + errx(1, "No ELF header in %s", kernel); + } + + nsegs = highaddr = 0; + lowaddr = UINT_MAX; + for (i = 0; i < ehdr.e_phnum; i++) { + if (lseek(ifd, (off_t) ehdr.e_phoff + i * sizeof(phdr), 0) < 0) + err(1, "%s", kernel); + if (read(ifd, &phdr, sizeof(phdr)) != sizeof(phdr)) + err(1, "%s", kernel); + if (phdr.p_type != Elf_pt_load) + continue; + + printf("load section %d at addr 0x%08x, file offset %8d, length %8d\n", + i, phdr.p_paddr, phdr.p_offset, phdr.p_filesz); + + seglist[nsegs].addr = phdr.p_paddr; + seglist[nsegs].f_offset = phdr.p_offset; + seglist[nsegs].f_size = phdr.p_filesz; + nsegs++; + + if (phdr.p_paddr < lowaddr) + lowaddr = phdr.p_paddr; + if (phdr.p_paddr + phdr.p_filesz > highaddr) + highaddr = phdr.p_paddr + phdr.p_filesz; + + } + +#ifdef DEBUG + printf("lowaddr = 0x%08x, highaddr = 0x%08x\n", lowaddr, highaddr); +#endif + printf("load address: 0x%08x\n", lowaddr); + printf("entry point: 0x%08x\n", ehdr.e_entry); + + destlen = highaddr - lowaddr; + + uncomp_kernel = (char *)malloc(destlen); + comp_kernel = (char *)malloc(destlen); /* Worst case... */ + for (i = 0; i < nsegs; i++) { +#ifdef DEBUG + printf("lseek(ifd, %d, 0)\n", seglist[i].f_offset); +#endif + if (lseek(ifd, (off_t)seglist[i].f_offset, 0) < 0) + err(1, "%s", kernel); +#ifdef DEBUG + printf("read(ifd, %p, %d)\n", \ + uncomp_kernel + seglist[i].addr - lowaddr, + seglist[i].f_size); +#endif + if (read(ifd, uncomp_kernel + seglist[i].addr - lowaddr, + seglist[i].f_size) != seglist[i].f_size) + err(1, "%s", kernel); + } + close(ifd); + + printf("Compressing %d bytes...", highaddr - lowaddr); fflush(stdout); + i = compress2(comp_kernel, &destlen, uncomp_kernel, \ + highaddr - lowaddr, Z_BEST_COMPRESSION); + if (i != Z_OK) { + printf("\n"); + errx(1, "%s compression error %d\n", kernel, i); + } + printf("done.\n"); fflush(stdout); + + printf("max kernelsize = %ld\n", NLVAR(X_MAXKERNEL_SIZE)); + printf("compressed size = %ld\n", destlen); + if (destlen > NLVAR(X_MAXKERNEL_SIZE)) + errx(1, "kernel %s is too big, " + "increase KERNELSIZE to at least %ld\n", + kernel, destlen); + + NLVAR(X_KERNEL_SIZE) = destlen; + NLVAR(X_KERNEL_LOADADDR) = lowaddr; + NLVAR(X_KERNEL_ENTRY) = ehdr.e_entry; + memcpy(NLADDR(X_KERNEL_IMAGE), comp_kernel, destlen); + munmap(mappedbfile, osb.st_size); + printf("unmapped %s\n", bootfile); + close(ofd); + + exit(0); +} diff --git a/sys/arch/pmax/stand/smallnet/smallnet.c b/sys/arch/pmax/stand/smallnet/smallnet.c new file mode 100644 index 000000000000..b36d138951dd --- /dev/null +++ b/sys/arch/pmax/stand/smallnet/smallnet.c @@ -0,0 +1,119 @@ +/* $NetBSD: smallnet.c,v 1.1 1999/05/13 08:38:05 simonb Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Simon Burge. + * + * 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 +#include +#include +#include +#include +#include + +#include "common.h" +#include "bootinfo.h" + + +typedef void (*entrypt) __P((int, char **, int, const void *)); + +int main __P((int, char **)); + +/* + * These variables and array will be patched to contain a kernel image + * and some information about the kernel. + */ + +int maxkernel_size = KERNELSIZE; +entrypt kernel_entry = 0 /* (entrypt)0x80030000 */ /* XXX XXX XXX */; +u_long kernel_loadaddr = 0 /* 0x80030000 */ /* XXX XXX XXX */; +int kernel_size = 0 /* 387321 */ /* XXX XXX XXX */; +char kernel_image[KERNELSIZE] = "|This is the kernel image!\n"; + + +/* + * This gets arguments from the PROM, calls other routines to open + * and load the secondary boot loader called boot, and then transfers + * execution to that program. + * + * Argv[0] should be something like "rz(0,0,0)netbsd" on a DECstation 3100. + * Argv[0,1] should be something like "boot 5/rz0/netbsd" on a DECstation 5000. + * The argument "-a" means netbsd should do an automatic reboot. + */ +int +main(argc, argv) + int argc; + char **argv; +{ + int ret; + char *name; + uLongf destlen; + struct btinfo_bootpath bi_bpath; + + printf("NetBSD/pmax " NETBSD_VERS " " BOOT_TYPE_NAME + " Bootstrap, Revision %s\n", bootprog_rev); + printf("(%s, %s)\n", bootprog_maker, bootprog_date); + + /* initialise bootinfo structure early */ + bi_init(BOOTINFO_ADDR); + + /* check for DS5000 boot */ + if (strcmp(argv[0], "boot") == 0) { + argc--; + argv++; + } + name = *argv; + + strncpy(bi_bpath.bootpath, name, BTINFO_BOOTPATH_LEN); + bi_add(&bi_bpath, BTINFO_BOOTPATH, sizeof(bi_bpath)); + + destlen = RELOC - kernel_loadaddr; + printf("\n"); + printf("Decompressing %d bytes to 0x%lx\n", kernel_size, + kernel_loadaddr); + ret = uncompress((Bytef *)kernel_loadaddr, &destlen, kernel_image, + kernel_size); + if (ret != Z_OK) { + printf("Error decompressing kernel\n"); + printf("libz error %d\n", ret); + return (1); + } + + if (callv == &callvec) + kernel_entry(argc, argv, 0, 0); + else + kernel_entry(argc, argv, DEC_PROM_MAGIC, callv); + return (1); +} diff --git a/sys/arch/pmax/stand/smallnet/version b/sys/arch/pmax/stand/smallnet/version new file mode 100644 index 000000000000..c24af89681cb --- /dev/null +++ b/sys/arch/pmax/stand/smallnet/version @@ -0,0 +1,8 @@ +$NetBSD: version,v 1.1 1999/05/13 08:38:05 simonb Exp $ + +# The newvers.sh looks for the line below. We use this method +# rather than $3 of the dollar-NetBSD-dollar line above so that +# this version can be on branch-files also. +Version: 1.0 + +1.0: Initial compressed kernel network boot