diff --git a/sys/boot/alpha/common/main.c b/sys/boot/alpha/common/main.c
index d7f6709fadc6..af337d268c7f 100644
--- a/sys/boot/alpha/common/main.c
+++ b/sys/boot/alpha/common/main.c
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id: main.c,v 1.2 1998/08/22 10:31:00 dfr Exp $
+ *	$Id: main.c,v 1.3 1998/08/31 21:10:40 msmith Exp $
  */
 
 
@@ -118,6 +118,7 @@ main(void)
     archsw.arch_autoload = alpha_autoload;
     archsw.arch_getdev = alpha_getdev;
     archsw.arch_copyin = alpha_copyin;
+    archsw.arch_copyout = alpha_copyout;
     archsw.arch_readin = alpha_readin;
 
     /*
@@ -128,15 +129,6 @@ main(void)
      */
     open("/", O_RDONLY);
 
-    /*
-     * XXX should these be in the MI source?
-     */
-    source("/boot/boot.config");
-    printf("\n");
-    autoboot(10, NULL);		/* try to boot automatically */
-    printf("\nType '?' for a list of commands, 'help' for more detailed help.\n");
-    /* setenv("prompt", "$currdev>", 1); */
-
     interact();			/* doesn't return */
 }
 
diff --git a/sys/boot/alpha/libalpha/alpha_copy.c b/sys/boot/alpha/libalpha/alpha_copy.c
index 9e164de0dbad..250c41692dc6 100644
--- a/sys/boot/alpha/libalpha/alpha_copy.c
+++ b/sys/boot/alpha/libalpha/alpha_copy.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id$
+ *	$Id: alpha_copy.c,v 1.1 1998/08/31 21:10:40 msmith Exp $
  */
 /*
  * MD primitives supporting placement of module data 
@@ -41,6 +41,13 @@ alpha_copyin(void *src, vm_offset_t dest, size_t len)
     return(len);
 }
 
+int
+alpha_copyout(void *src, vm_offset_t dest, size_t len)
+{
+    bcopy(src, dest, len);
+    return(len);
+}
+
 int
 alpha_readin(int fd, vm_offset_t dest, size_t len)
 {
diff --git a/sys/boot/common/bootstrap.h b/sys/boot/common/bootstrap.h
index fd78eb7346d7..770ecfd3b609 100644
--- a/sys/boot/common/bootstrap.h
+++ b/sys/boot/common/bootstrap.h
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id: bootstrap.h,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
+ *	$Id: bootstrap.h,v 1.2 1998/08/31 21:10:42 msmith Exp $
  */
 
 #include <sys/types.h>
@@ -62,6 +62,8 @@ extern int	autoboot(int delay, char *prompt);
 
 /* misc.c */
 extern char	*unargv(int argc, char *argv[]);
+extern size_t	strlenout(vm_offset_t str);
+extern char	*strdupout(vm_offset_t str);
 
 /*
  * Modular console support.
@@ -123,14 +125,16 @@ struct module_format
     /* Load function must return EFTYPE if it can't handle the module supplied */
     int		(* l_load)(char *filename, vm_offset_t dest, struct loaded_module **result);
     /* Only a loader that will load a kernel (first module) should have an exec handler */
-    int		(* l_exec)(struct loaded_module *amp);
+    int		(* l_exec)(struct loaded_module *mp);
 };
 extern struct module_format	*module_formats[];	/* supplied by consumer */
 extern struct loaded_module	*loaded_modules;
 extern int			mod_load(char *name, int argc, char *argv[]);
+extern int			mod_loadobj(char *type, char *name);
 extern struct loaded_module	*mod_findmodule(char *name, char *type);
 extern void			mod_addmetadata(struct loaded_module *mp, int type, size_t size, void *p);
 extern struct module_metadata	*mod_findmetadata(struct loaded_module *mp, int type);
+extern void			mod_discard(struct loaded_module *mp);
 
 /*
  * Module information subtypes
@@ -144,12 +148,18 @@ extern struct module_metadata	*mod_findmetadata(struct loaded_module *mp, int ty
 
 #define MODINFOMD_AOUTEXEC	0x0001		/* a.out exec header */
 #define MODINFOMD_ELFHDR	0x0002		/* ELF header */
+#define MODINFOMD_NOCOPY	0x8000		/* don't copy this metadata to the kernel */
 
 /* MI module loaders */
-extern int	aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result);
+extern int		aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result);
+extern vm_offset_t	aout_findsym(char *name, struct loaded_module *mp);
 
 /* extern int	elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); */
 
+#define KLD_IDENT_SYMNAME	"kld_identifier_"
+#define MODINFOMD_KLDIDENT	(MODINFOMD_NOCOPY | 0x4000)
+#define MODINFOMD_KLDDEP	(MODINFOMD_NOCOPY | 0x4001)
+
 #if defined(__ELF__)
 
 /*
@@ -231,8 +241,36 @@ struct arch_switch
     int			(*arch_getdev)(void **dev, char *name, char **path);
     /* Copy from local address space to module address space, similar to bcopy() */
     int			(*arch_copyin)(void *src, vm_offset_t dest, size_t len);
+    /* Copy to local address space from module address space, similar to bcopy() */
+    int			(*arch_copyout)(vm_offset_t src, void *dest, size_t len);
     /* Read from file to module address space, same semantics as read() */
     int			(*arch_readin)(int fd, vm_offset_t dest, size_t len);
 };
 extern struct arch_switch archsw;
 
+/*
+ * XXX these belong in a system header
+ */
+#define KLD_NAMELEN	32
+
+struct kld_module_dependancy
+{
+    char	kd_name[KLD_NAMELEN];
+    u_int32_t	kd_version;
+};
+
+struct kld_module_identifier
+{
+    u_int32_t				ki_kldversion;
+    char				ki_name[KLD_NAMELEN];
+    u_int32_t				ki_version;
+    struct kld_module_dependancy	*ki_deps;
+    int					ki_ndeps;
+    size_t				ki_depsize;
+};
+
+/*
+ * Use the depsize field in the identifier to correctly index a
+ * dependancy.
+ */
+#define KLD_GETDEP(ki, kd, n)	(struct kld_module_dependancy *)((char *)(kd) + ((ki)->ki_depsize * (n)))
diff --git a/sys/boot/common/commands.c b/sys/boot/common/commands.c
index af6a4752daeb..8ed140affa82 100644
--- a/sys/boot/common/commands.c
+++ b/sys/boot/common/commands.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id$
+ *	$Id: commands.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
  */
 
 #include <stand.h>
@@ -61,7 +61,7 @@ command_commandlist(int argc, char *argv[])
     printf("Available commands:\n");
     cmdp = (struct bootblk_command **)Xcommand_set.ls_items;
     for (i = 0; i < Xcommand_set.ls_length; i++)
-	if (cmdp[i]->c_name != NULL)
+	if ((cmdp[i]->c_name != NULL) && (cmdp[i]->c_desc != NULL))
 	    printf("  %-15s  %s\n", cmdp[i]->c_name, cmdp[i]->c_desc);
     return(CMD_OK);
 }
@@ -153,3 +153,38 @@ command_panic(int argc, char *argv[])
     cp = unargv(argc - 1, argv + 1);
     panic(cp);
 }
+
+COMMAND_SET(echo, "echo", NULL, command_echo);
+
+static int
+command_echo(int argc, char *argv[])
+{
+    char	*s;
+    int		nl, ch;
+    
+    nl = 0;
+    optind = 1;
+    while ((ch = getopt(argc, argv, "n")) != -1) {
+	switch(ch) {
+	case 'n':
+	    nl = 1;
+	    break;
+	case '?':
+	default:
+	    /* getopt has already reported an error */
+	    return(CMD_OK);
+	}
+    }
+    argv += (optind);
+    argc -= (optind);
+
+    s = unargv(argc, argv);
+    if (s != NULL) {
+	printf(s);
+	free(s);
+    }
+    if (!nl)
+	printf("\n");
+    return(CMD_OK);
+}
+
diff --git a/sys/boot/common/interp.c b/sys/boot/common/interp.c
index a0162ba0a8a0..c58b1c4f3d16 100644
--- a/sys/boot/common/interp.c
+++ b/sys/boot/common/interp.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id: interp.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
+ *	$Id: interp.c,v 1.2 1998/09/01 00:41:24 msmith Exp $
  */
 /*
  * Simple commandline interpreter, toplevel and misc.
@@ -83,6 +83,24 @@ interact(void)
     int		argc;
     char	**argv;
 
+    /*
+     * Read our default configuration
+     */
+    source("/boot/boot.conf");
+    printf("\n");
+    /*
+     * Before interacting, we might want to autoboot
+     */
+    if (getenv("no_autoboot") == NULL)
+	autoboot(10, NULL);		/* try to boot automatically */
+
+    /*
+     * Not autobooting, go manual
+     */
+    printf("\nType '?' for a list of commands, 'help' for more detailed help.\n");
+    setenv("prompt", "${currdev}>", 1);
+    
+
     for (;;) {
 	input[0] = '\0';
 	prompt();
@@ -149,32 +167,29 @@ source(char *filename)
 }
 
 /*
- * Emit the current prompt; support primitive embedding of
- * environment variables.
- * We're a little rude here, modifying the return from getenv().
+ * Emit the current prompt; use the same syntax as the parser
+ * for embedding environment variables.
  */
 static void
 prompt(void) 
 {
-    char	*p, *cp, *ev, c;
+    char	*p, *cp, *ev;
     
-    if ((p = getenv("prompt")) == NULL)
-	p = ">";
+    if ((cp = getenv("prompt")) == NULL)
+	cp = ">";
+    p = strdup(cp);
 
     while (*p != 0) {
-	if (*p == '$') {
-	    for (cp = p + 1; (*cp != 0) && isalpha(*cp); cp++)
+	if ((*p == '$') && (*(p+1) == '{')) {
+	    for (cp = p + 2; (*cp != 0) && (*cp != '}'); cp++)
 		;
-	    c = *cp;
 	    *cp = 0;
-	    ev = getenv(p + 1);
-	    *cp = c;
+	    ev = getenv(p + 2);
 	    
-	    if (ev != NULL) {
+	    if (ev != NULL)
 		printf(ev);
-		p = cp;
-		continue;
-	    }
+	    p = cp + 1;
+	    continue;
 	}
 	putchar(*p++);
     }
diff --git a/sys/boot/common/load_aout.c b/sys/boot/common/load_aout.c
index 45b632866a0d..5c593724d309 100644
--- a/sys/boot/common/load_aout.c
+++ b/sys/boot/common/load_aout.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id: aout_freebsd.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
+ *	$Id: load_aout.c,v 1.1 1998/08/31 21:10:42 msmith Exp $
  */
 
 #include <sys/param.h>
@@ -33,10 +33,15 @@
 #include <string.h>
 #include <machine/bootinfo.h>
 #include <stand.h>
+#define _AOUT_INCLUDE_
+#include <nlist.h>
+#include <link.h>
 
 #include "bootstrap.h"
 
-static int	aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr);
+static int		aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr, int kernel);
+static vm_offset_t	aout_findkldident(struct loaded_module *mp, struct exec *ehdr);
+static int		aout_fixupkldmod(struct loaded_module *mp, struct exec *ehdr);
 
 char	*aout_kerneltype = "a.out kernel";
 char	*aout_moduletype = "a.out module";
@@ -49,12 +54,15 @@ char	*aout_moduletype = "a.out module";
 int
 aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
 {
-    struct loaded_module	*mp;
+    struct loaded_module	*mp, *kmp;
     struct exec			ehdr;
     int				fd;
     vm_offset_t			addr;
     int				err, kernel;
+    u_int			pad;
 
+    mp = NULL;
+    
     /*
      * Open the image, read and validate the a.out header 
      */
@@ -62,35 +70,42 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
 	return(EFTYPE);
     if ((fd = open(filename, O_RDONLY)) == -1)
 	return(errno);
-    if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
-	return(EFTYPE);		/* could be EIO, but may be small file */
-    if (N_BADMAG(ehdr))
-	return(EFTYPE);
+    if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) {
+	err = EFTYPE;		/* could be EIO, but may be small file */
+	goto oerr;
+    }
+    if (N_BADMAG(ehdr)) {
+	err = EFTYPE;
+	goto oerr;
+    }
 
     /*
      * Check to see what sort of module we are.
      *
      * XXX should check N_GETMID()
      */
-    mp = mod_findmodule(NULL, NULL);
+    kmp = mod_findmodule(NULL, NULL);
     if (N_GETFLAG(ehdr) == (EX_DYNAMIC | EX_PIC)) {
 	/* Looks like a kld module */
-	if (mp == NULL) {
+	if (kmp == NULL) {
 	    printf("aout_loadmodule: can't load module before kernel\n");
-	    return(EPERM);
+	    err = EPERM;
+	    goto oerr;
 	}
-	if (strcmp(aout_kerneltype, mp->m_type)) {
-	    printf("out_loadmodule: can't load module with kernel type '%s'\n", mp->m_type);
-	    return(EPERM);
+	if (strcmp(aout_kerneltype, kmp->m_type)) {
+	    printf("out_loadmodule: can't load module with kernel type '%s'\n", kmp->m_type);
+	    err = EPERM;
+	    goto oerr;
 	}
 	/* Looks OK, got ahead */
 	kernel = 0;
 
     } else if (N_GETFLAG(ehdr) == 0) {
 	/* Looks like a kernel */
-	if (mp != NULL) {
+	if (kmp != NULL) {
 	    printf("aout_loadmodule: kernel already loaded\n");
-	    return(EPERM);
+	    err = EPERM;
+	    goto oerr;
 	}
 	/* 
 	 * Calculate destination address based on kernel entrypoint 	
@@ -99,39 +114,56 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
 	dest = ehdr.a_entry & 0x100000;
 	if (dest == 0) {
 	    printf("aout_loadmodule: not a kernel (maybe static binary?)\n");
-	    return(EPERM);
+	    err = EPERM;
+	    goto oerr;
 	}
 	kernel = 1;
     } else {
-	return(EFTYPE);
+	err = EFTYPE;
+	goto oerr;
     }
 
     /* 
      * Ok, we think we should handle this.
      */
     mp = malloc(sizeof(struct loaded_module));
-    mp->m_name = strdup(filename);		/* XXX should we prune the name? */
+    mp->m_name = kernel ? strdup(filename) : NULL;	/* XXX should we prune the name? */
     mp->m_type = strdup(kernel ? aout_kerneltype : aout_moduletype);
-    mp->m_args = NULL;				/* XXX should we put the bootstrap args here and parse later? */
+    mp->m_args = NULL;					/* filled in by parent */
     mp->m_metadata = NULL;
-    mp->m_addr = addr = dest;
+    /* Page-align the load address */
+    addr = dest;
+    pad = (u_int)addr & PAGE_MASK;
+    if (pad != 0) {
+	pad = PAGE_SIZE - pad;
+	addr += pad;
+    }
+    mp->m_addr = addr;					/* save the aligned load address */
     printf("%s at 0x%x\n", filename, addr);
 
-    mp->m_size = aout_loadimage(fd, addr, &ehdr);
+    mp->m_size = aout_loadimage(fd, addr, &ehdr, kernel);
     if (mp->m_size == 0)
 	goto ioerr;
 
+    /* Handle KLD module data */
+    if (!kernel && ((err = aout_fixupkldmod(mp, &ehdr)) != 0))
+	goto oerr;
+
     /* save exec header as metadata */
     mod_addmetadata(mp, MODINFOMD_AOUTEXEC, sizeof(struct exec), &ehdr);
 
     /* Load OK, return module pointer */
     *result = (struct loaded_module *)mp;
-    return(0);
-
+    err = 0;
+    goto out;
+    
  ioerr:
     err = EIO;
-    close(fd);
+ oerr:
+    mod_discard(mp);
     free(mp);
+ out:
+    close(fd);
     return(err);
 }
 
@@ -143,17 +175,17 @@ aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
  * align the symbol table.
  */
 static int
-aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr)
+aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr, int kernel)
 {
     u_int		pad;
     vm_offset_t		addr;
     int			ss;
-
+    
     addr = loadaddr;
     lseek(fd, N_TXTOFF(*ehdr), SEEK_SET);
-    
+
     /* text segment */
-    printf("text=0x%lx ", ehdr->a_text);
+    printf("  text=0x%lx ", ehdr->a_text);
     if (archsw.arch_readin(fd, addr, ehdr->a_text) != ehdr->a_text)
 	return(0);
     addr += ehdr->a_text;
@@ -164,24 +196,23 @@ aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr)
 	return(0);
     addr += ehdr->a_data;
 
-    /* skip the BSS */
+    /* For kernels, we pad the BSS to a page boundary */
+    if (kernel) {
+	pad = (u_int)ehdr->a_bss & PAGE_MASK;
+	if (pad != 0) {
+	    pad = PAGE_SIZE - pad;
+	    ehdr->a_bss += pad;
+	}
+    }
     printf("bss=0x%lx ", ehdr->a_bss);
     addr += ehdr->a_bss;
-    
-    /* pad to a page boundary */
-    pad = (u_int)addr & PAGE_MASK;
-    if (pad != 0) {
-	pad = PAGE_SIZE - pad;
-	addr += pad;
-	ehdr->a_bss += pad;
-    }
 
     /* symbol table size */
     archsw.arch_copyin(&ehdr->a_syms, addr, sizeof(ehdr->a_syms));
     addr += sizeof(ehdr->a_syms);
 
     /* symbol table */
-    printf("symbols=[0x%x+0x%x+0x%lx", pad, sizeof(ehdr->a_syms), ehdr->a_syms);
+    printf("symbols=[0x%x+0x%lx", sizeof(ehdr->a_syms), ehdr->a_syms);
     if (archsw.arch_readin(fd, addr, ehdr->a_syms) != ehdr->a_syms)
 	return(0);
     addr += ehdr->a_syms;
@@ -200,3 +231,230 @@ aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr)
     return(addr - loadaddr);
 }
 
+
+#define AOUT_RELOC(mp, off) ((mp)->m_addr + (vm_offset_t)(off))
+
+/*
+ * The goal here is to find the one symbol in the loaded object
+ * which fits the format "kld_identifier_<something>.  If there's
+ * more than one, we fail.
+ */
+static vm_offset_t
+aout_findkldident(struct loaded_module *mp, struct exec *ehdr)
+{
+    /* XXX much of this can go when we can address the load area directly */
+    vm_offset_t				sp, ep, cand, stringbase, result;
+    struct _dynamic			dynamic;
+    struct section_dispatch_table	sdt;
+    struct nzlist			nzl;
+    char				*np;
+    int					match;
+
+    /* Get the _DYNAMIC object, which we assume is first in the data segment */
+    archsw.arch_copyout(AOUT_RELOC(mp, ehdr->a_text), &dynamic, sizeof(dynamic));
+    archsw.arch_copyout(AOUT_RELOC(mp, dynamic.d_un.d_sdt), &sdt, sizeof(struct section_dispatch_table));
+    dynamic.d_un.d_sdt = &sdt;			/* fix up SDT pointer */
+    if (dynamic.d_version != LD_VERSION_BSD)
+	return(0);
+    stringbase = AOUT_RELOC(mp, LD_STRINGS(&dynamic));
+    
+    /* start pointer */
+    sp = AOUT_RELOC(mp, LD_SYMBOL(&dynamic));
+    /* end pointer */
+    ep = sp + LD_STABSZ(&dynamic);
+
+    /*
+     * Walk the entire table comparing names.
+     */
+    match = 0;
+    result = 0;
+    for (cand = sp; cand < ep; cand += sizeof(struct nzlist)) {
+	/* get the entry, check for a name */
+	archsw.arch_copyout(cand, &nzl, sizeof(struct nzlist));
+	/* is this symbol worth looking at? */
+	if ((nzl.nz_strx == 0)			||		/* no name */
+	    (nzl.nz_value == 0)			||		/* not a definition */
+	    ((nzl.nz_type == N_UNDF+N_EXT) && 
+	     (nzl.nz_value != 0)           && 
+	     (nzl.nz_other == AUX_FUNC)))			/* weak function */
+	    continue;
+
+	np = strdupout(stringbase + nzl.nz_strx);
+	match = (np[0] == '_') && !strncmp(KLD_IDENT_SYMNAME, np + 1, strlen(KLD_IDENT_SYMNAME));
+	free(np);
+	if (match) {
+	    /* duplicates? */
+	    if (result)
+		return(0);
+	    result = AOUT_RELOC(mp, nzl.nz_value);
+	}
+    }
+    return(result);
+}
+
+/*
+ * Perform extra housekeeping associated with loading a KLD module.
+ *
+ * XXX if this returns an error, it seems the heap becomes corrupted.
+ */
+static int
+aout_fixupkldmod(struct loaded_module *mp, struct exec *ehdr)
+{
+    struct kld_module_identifier	kident;
+    struct kld_module_dependancy	*kdeps;
+    vm_offset_t				vp;
+    size_t				dsize;
+
+    /* Find the KLD identifier */
+    if ((vp = aout_findkldident(mp, ehdr)) == 0) {
+	printf("bad a.out module format\n");
+	return(EFTYPE);
+    }
+    archsw.arch_copyout(vp, &kident, sizeof(struct kld_module_identifier));
+    
+    /* Name the module using the name from the KLD data */
+    if (mod_findmodule(kident.ki_name, NULL) != NULL) {
+	printf("module '%s' already loaded\n", kident.ki_name);
+	return(EPERM);
+    }
+    mp->m_name = strdup(kident.ki_name);
+
+    /* Save the module identifier */
+    mod_addmetadata(mp, MODINFOMD_KLDIDENT, sizeof(struct kld_module_identifier), &kident);
+    
+    /* Look for dependancy data, add to metadata list */
+    if (kident.ki_ndeps > 0) {
+	dsize = kident.ki_ndeps * kident.ki_depsize;
+	kdeps = malloc(dsize);
+	archsw.arch_copyout(AOUT_RELOC(mp, kident.ki_deps), kdeps, dsize);
+	mod_addmetadata(mp, MODINFOMD_KLDDEP, dsize, kdeps);
+	free(kdeps);
+    }
+    return(0);
+}
+
+#if 0
+/************************************************************/
+/* XXX  Arbitrary symbol lookup - unused at this point  XXX */
+/*                                                          */
+/* Code heavily borrowed from kern/link_aout.c (c) DFR      */
+/************************************************************/
+
+static long
+symbol_hash_value(struct _dynamic *dynamic, const char* name)
+{
+    long hashval;
+    const char* p;
+
+    hashval = '_';		/* fake a starting '_' for C symbols */
+    for (p = name; *p; p++)
+	hashval = (hashval << 1) + *p;
+
+    return (hashval & 0x7fffffff) % LD_BUCKETS(dynamic);
+}
+
+/*
+ * Locate the symbol (name) in the a.out object associated with (mp),
+ * return a vm_offset_t containing the value of the symbol.
+ */
+static vm_offset_t
+aout_findsym(char *name, struct loaded_module *mp)
+{
+    struct module_metadata		*md;
+    struct exec				*ehdr;
+    struct _dynamic			dynamic;
+    struct section_dispatch_table	sdt;
+    vm_offset_t				hashbase, symbolbase, stringbase, hp, np, cp;
+    struct rrs_hash			hash;
+    struct nzlist			nzl;
+    char				*symbol, *asymbol;	/* XXX symbol name limit? */
+    long				hashval;
+    vm_offset_t				result;
+
+    
+    symbol = NULL;
+    asymbol = NULL;
+    result = 0;
+
+    /* Find the exec header */
+    if ((md = mod_findmetadata(mp, MODINFOMD_AOUTEXEC)) == NULL)
+	goto out;
+    ehdr = (struct exec *)md->md_data;
+    
+    /* Get the _DYNAMIC object, which we assume is first in the data segment */
+    archsw.arch_copyout(AOUT_RELOC(mp, ehdr->a_text), &dynamic, sizeof(dynamic));
+    archsw.arch_copyout(AOUT_RELOC(mp, dynamic.d_un.d_sdt), &sdt, sizeof(struct section_dispatch_table));
+    dynamic.d_un.d_sdt = &sdt;			/* fix up SDT pointer */
+    if ((dynamic.d_version != LD_VERSION_BSD) ||
+	(LD_BUCKETS(&dynamic) == 0))
+	goto out;
+
+    hashbase = AOUT_RELOC(mp, LD_HASH(&dynamic));
+    symbolbase = AOUT_RELOC(mp, LD_SYMBOL(&dynamic));
+    stringbase = AOUT_RELOC(mp, LD_STRINGS(&dynamic));
+    
+restart:
+    hashval = symbol_hash_value(&dynamic, name);
+    hp = hashbase + (hashval * sizeof(struct rrs_hash));
+    archsw.arch_copyout(hp, &hash, sizeof(struct rrs_hash));
+    if (hash.rh_symbolnum == -1)
+	goto out;
+    
+    while (hp) {
+	np = symbolbase + (hash.rh_symbolnum * sizeof(struct nzlist));
+	archsw.arch_copyout(np, &nzl, sizeof(struct nzlist));
+	cp = stringbase + nzl.nz_strx;
+	if (symbol != NULL)
+	    free(symbol);
+	symbol = strdupout(cp);
+	/*
+	 * Note: we fake the leading '_' for C symbols.
+	 */
+	if (symbol[0] == '_' && !strcmp(symbol + 1, name))
+	    break;
+
+	if (hash.rh_next == 0) {
+	    hp = 0;
+	} else {
+	    hp = hashbase + (hash.rh_next * sizeof(struct rrs_hash));
+	    archsw.arch_copyout(hp, &hash, sizeof(struct rrs_hash));
+	}
+    }
+    /* Not found. */
+    if (hp == 0)
+	goto out;
+
+    /*
+     * Check for an aliased symbol, whatever that is.
+     */
+    if (nzl.nz_type == N_INDR+N_EXT) {
+	np += sizeof(struct nzlist);
+	archsw.arch_copyout(np, &nzl, sizeof(struct nzlist));
+	asymbol = strdupout(stringbase + nzl.nz_strx + 1); /* +1 for '_' */
+	goto restart;
+    }
+
+    /*
+     * Check this is an actual definition of the symbol.
+     */
+    if (nzl.nz_value == 0)
+	goto out;
+
+    if (nzl.nz_type == N_UNDF+N_EXT && nzl.nz_value != 0)
+	if (nzl.nz_other == AUX_FUNC)
+	    /* weak function */
+	    goto out;
+    
+    /* Return a vm_offset_t pointing to the object itself */
+    result = AOUT_RELOC(mp, nzl.nz_value);
+
+ out:
+    if (symbol)
+	free(symbol);
+    if (asymbol)
+	free(asymbol);
+    return(result);
+    
+}
+
+#endif
diff --git a/sys/boot/common/ls.c b/sys/boot/common/ls.c
index b777c5a771b1..962d4f740869 100644
--- a/sys/boot/common/ls.c
+++ b/sys/boot/common/ls.c
@@ -1,5 +1,5 @@
 /*
- * $Id$
+ * $Id: ls.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
  * From: $NetBSD: ls.c,v 1.3 1997/06/13 13:48:47 drochner Exp $
  */
 
@@ -57,9 +57,8 @@ command_ls(int argc, char *argv[])
     int		fd;
     struct stat	sb;
     size_t	size;
-    char	dirbuf[DIRBLKSIZ];
-    char	pathbuf[128];	/* XXX path length constant? */
-    char	buf[128];	/* must be long enough for dir entry! */
+    static char	dirbuf[DIRBLKSIZ];
+    static char	buf[128];	/* must be long enough for full pathname */
     char	*path;
     int		result, ch;
 #ifdef VERBOSE_LS
@@ -138,10 +137,12 @@ command_ls(int argc, char *argv[])
 		    if (verbose) {
 			/* stat the file, if possible */
 			sb.st_size = 0;
-			sprintf(buf, "%s/%s", pathbuf, dp->d_name);
+			sprintf(buf, "%s/%s", path, dp->d_name);
 			/* ignore return */
-			if (stat(buf, &sb))
+			if (stat(buf, &sb)) {
+			    printf("stat(%s) failed: %s\n", buf, strerror(errno));
 			    sb.st_size = -1;
+			}
 			sprintf(buf, " %c %8d %s\n", typestr[dp->d_type], (int)sb.st_size, dp->d_name);
 #endif
 		    } else
diff --git a/sys/boot/common/misc.c b/sys/boot/common/misc.c
index 98ec3deb2c52..2999da5ba50f 100644
--- a/sys/boot/common/misc.c
+++ b/sys/boot/common/misc.c
@@ -23,11 +23,12 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id$
+ *	$Id: misc.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
  */
 
 #include <string.h>
 #include <stand.h>
+#include <bootstrap.h>
 
 /*
  * Concatenate the (argc) elements of (argv) into a single string, and return
@@ -53,3 +54,36 @@ unargv(int argc, char *argv[])
     return(cp);
 }
 
+/*
+ * Get the length of a string in kernel space
+ */
+size_t
+strlenout(vm_offset_t src)
+{
+    char	c;
+    size_t	len;
+    
+    for (len = 0; ; len++) {
+	archsw.arch_copyout(src++, &c, 1);
+	if (c == 0)
+	    break;
+    }
+    return(len);
+}
+
+/*
+ * Make a duplicate copy of a string in kernel space
+ */
+char *
+strdupout(vm_offset_t str)
+{
+    char	*result, *cp;
+    
+    result = malloc(strlenout(str) + 1);
+    for (cp = result; ;cp++) {
+	archsw.arch_copyout(str++, cp, 1);
+	if (*cp == 0)
+	    break;
+    }
+    return(result);
+}
diff --git a/sys/boot/common/module.c b/sys/boot/common/module.c
index 28c10dc71ebb..f10fe3bafeaf 100644
--- a/sys/boot/common/module.c
+++ b/sys/boot/common/module.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id: module.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
+ *	$Id: module.c,v 1.2 1998/08/31 21:10:42 msmith Exp $
  */
 
 /*
@@ -38,16 +38,68 @@
 
 #include "bootstrap.h"
 
+static struct loaded_module	*mod_loadmodule(char *name, int argc, char *argv[]);
+static char			*mod_searchdep(struct loaded_module *mp);
+static char			*mod_searchmodule(char *name);
+static void			mod_append(struct loaded_module *mp);
+
 /* XXX load address should be tweaked by first module loaded (kernel) */
 static vm_offset_t	loadaddr = 0;
 
 struct loaded_module *loaded_modules = NULL;
 
+/*
+ * load an object, either a disk file or code module.
+ *
+ * To load a file, the syntax is:
+ *
+ * load -t <type> <path>
+ *
+ * code modules are loaded as:
+ *
+ * load <path> <options>
+ */
+
 COMMAND_SET(load, "load", "load a kernel or module", command_load);
 
 static int
 command_load(int argc, char *argv[])
 {
+    char	*typestr;
+    int		dofile, ch;
+    
+    dofile = 0;
+    optind = 1;
+    typestr = NULL;
+    while ((ch = getopt(argc, argv, "t:")) != -1) {
+	switch(ch) {
+	case 't':
+	    typestr = optarg;
+	    dofile = 1;
+	    break;
+	case '?':
+	default:
+	    /* getopt has already reported an error */
+	    return(CMD_OK);
+	}
+    }
+    argv += (optind - 1);
+    argc -= (optind - 1);
+
+    /*
+     * Request to load a raw file?
+     */
+    if (dofile) {
+	if ((typestr == NULL) || (*typestr == 0)) {
+	    command_errmsg = "invalid load type";
+	    return(CMD_ERROR);
+	}
+	return(mod_loadobj(typestr, argv[1]));
+    }
+    
+    /*
+     * Looks like a request for a module.
+     */
     return(mod_load(argv[1], argc - 2, argv + 2));
 }
 
@@ -57,21 +109,11 @@ static int
 command_unload(int argc, char *argv[])
 {
     struct loaded_module	*mp;
-    struct module_metadata	*md;
     
     while (loaded_modules != NULL) {
 	mp = loaded_modules;
 	loaded_modules = loaded_modules->m_next;
-	while (mp->m_metadata != NULL) {
-	    md = mp->m_metadata;
-	    mp->m_metadata = mp->m_metadata->md_next;
-	    free(md);
-	}
-	free(mp->m_name);
-	free(mp->m_type);
-	if (mp->m_args != NULL)
-	    free(mp->m_args);
-	free(mp);
+	mod_discard(mp);
     }
     loadaddr = 0;
     return(CMD_OK);
@@ -83,8 +125,24 @@ static int
 command_lsmod(int argc, char *argv[])
 {
     struct loaded_module	*am;
+    struct module_metadata	*md;
     char			lbuf[80];
-    
+    int				ch, verbose;
+
+    verbose = 0;
+    optind = 1;
+    while ((ch = getopt(argc, argv, "v")) != -1) {
+	switch(ch) {
+	case 'v':
+	    verbose = 1;
+	    break;
+	case '?':
+	default:
+	    /* getopt has already reported an error */
+	    return(CMD_OK);
+	}
+    }
+
     pager_open();
     for (am = loaded_modules; (am != NULL); am = am->m_next) {
 	sprintf(lbuf, " %x: %s (%s, 0x%x)\n", 
@@ -95,20 +153,141 @@ command_lsmod(int argc, char *argv[])
 	    pager_output(am->m_args);
 	    pager_output("\n");
 	}
+	if (verbose)
+	    /* XXX could add some formatting smarts here to display some better */
+	    for (md = am->m_metadata; md != NULL; md = md->md_next) {
+		sprintf(lbuf, "      0x%04x, 0x%x\n", md->md_type, md->md_size);
+		pager_output(lbuf);
+	    }
     }
     pager_close();
     return(CMD_OK);
 }
 
+/*
+ * We've been asked to load (name) and give it (argc),(argv).
+ * Start by trying to load it, and then attempt to load all of its 
+ * dependancies.  If we fail at any point, throw them all away and
+ * fail the entire load.
+ *
+ * XXX if a depended-on module requires arguments, it must be loaded
+ *     explicitly first.
+ */
 int
 mod_load(char *name, int argc, char *argv[])
 {
-    struct loaded_module	*am, *cm;
-    int				i, err;
+    struct loaded_module	*last_mod, *base_mod, *mp;
+    char			*dep_name;
+
+    /* remember previous last module on chain */
+    for (last_mod = loaded_modules; 
+	 (last_mod != NULL) && (last_mod->m_next != NULL);
+	 last_mod = last_mod->m_next)
+	;
     
-    for (i = 0, am = NULL; (module_formats[i] != NULL) && (am == NULL); i++) {
-	/* XXX call searchmodule() to search for module (name) */
-	if ((err = (module_formats[i]->l_load)(name, loadaddr, &am)) != 0) {
+    /* 
+     * Load the first module; note that it's the only one that gets
+     * arguments explicitly.
+     */
+    if ((base_mod = mod_loadmodule(name, argc, argv)) == NULL)
+	return(CMD_ERROR);
+
+    /*
+     * Look for dependancies.
+     */
+    while ((dep_name = mod_searchdep(base_mod)) != NULL) {
+	printf("loading required module '%s'\n", dep_name);
+	if ((mp = mod_loadmodule(dep_name, 0, NULL)) == NULL) {
+	    /* Load failed; discard everything */
+	    while (base_mod != NULL) {
+		mp = base_mod;
+		base_mod = base_mod->m_next;
+		mod_discard(mp);
+	    }
+	    last_mod->m_next = NULL;
+	    loadaddr = last_mod->m_addr + last_mod->m_size;
+	    /* error message already set by mod_loadmodule */
+	    return(CMD_ERROR);
+	}
+    }
+    return(CMD_OK);
+}
+
+/*
+ * We've been asked to load (name) as (type), so just suck it in,
+ * no arguments or anything.
+ */
+int
+mod_loadobj(char *type, char *name)
+{
+    struct loaded_module	*mp;
+    char			*cp;
+    int				fd, got;
+    vm_offset_t			laddr;
+
+    /* We can't load first */
+    if ((mod_findmodule(NULL, NULL)) == NULL) {
+	command_errmsg = "can't load file before kernel";
+	return(CMD_ERROR);
+    }
+
+    /* Try to come up with a fully-qualified name if we don't have one */
+    if ((cp = mod_searchmodule(name)) != NULL)
+	name = cp;
+    
+    if ((fd = open(name, O_RDONLY)) < 0) {
+	sprintf(command_errbuf, "can't open '%s': %s", name, strerror(errno));
+	return(CMD_ERROR);
+    }
+
+    laddr = loadaddr;
+    for (;;) {
+	/* read in 4k chunks; size is not really important */
+	got = archsw.arch_readin(fd, laddr, 4096);
+	if (got == 0)				/* end of file */
+	    break;
+	if (got < 0) {				/* error */
+	    sprintf(command_errbuf, "error reading '%s': %s", name, strerror(errno));
+	    return(CMD_ERROR);
+	}
+	laddr += got;
+    }
+    
+    /* Looks OK so far; create & populate control structure */
+    mp = malloc(sizeof(struct loaded_module));
+    mp->m_name = strdup(name);
+    mp->m_type = strdup(type);
+    mp->m_args = NULL;
+    mp->m_metadata = NULL;
+    mp->m_loader = -1;
+    mp->m_addr = loadaddr;
+    mp->m_size = laddr - loadaddr;
+
+    /* recognise space consumption */
+    loadaddr = laddr;
+
+    /* Add to the list of loaded modules */
+    mod_append(mp);
+    return(CMD_OK);
+}
+
+/*
+ * Load the module (name), pass it (argc),(argv).
+ * Don't do any dependancy checking.
+ */
+static struct loaded_module *
+mod_loadmodule(char *name, int argc, char *argv[])
+{
+    struct loaded_module	*mp;
+    int				i, err;
+    char			*cp;
+
+    /* Try to come up with a fully-qualified name if we don't have one */
+    if ((cp = mod_searchmodule(name)) != NULL)
+	name = cp;
+    err = 0;
+    for (i = 0, mp = NULL; (module_formats[i] != NULL) && (mp == NULL); i++) {
+	if ((err = (module_formats[i]->l_load)(name, loadaddr, &mp)) != 0) {
 
 	    /* Unknown to this handler? */
 	    if (err == EFTYPE)
@@ -116,34 +295,87 @@ mod_load(char *name, int argc, char *argv[])
 		
 	    /* Fatal error */
 	    sprintf(command_errbuf, "can't load module '%s': %s", name, strerror(err));
-	    return(CMD_ERROR);
+	    return(NULL);
 	} else {
+
+	    /* Load was OK, set args */
+	    mp->m_args = unargv(argc, argv);
+
+	    /* where can we put the next one? */
+	    loadaddr = mp->m_addr + mp->m_size;
+	
 	    /* remember the loader */
-	    am->m_loader = i;
+	    mp->m_loader = i;
+
+	    /* Add to the list of loaded modules */
+	    mod_append(mp);
+
+	    break;
 	}
     }
-    if (am == NULL) {
-	sprintf(command_errbuf, "can't work out what to do with '%s'", name);
-	return(CMD_ERROR);
-    }
-    /* where can we put the next one? */
-    loadaddr = am->m_addr + am->m_size;
-	
-    /* Load was OK, set args */
-    am->m_args = unargv(argc, argv);
-
-    /* Append to list of loaded modules */
-    am->m_next = NULL;
-    if (loaded_modules == NULL) {
-	loaded_modules = am;
-    } else {
-	for (cm = loaded_modules; cm->m_next != NULL; cm = cm->m_next)
-	    ;
-	cm->m_next = am;
-    }
-    return(CMD_OK);
+    if (err == EFTYPE)
+	sprintf(command_errbuf, "don't know how to load module '%s'", name);
+    return(mp);
 }
 
+/*
+ * Search the modules from (mp) onwards, and return the name of the
+ * first unresolved dependancy, or NULL if none were found.
+ */
+static char *
+mod_searchdep(struct loaded_module *mp)
+{
+    struct kld_module_identifier	*ident, *dident;
+    struct kld_module_dependancy	*deps, *dp;
+    struct module_metadata		*md;
+    struct loaded_module		*dmp;
+    int					dindex;
+
+    for (; mp != NULL; mp = mp->m_next) {
+
+	/*
+	 * Get KLD module data
+	 */
+	ident = NULL;
+	deps = NULL;
+	if ((md = mod_findmetadata(mp, MODINFOMD_KLDIDENT)) != NULL)
+	    ident = (struct kld_module_identifier *)md->md_data;
+	if ((md = mod_findmetadata(mp, MODINFOMD_KLDDEP)) != NULL)
+	    deps = (struct kld_module_dependancy *)md->md_data;
+	
+	/*
+	 * Both must exist for this module to depend on anything
+	 */
+	if ((ident != NULL) && (deps != NULL)) {
+	    
+	    /* Iterate over dependancies */
+	    for (dindex = 0; dindex < ident->ki_ndeps; dindex++) {
+		dp = KLD_GETDEP(ident, deps, dindex);
+		
+		/* 
+		 * Look for a module matching the dependancy; if we don't have it,
+		 * we need it.
+		 */
+		if ((dmp = mod_findmodule(dp->kd_name, NULL)) == NULL)
+		    return(dp->kd_name);
+		
+		/* Version check */
+		if ((md = mod_findmetadata(dmp, MODINFOMD_KLDIDENT)) != NULL) {
+		    dident = (struct kld_module_identifier *)md->md_data;
+		    if (dp->kd_version != dident->ki_version)
+			printf("module '%s' requires '%s' version %d, but version %d is loaded\n", 
+			       mp->m_name, dp->kd_name, dp->kd_version, dident->ki_version);
+		}
+	    }
+	}
+    }
+    return(NULL);
+}
+
+/*
+ * Find a module matching (name) and (type).
+ * NULL may be passed as a wildcard to either.
+ */
 struct loaded_module *
 mod_findmodule(char *name, char *type)
 {
@@ -157,6 +389,10 @@ mod_findmodule(char *name, char *type)
     return(mp);
 }
 
+/*
+ * Make a copy of (size) bytes of data from (p), and associate them as
+ * metadata of (type) to the module (mp).
+ */
 void
 mod_addmetadata(struct loaded_module *mp, int type, size_t size, void *p)
 {
@@ -170,6 +406,10 @@ mod_addmetadata(struct loaded_module *mp, int type, size_t size, void *p)
     mp->m_metadata = md;
 }
 
+/*
+ * Find a metadata object of (type) associated with the module
+ * (mp)
+ */
 struct module_metadata *
 mod_findmetadata(struct loaded_module *mp, int type)
 {
@@ -180,3 +420,101 @@ mod_findmetadata(struct loaded_module *mp, int type)
 	    break;
     return(md);
 }
+
+/*
+ * Attempt to locate a kernel module file for the module (name).
+ * If (name) is qualified in any way, we simply check it and
+ * return it or NULL.  If it is not qualified, then we attempt
+ * to construct a path using entries in the environment variable
+ * module_path.
+ *
+ * The path we return a pointer to need never be freed, as we manage
+ * it internally.
+ */
+static char *
+mod_searchmodule(char *name)
+{
+    static char		*result = NULL;
+    static char		*defpath = "/boot", *path;
+    char		*cp, *sp;
+    struct stat		sb;
+
+    /* Don't look for nothing */
+    if ((name == NULL) || (*name == 0))
+	return(name);
+
+    /*
+     * See if there's a device on the front, or a directory name.
+     */
+    archsw.arch_getdev(NULL, name, &cp);
+    if ((cp != name) || (strchr(name, '/') != NULL)) {
+	/* Qualified, so just see if it exists */
+	if (stat(name, &sb) == 0)
+	    return(name);
+	return(NULL);
+    }
+    
+    /*
+     * Get the module path
+     */
+    if ((cp = getenv("module_path")) == NULL)
+	cp = defpath;
+    sp = path = strdup(cp);
+    
+    /*
+     * Traverse the path, splitting off ';'-delimited components.
+     */
+    if (result != NULL)
+	free(result);
+    while((cp = strsep(&path, ";")) != NULL) {
+	result = malloc(strlen(cp) + strlen(name) + 2);
+	sprintf(result, "%s/%s", cp, name);
+	if (stat(result, &sb) == 0)
+	    break;
+	free(result);
+	result = NULL;
+    }
+    free(sp);
+    return(result);
+}
+
+/*
+ * Throw a module away
+ */
+void
+mod_discard(struct loaded_module *mp)
+{
+    struct module_metadata	*md;
+
+    while (mp->m_metadata != NULL) {
+	md = mp->m_metadata;
+	mp->m_metadata = mp->m_metadata->md_next;
+	free(md);
+    }	
+    if (mp->m_name != NULL)
+	free(mp->m_name);
+    if (mp->m_type != NULL)
+	free(mp->m_type);
+    if (mp->m_args != NULL)
+	free(mp->m_args);
+    free(mp);
+}
+
+/*
+ * Add a module to the chain
+ */
+static void
+mod_append(struct loaded_module *mp)
+{
+    struct loaded_module	*cm;
+    
+    /* Append to list of loaded modules */
+    mp->m_next = NULL;
+    if (loaded_modules == NULL) {
+	loaded_modules = mp;
+    } else {
+	for (cm = loaded_modules; cm->m_next != NULL; cm = cm->m_next)
+	    ;
+	cm->m_next = mp;
+    }
+}
diff --git a/sys/boot/i386/installboot/installboot.c b/sys/boot/i386/installboot/installboot.c
index a5bfd3b5b6da..12e75bc89883 100644
--- a/sys/boot/i386/installboot/installboot.c
+++ b/sys/boot/i386/installboot/installboot.c
@@ -59,7 +59,7 @@
 
 #include "bbinfo.h"
 
-#define DEFBBLKNAME "boot"
+#define DEFBBLKNAME "loader"
 
 struct fraglist *fraglist;
 
diff --git a/sys/boot/i386/libi386/bootinfo.c b/sys/boot/i386/libi386/bootinfo.c
index 8554f2a83dc7..041ccb81f6f8 100644
--- a/sys/boot/i386/libi386/bootinfo.c
+++ b/sys/boot/i386/libi386/bootinfo.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id$
+ *	$Id: bootinfo.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
  */
 
 #include <sys/reboot.h>
@@ -191,7 +191,8 @@ bi_copymodules(vm_offset_t addr)
 	MOD_ADDR(addr, mp->m_addr);
 	MOD_SIZE(addr, mp->m_size);
 	for (md = mp->m_metadata; md != NULL; md = md->md_next)
-	    MOD_METADATA(addr, md);
+	    if (!(md->md_type & MODINFOMD_NOCOPY))
+		MOD_METADATA(addr, md);
     }
     return(addr);
 }
diff --git a/sys/boot/i386/libi386/bootinfo32.c b/sys/boot/i386/libi386/bootinfo32.c
index 8554f2a83dc7..041ccb81f6f8 100644
--- a/sys/boot/i386/libi386/bootinfo32.c
+++ b/sys/boot/i386/libi386/bootinfo32.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id$
+ *	$Id: bootinfo.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
  */
 
 #include <sys/reboot.h>
@@ -191,7 +191,8 @@ bi_copymodules(vm_offset_t addr)
 	MOD_ADDR(addr, mp->m_addr);
 	MOD_SIZE(addr, mp->m_size);
 	for (md = mp->m_metadata; md != NULL; md = md->md_next)
-	    MOD_METADATA(addr, md);
+	    if (!(md->md_type & MODINFOMD_NOCOPY))
+		MOD_METADATA(addr, md);
     }
     return(addr);
 }
diff --git a/sys/boot/i386/libi386/bootinfo64.c b/sys/boot/i386/libi386/bootinfo64.c
index 8554f2a83dc7..041ccb81f6f8 100644
--- a/sys/boot/i386/libi386/bootinfo64.c
+++ b/sys/boot/i386/libi386/bootinfo64.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id$
+ *	$Id: bootinfo.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
  */
 
 #include <sys/reboot.h>
@@ -191,7 +191,8 @@ bi_copymodules(vm_offset_t addr)
 	MOD_ADDR(addr, mp->m_addr);
 	MOD_SIZE(addr, mp->m_size);
 	for (md = mp->m_metadata; md != NULL; md = md->md_next)
-	    MOD_METADATA(addr, md);
+	    if (!(md->md_type & MODINFOMD_NOCOPY))
+		MOD_METADATA(addr, md);
     }
     return(addr);
 }
diff --git a/sys/boot/i386/libi386/i386_copy.c b/sys/boot/i386/libi386/i386_copy.c
index c6ddf240e5f0..8f614204681c 100644
--- a/sys/boot/i386/libi386/i386_copy.c
+++ b/sys/boot/i386/libi386/i386_copy.c
@@ -19,6 +19,14 @@ i386_copyin(void *src, vm_offset_t dest, size_t len)
     return(len);
 }
 
+int
+i386_copyout(vm_offset_t src, void *dest, size_t len)
+{
+    pvbcopy(src, dest, len);
+    return(len);
+}
+
+
 int
 i386_readin(int fd, vm_offset_t dest, size_t len)
 {
diff --git a/sys/boot/i386/libi386/libi386.h b/sys/boot/i386/libi386/libi386.h
index 8d489f840651..abecb349dfdc 100644
--- a/sys/boot/i386/libi386/libi386.h
+++ b/sys/boot/i386/libi386/libi386.h
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id: libi386.h,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
+ *	$Id: libi386.h,v 1.2 1998/08/31 21:10:43 msmith Exp $
  */
 
 
@@ -64,20 +64,18 @@ extern struct devdesc	currdev;	/* our current device */
 extern struct devsw biosdisk;
 
 /* from crt module */
-extern void		vpbcopy(void*, vm_offset_t, int);
-extern void		pvbcopy(vm_offset_t, void*, int);
-extern void		pbzero(vm_offset_t, int);
-extern vm_offset_t	vtophys(void*);
+extern void		vpbcopy(void *src, vm_offset_t dest, size_t size);
+extern void		pvbcopy(vm_offset_t src, void *dest, size_t size);
+extern void		pbzero(vm_offset_t dest, size_t size);
+extern vm_offset_t	vtophys(void *addr);
 
 extern int		i386_copyin(void *src, vm_offset_t dest, size_t len);
+extern int		i386_copyout(vm_offset_t src, void *dest, size_t len);
 extern int		i386_readin(int fd, vm_offset_t dest, size_t len);
 
-/* XXX pread deprecated */
-extern int		pread(int, vm_offset_t, int);
+extern void		startprog(vm_offset_t entry, int argc, u_int32_t *argv, vm_offset_t stack);
 
-extern void		startprog(vm_offset_t, int, u_int32_t *, vm_offset_t);
-
-extern void		delay(int);
+extern void		delay(int delay);
 extern int		getbasemem(void);
 extern int		getextmem(void);
 
diff --git a/sys/boot/i386/loader/main.c b/sys/boot/i386/loader/main.c
index ded0d5a6af33..ee7d5752498f 100644
--- a/sys/boot/i386/loader/main.c
+++ b/sys/boot/i386/loader/main.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id: main.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
+ *	$Id: main.c,v 1.2 1998/08/31 21:10:43 msmith Exp $
  */
 
 /*
@@ -102,19 +102,14 @@ main(void)
     archsw.arch_autoload = i386_autoload;
     archsw.arch_getdev = i386_getdev;
     archsw.arch_copyin = i386_copyin;
+    archsw.arch_copyout = i386_copyout;
     archsw.arch_readin = i386_readin;
     /*
      * XXX should these be in the MI source?
      */
-    source("/boot/boot.conf");
 #if 0
     legacy_config();		/* read old /boot.config file */
 #endif
-    printf("\n");
-    autoboot(10, NULL);		/* try to boot automatically */
-    printf("\nType '?' for a list of commands, 'help' for more detailed help.\n");
-    setenv("prompt", "$currdev>", 1);
-    
     interact();			/* doesn't return */
 }
 
diff --git a/sys/boot/ofw/libofw/ofw_copy.c b/sys/boot/ofw/libofw/ofw_copy.c
index 9e164de0dbad..250c41692dc6 100644
--- a/sys/boot/ofw/libofw/ofw_copy.c
+++ b/sys/boot/ofw/libofw/ofw_copy.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id$
+ *	$Id: alpha_copy.c,v 1.1 1998/08/31 21:10:40 msmith Exp $
  */
 /*
  * MD primitives supporting placement of module data 
@@ -41,6 +41,13 @@ alpha_copyin(void *src, vm_offset_t dest, size_t len)
     return(len);
 }
 
+int
+alpha_copyout(void *src, vm_offset_t dest, size_t len)
+{
+    bcopy(src, dest, len);
+    return(len);
+}
+
 int
 alpha_readin(int fd, vm_offset_t dest, size_t len)
 {