Bootloader update.

- Implement a new copyin/readin interface for loading modules.
   This allows the module loaders to become MI, reducing code duplication.
 - Simplify the search for an image activator for the loaded kernel.
 - Use the common module management code for all module metadata.
 - Add an 'unload' command that throws everything away.
 - Move the a.out module loader to MI code, add support for a.out
   kld modules.

Submitted by:	Alpha changes fixed by Doug Rabson <dfr@freebsd.org>
This commit is contained in:
Mike Smith 1998-08-31 21:10:43 +00:00
parent f471c44869
commit c73b70eec4
27 changed files with 528 additions and 2502 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* $Id$
* $Id: conf.c,v 1.1.1.1 1998/08/21 03:17:42 msmith Exp $
* From $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $
*/
@ -64,6 +64,8 @@ struct fs_ops *file_system[] = {
* Sort formats so that those that can detect based on arguments
* rather than reading the file go first.
*/
extern struct module_format alpha_elf;
struct module_format *module_formats[] = {
&alpha_elf,
NULL

View File

@ -1,2 +0,0 @@
/* $Id$ */
DEFINE_SET(Xcommand_set, 15);

View File

@ -1,4 +0,0 @@
char bootprog_name[] = "FreeBSD/alpha SRM disk boot";
char bootprog_rev[] = "0.1";
char bootprog_date[] = "Mon Aug 17 10:38:19 BST 1998";
char bootprog_maker[] = "dfr@salmon.nlsystems.com";

View File

@ -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.1.1.1 1998/08/21 03:17:42 msmith Exp $
* $Id: main.c,v 1.2 1998/08/22 10:31:00 dfr Exp $
*/
@ -116,8 +116,9 @@ main(void)
setenv("LINES", "24", 1); /* optional */
archsw.arch_autoload = alpha_autoload;
archsw.arch_boot = alpha_boot;
archsw.arch_getdev = alpha_getdev;
archsw.arch_copyin = alpha_copyin;
archsw.arch_readin = alpha_readin;
/*
* SRM firmware takes *ages* to open the disk device. We hold it

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.1.1.1 1998/08/21 03:17:42 msmith Exp $
# $Id: Makefile,v 1.2 1998/08/22 10:31:01 dfr Exp $
LIB= alpha
NOPIC= true
@ -18,7 +18,7 @@ CFLAGS+= -DDISK_DEBUG
SRCS= OSFpal.c elf_freebsd.c prom.c prom_disp.S prom_swpal.S start.S \
pal.S reboot.c delay.c time.c alpha_module.c devicename.c \
srmdisk.c srmnet.c getsecs.c
srmdisk.c srmnet.c getsecs.c alpha_copy.c
all: libalpha.a

View File

@ -0,0 +1,50 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
/*
* MD primitives supporting placement of module data
*
* XXX should check load address/size against memory top.
*/
#include <stand.h>
#include "libalpha.h"
int
alpha_copyin(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)
{
return(read(fd, dest, len));
}

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: alpha_module.c,v 1.1.1.1 1998/08/21 03:17:42 msmith Exp $
*/
/*
@ -37,22 +37,6 @@
#include "bootstrap.h"
#include "libalpha.h"
/*
* Look for a method and having found it, boot the kernel module.
*/
int
alpha_boot(void)
{
int i;
for (i = 0; module_formats[i] != NULL; i++) {
if (((loaded_modules->m_flags & MF_FORMATMASK) == module_formats[i]->l_format) &&
(module_formats[i]->l_exec != NULL)) {
return((module_formats[i]->l_exec)(loaded_modules));
}
}
}
/*
* Use voodoo to load modules required by current hardware.
*/

View File

@ -1,4 +1,4 @@
/* $Id$ */
/* $Id: elf_freebsd.c,v 1.1.1.1 1998/08/21 03:17:42 msmith Exp $ */
/* $NetBSD: loadfile.c,v 1.10 1998/06/25 06:45:46 ross Exp $ */
/*-
@ -89,18 +89,11 @@
#define _KERNEL
struct elf_kernel_module
{
struct loaded_module m;
vm_offset_t m_entry; /* module entrypoint */
struct bootinfo_v1 m_bi; /* legacy bootinfo */
};
static int elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result);
static int elf_exec(struct loaded_module *amp);
static int elf_load(int fd, Elf_Ehdr *elf, vm_offset_t dest);
struct module_format alpha_elf = { MF_ELF, elf_loadmodule, elf_exec };
struct module_format alpha_elf = { elf_loadmodule, elf_exec };
vm_offset_t ffp_save, ptbr_save;
vm_offset_t ssym, esym;
@ -108,7 +101,7 @@ vm_offset_t ssym, esym;
static int
elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
{
struct elf_kernel_module *mp;
struct loaded_module *mp;
Elf_Ehdr hdr;
ssize_t nr;
int fd, rval;
@ -137,21 +130,23 @@ elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
/*
* Ok, we think this is for us.
*/
mp = malloc(sizeof(struct elf_kernel_module));
mp->m.m_name = strdup(filename); /* XXX should we prune the name? */
mp->m.m_type = "elf kernel"; /* XXX only if that's what we really are */
mp->m.m_args = NULL; /* XXX should we put the bootstrap args here and parse later? */
mp->m.m_flags = MF_ELF; /* we're an elf kernel */
mp->m_entry = hdr.e_entry;
if (dest == 0)
dest = (vm_offset_t) hdr.e_entry;
if (mod_findmodule(NULL, mp->m.m_type) != NULL) {
mp = malloc(sizeof(struct loaded_module));
mp->m_name = strdup(filename); /* XXX should we prune the name? */
mp->m_type = strdup("elf kernel"); /* XXX only if that's what we really are */
mp->m_args = NULL; /* XXX should we put the bootstrap args here and parse later? */
mp->m_metadata = NULL;
dest = (vm_offset_t) hdr.e_entry;
mp->m_addr = dest;
if (mod_findmodule(NULL, NULL) != NULL) {
printf("elf_loadmodule: kernel already loaded\n");
rval = EPERM;
goto err;
}
rval = elf_load(fd, &hdr, (vm_offset_t) dest);
/* save ELF header as metadata */
mod_addmetadata(mp, MODINFOMD_ELFHDR, sizeof(Elf_Ehdr), &hdr);
*result = (struct loaded_module *)mp;
err:
@ -284,10 +279,15 @@ elf_load(int fd, Elf_Ehdr *elf, vm_offset_t dest)
}
static int
elf_exec(struct loaded_module *amp)
elf_exec(struct loaded_module *mp)
{
struct elf_kernel_module *mp = (struct elf_kernel_module *)amp;
static struct bootinfo_v1 bootinfo_v1;
static struct bootinfo_v1 bootinfo_v1;
struct module_metadata *md;
Elf_Ehdr *hdr;
if ((md = mod_findmetadata(mp, MODINFOMD_ELFHDR)) == NULL)
return(EFTYPE); /* XXX actually EFUCKUP */
hdr = (Elf_Ehdr *)&(md->md_data);
/*
* Fill in the bootinfo for the kernel.
@ -295,7 +295,7 @@ elf_exec(struct loaded_module *amp)
bzero(&bootinfo_v1, sizeof(bootinfo_v1));
bootinfo_v1.ssym = ssym;
bootinfo_v1.esym = esym;
strncpy(bootinfo_v1.booted_kernel, mp->m.m_name,
strncpy(bootinfo_v1.booted_kernel, mp->m_name,
sizeof(bootinfo_v1.booted_kernel));
prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo_v1.boot_flags,
sizeof(bootinfo_v1.boot_flags));
@ -305,10 +305,10 @@ elf_exec(struct loaded_module *amp)
bootinfo_v1.cnputc = NULL;
bootinfo_v1.cnpollc = NULL;
printf("Entering %s at 0x%lx...\n", mp->m.m_name, mp->m_entry);
printf("Entering %s at 0x%lx...\n", mp->m_name, hdr->e_entry);
closeall();
alpha_pal_imb();
(*(void (*)())mp->m_entry)(ffp_save, ptbr_save,
(*(void (*)())hdr->e_entry)(ffp_save, ptbr_save,
BOOTINFO_MAGIC, &bootinfo_v1, 1, 0);
}

View File

@ -1,4 +1,4 @@
/* $Id$ */
/* $Id: libalpha.h,v 1.1.1.1 1998/08/21 03:17:42 msmith Exp $ */
/*
* Copyright (c) 1996
@ -74,34 +74,8 @@ extern struct netif_driver srmnet;
extern void delay(int);
extern void reboot(void);
/*
* alpha module loader
*/
#define MF_FORMATMASK 0xf
#define MF_AOUT 0 /* not supported */
#define MF_ELF 1
extern int alpha_copyin(void *src, vm_offset_t dest, size_t len);
extern int alpha_readin(int fd, vm_offset_t dest, size_t len);
struct alpha_module
{
char *m_name; /* module name */
char *m_type; /* module type, eg 'kernel', 'pnptable', etc. */
char *m_args; /* arguments for the module */
int m_flags; /* 0xffff reserved for arch-specific use */
struct alpha_module *m_next; /* next module */
physaddr_t m_addr; /* load address */
size_t m_size; /* module size */
};
struct alpha_format
{
int l_format;
/* Load function must return EFTYPE if it can't handle the module supplied */
int (* l_load)(char *filename, physaddr_t dest, struct alpha_module **result);
int (* l_exec)(struct alpha_module *amp);
};
extern struct alpha_format *formats[]; /* supplied by consumer */
extern struct alpha_format alpha_elf;
extern int alpha_boot(void);
extern int alpha_autoload(void);
extern struct alpha_module *alpha_findmodule(char *name, char *type);
extern int alpha_boot(void);
extern int alpha_autoload(void);

View File

@ -1,5 +1,5 @@
/*
* $Id$
* $Id: conf.c,v 1.1.1.1 1998/08/21 03:17:42 msmith Exp $
* From: $NetBSD: conf.c,v 1.2 1997/03/22 09:03:29 thorpej Exp $
*/
@ -70,6 +70,8 @@ struct netif_driver *netif_drivers[] = {
* Sort formats so that those that can detect based on arguments
* rather than reading the file go first.
*/
extern struct module_format alpha_elf;
struct module_format *module_formats[] = {
&alpha_elf,
NULL

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +0,0 @@
/* $Id$ */
DEFINE_SET(Xcommand_set, 15);

View File

@ -1,4 +0,0 @@
char bootprog_name[] = "FreeBSD/alpha SRM net boot";
char bootprog_rev[] = "0.1";
char bootprog_date[] = "Mon Aug 17 10:38:31 BST 1998";
char bootprog_maker[] = "dfr@salmon.nlsystems.com";

View File

@ -1,4 +1,4 @@
# $Id$
# $Id: Makefile.inc,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
SRCS+= boot.c commands.c console.c devopen.c interp.c ls.c misc.c module.c
SRCS+= panic.c
SRCS+= boot.c commands.c console.c devopen.c interp.c load_aout.c
SRCS+= ls.c misc.c module.c panic.c

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: boot.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
*/
/*
@ -106,7 +106,9 @@ command_boot(int argc, char *argv[])
/* Hook for platform-specific autoloading of modules */
if (archsw.arch_autoload() != 0)
return(CMD_ERROR);
archsw.arch_boot();
/* Call the exec handler from the loader matching the kernel */
module_formats[km->m_loader]->l_exec(km);
return(CMD_ERROR);
}

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: bootstrap.h,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
*/
#include <sys/types.h>
@ -84,13 +84,6 @@ struct console
extern struct console *consoles[];
extern void cons_probe(void);
/*
* Module loader.
*/
#define MF_FORMATMASK 0xf
#define MF_AOUT 0
#define MF_ELF 1
/*
* Module metadata header.
*
@ -110,14 +103,16 @@ struct module_metadata
*
* At least one module (the kernel) must be loaded in order to boot.
* The kernel is always loaded first.
*
* String fields (m_name, m_type) should be dynamically allocated.
*/
struct loaded_module
{
char *m_name; /* module name */
char *m_type; /* module type, eg 'kernel', 'pnptable', etc. */
char *m_type; /* verbose module type, eg 'ELF kernel', 'pnptable', etc. */
char *m_args; /* arguments for the module */
void *m_metadata; /* metadata that will be placed in the module directory */
int m_flags; /* 0xffff reserved for arch-specific use */
struct module_metadata *m_metadata; /* metadata that will be placed in the module directory */
int m_loader; /* index of the loader that read the file */
vm_offset_t m_addr; /* load address */
size_t m_size; /* module size */
struct loaded_module *m_next; /* next module */
@ -125,16 +120,21 @@ struct loaded_module
struct module_format
{
int l_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);
};
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 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);
/*
* Module information subtypes
*/
/* XXX these belong in <machine/bootinfo.h> */
#define MODINFO_NAME 0x0000
#define MODINFO_TYPE 0x0001
@ -142,6 +142,13 @@ extern struct loaded_module *mod_findmodule(char *name, char *type);
#define MODINFO_SIZE 0x0003
#define MODINFO_METADATA 0x8000
#define MODINFOMD_AOUTEXEC 0x0001 /* a.out exec header */
#define MODINFOMD_ELFHDR 0x0002 /* ELF header */
/* MI module loaders */
extern int aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result);
/* extern int elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result); */
#if defined(__ELF__)
@ -211,16 +218,21 @@ struct bootblk_command
extern struct linker_set Xcommand_set;
/*
* functions called down from the generic code
* The intention of the architecture switch is to provide a convenient
* encapsulation of the interface between the bootstrap MI and MD code.
* MD code may selectively populate the switch at runtime based on the
* actual configuration of the target system.
*/
struct arch_switch
{
/* Automatically load modules as required by detected hardware */
int (* arch_autoload)();
/* Boot the loaded kernel (first loaded module) */
int (* arch_boot)(void);
/* Locate the device for (name), return pointer to tail in (*path) */
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);
/* 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;

202
sys/boot/common/load_aout.c Normal file
View File

@ -0,0 +1,202 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id: aout_freebsd.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
*/
#include <sys/param.h>
#include <sys/exec.h>
#include <sys/imgact_aout.h>
#include <sys/reboot.h>
#include <string.h>
#include <machine/bootinfo.h>
#include <stand.h>
#include "bootstrap.h"
static int aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr);
char *aout_kerneltype = "a.out kernel";
char *aout_moduletype = "a.out module";
/*
* Attempt to load the file (file) as an a.out module. It will be stored at
* (dest), and a pointer to a module structure describing the loaded object
* will be saved in (result).
*/
int
aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
{
struct loaded_module *mp;
struct exec ehdr;
int fd;
vm_offset_t addr;
int err, kernel;
/*
* Open the image, read and validate the a.out header
*/
if (filename == NULL) /* can't handle nameless */
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);
/*
* Check to see what sort of module we are.
*
* XXX should check N_GETMID()
*/
mp = mod_findmodule(NULL, NULL);
if (N_GETFLAG(ehdr) == (EX_DYNAMIC | EX_PIC)) {
/* Looks like a kld module */
if (mp == NULL) {
printf("aout_loadmodule: can't load module before kernel\n");
return(EPERM);
}
if (strcmp(aout_kerneltype, mp->m_type)) {
printf("out_loadmodule: can't load module with kernel type '%s'\n", mp->m_type);
return(EPERM);
}
/* Looks OK, got ahead */
kernel = 0;
} else if (N_GETFLAG(ehdr) == 0) {
/* Looks like a kernel */
if (mp != NULL) {
printf("aout_loadmodule: kernel already loaded\n");
return(EPERM);
}
/*
* Calculate destination address based on kernel entrypoint
* XXX this is i386-freebsd-aout specific
*/
dest = ehdr.a_entry & 0x100000;
if (dest == 0) {
printf("aout_loadmodule: not a kernel (maybe static binary?)\n");
return(EPERM);
}
kernel = 1;
} else {
return(EFTYPE);
}
/*
* 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_type = strdup(kernel ? aout_kerneltype : aout_moduletype);
mp->m_args = NULL; /* XXX should we put the bootstrap args here and parse later? */
mp->m_metadata = NULL;
mp->m_addr = addr = dest;
printf("%s at 0x%x\n", filename, addr);
mp->m_size = aout_loadimage(fd, addr, &ehdr);
if (mp->m_size == 0)
goto ioerr;
/* 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);
ioerr:
err = EIO;
close(fd);
free(mp);
return(err);
}
/*
* With the file (fd) open on the image, and (ehdr) containing
* the exec header, load the image at (addr)
*
* Fixup the a_bss field in (ehdr) to reflect the padding added to
* align the symbol table.
*/
static int
aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr)
{
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);
if (archsw.arch_readin(fd, addr, ehdr->a_text) != ehdr->a_text)
return(0);
addr += ehdr->a_text;
/* data segment */
printf("data=0x%lx ", ehdr->a_data);
if (archsw.arch_readin(fd, addr, ehdr->a_data) != ehdr->a_data)
return(0);
addr += ehdr->a_data;
/* skip the BSS */
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);
if (archsw.arch_readin(fd, addr, ehdr->a_syms) != ehdr->a_syms)
return(0);
addr += ehdr->a_syms;
/* string table */
read(fd, &ss, sizeof(ss));
archsw.arch_copyin(&ss, addr, sizeof(ss));
addr += sizeof(ss);
ss -= sizeof(ss);
printf("+0x%x+0x%x]", sizeof(ss), ss);
if (archsw.arch_readin(fd, addr, ss) != ss)
return(0);
printf(" \n");
addr += ss;
return(addr - loadaddr);
}

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: module.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
*/
/*
@ -38,7 +38,7 @@
#include "bootstrap.h"
/* Initially determined from kernel load address */
/* XXX load address should be tweaked by first module loaded (kernel) */
static vm_offset_t loadaddr = 0;
struct loaded_module *loaded_modules = NULL;
@ -51,6 +51,32 @@ command_load(int argc, char *argv[])
return(mod_load(argv[1], argc - 2, argv + 2));
}
COMMAND_SET(unload, "unload", "unload all modules", command_unload);
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);
}
loadaddr = 0;
return(CMD_OK);
}
COMMAND_SET(lsmod, "lsmod", "list loaded modules", command_lsmod);
static int
@ -61,7 +87,7 @@ command_lsmod(int argc, char *argv[])
pager_open();
for (am = loaded_modules; (am != NULL); am = am->m_next) {
sprintf(lbuf, " %p: %s (%s, 0x%x)\n",
sprintf(lbuf, " %x: %s (%s, 0x%x)\n",
am->m_addr, am->m_name, am->m_type, am->m_size);
pager_output(lbuf);
if (am->m_args != NULL) {
@ -91,6 +117,9 @@ 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);
} else {
/* remember the loader */
am->m_loader = i;
}
}
if (am == NULL) {
@ -127,3 +156,27 @@ mod_findmodule(char *name, char *type)
}
return(mp);
}
void
mod_addmetadata(struct loaded_module *mp, int type, size_t size, void *p)
{
struct module_metadata *md;
md = malloc(sizeof(struct module_metadata) + size);
md->md_size = size;
md->md_type = type;
bcopy(p, md->md_data, size);
md->md_next = mp->m_metadata;
mp->m_metadata = md;
}
struct module_metadata *
mod_findmetadata(struct loaded_module *mp, int type)
{
struct module_metadata *md;
for (md = mp->m_metadata; md != NULL; md = md->md_next)
if (md->md_type == type)
break;
return(md);
}

View File

@ -1,4 +1,4 @@
# $Id$
# $Id: Makefile,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
#
SUBDIR= crt
LIB= i386
@ -7,15 +7,12 @@ NOPROFILE=
SRCS= aout_freebsd.c biosdelay.S biosdisk.c biosdisk_support.S biosgetrtc.S \
biosmem.S biosreboot.S bootinfo.c comconsole.c comconsole_support.S \
devicename.c gatea20.c getsecs.c i386_module.c pread.c startprog.S \
vidconsole.c vidconsole_support.S
devicename.c gatea20.c getsecs.c i386_copy.c i386_module.c \
startprog.S vidconsole.c vidconsole_support.S
CFLAGS+= -I${.CURDIR}/../../common
# Make the disk code more talkative
#CFLAGS+= -DDISK_DEBUG
# Minimise the pread() buffer at the price of slower loads
#CPPFLAGS+= -DSAVE_MEMORY
.include <bsd.lib.mk>

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: aout_freebsd.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
*/
#include <sys/param.h>
@ -37,154 +37,11 @@
#include "bootstrap.h"
#include "libi386.h"
struct aout_kernel_module
{
struct loaded_module m;
vm_offset_t m_entry; /* module entrypoint */
struct bootinfo m_bi; /* legacy bootinfo */
};
static int aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result);
static int aout_exec(struct loaded_module *amp);
struct module_format i386_aout = { MF_AOUT, aout_loadmodule, aout_exec };
static int aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr);
/*
* Attempt to load the file (file) as an a.out module. It will be stored at
* (dest), and a pointer to a module structure describing the loaded object
* will be saved in (result).
*/
static int
aout_loadmodule(char *filename, vm_offset_t dest, struct loaded_module **result)
{
struct aout_kernel_module *mp;
struct exec ehdr;
int fd;
vm_offset_t addr;
int err;
u_int pad;
/*
* Open the image, read and validate the a.out header
*
* XXX what do kld modules look like? We only handle kernels here.
*/
if (filename == NULL) /* can't handle nameless */
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);
/*
* Ok, we think this is for us.
*/
mp = malloc(sizeof(struct aout_kernel_module));
mp->m.m_name = strdup(filename); /* XXX should we prune the name? */
mp->m.m_type = "a.out kernel"; /* XXX only if that's what we really are */
mp->m.m_args = NULL; /* XXX should we put the bootstrap args here and parse later? */
mp->m.m_flags = MF_AOUT; /* we're an a.out kernel */
mp->m_entry = (vm_offset_t)(ehdr.a_entry & 0xffffff);
if (dest == 0)
dest = (vm_offset_t)(ehdr.a_entry & 0x100000);
if (mod_findmodule(NULL, mp->m.m_type) != NULL) {
printf("aout_loadmodule: kernel already loaded\n");
err = EPERM;
goto out;
}
printf("%s at 0x%x\n", filename, dest);
mp->m.m_addr = addr = dest;
mp->m.m_size = aout_loadimage(fd, addr, &ehdr);
printf("\n");
if (mp->m.m_size == 0)
goto ioerr;
/* XXX and if these parts don't exist? */
mp->m_bi.bi_symtab = mp->m.m_addr + ehdr.a_text + ehdr.a_data + ehdr.a_bss;
mp->m_bi.bi_esymtab = mp->m_bi.bi_symtab + sizeof(ehdr.a_syms) + ehdr.a_syms;
/* Load OK, return module pointer */
*result = (struct loaded_module *)mp;
return(0);
ioerr:
err = EIO;
out:
close(fd);
free(mp);
return(err);
}
/*
* With the file (fd) open on the image, and (ehdr) containing
* the exec header, load the image at (addr)
*
* Fixup the a_bss field in (ehdr) to reflect the padding added to
* align the symbol table.
*/
static int
aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr)
{
u_int pad;
vm_offset_t addr;
int ss;
addr = loadaddr;
lseek(fd, N_TXTOFF(*ehdr), SEEK_SET);
/* text segment */
printf("text=0x%x ", ehdr->a_text);
if (pread(fd, addr, ehdr->a_text) != ehdr->a_text)
return(0);
addr += ehdr->a_text;
/* data segment */
printf("data=0x%x ", ehdr->a_data);
if (pread(fd, addr, ehdr->a_data) != ehdr->a_data)
return(0);
addr += ehdr->a_data;
/* skip the BSS */
printf("bss=0x%x ", 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;
}
/* XXX bi_symtab = addr */
/* symbol table size */
vpbcopy(&ehdr->a_syms, addr, sizeof(ehdr->a_syms));
addr += sizeof(ehdr->a_syms);
/* symbol table */
printf("symbols=[0x%x+0x%x+0x%x", pad, sizeof(ehdr->a_syms), ehdr->a_syms);
if (pread(fd, addr, ehdr->a_syms) != ehdr->a_syms)
return(0);
addr += ehdr->a_syms;
/* string table */
read(fd, &ss, sizeof(ss));
vpbcopy(&ss, addr, sizeof(ss));
addr += sizeof(ss);
ss -= sizeof(ss);
printf("+0x%x+0x%x]", sizeof(ss), ss);
if (pread(fd, addr, ss) != ss)
return(0);
/* XXX bi_esymtab = addr */
addr += ss;
return(addr - loadaddr);
}
struct module_format i386_aout = { aout_loadmodule, aout_exec };
static struct bootinfo bi;
/*
* There is an a.out kernel and one or more a.out modules loaded.
@ -192,24 +49,26 @@ aout_loadimage(int fd, vm_offset_t loadaddr, struct exec *ehdr)
* preparations as are required, and do so.
*/
static int
aout_exec(struct loaded_module *amp)
aout_exec(struct loaded_module *mp)
{
struct aout_kernel_module *mp = (struct aout_kernel_module *)amp;
struct loaded_module *xp;
struct i386_devdesc *currdev;
struct module_metadata *md;
struct exec *ehdr;
u_int32_t argv[6]; /* kernel arguments */
int major, bootdevnr;
vm_offset_t addr;
vm_offset_t addr, entry;
u_int pad;
if ((amp->m_flags & MF_FORMATMASK) != MF_AOUT)
return(EFTYPE);
if ((md = mod_findmetadata(mp, MODINFOMD_AOUTEXEC)) == NULL)
return(EFTYPE); /* XXX actually EFUCKUP */
ehdr = (struct exec *)&(md->md_data);
/* Boot from whatever the current device is */
i386_getdev((void **)(&currdev), NULL, NULL);
switch(currdev->d_type) {
case DEVT_DISK:
major = 0; /* XXX in the short term, have to work out a major number here for old kernels */
major = 0; /* XXX work out the best possible major here */
bootdevnr = MAKEBOOTDEV(major,
currdev->d_kind.biosdisk.slice >> 4,
currdev->d_kind.biosdisk.slice & 0xf,
@ -217,28 +76,34 @@ aout_exec(struct loaded_module *amp)
currdev->d_kind.biosdisk.partition);
break;
default:
printf("aout_loadmodule: WARNING - don't know how to boot from device type %d\n", currdev->d_type);
printf("aout_exec: WARNING - don't know how to boot from device type %d\n", currdev->d_type);
}
free(currdev);
/* Device data is kept in the kernel argv array */
argv[0] = bi_getboothowto(mp->m_args);
argv[1] = bootdevnr;
argv[0] = bi_getboothowto(amp->m_args);
/* argv[2] = vtophys(bootinfo); /* old cyl offset (do we care about this?) */
argv[2] = 0;
argv[3] = 0;
argv[4] = 0;
argv[5] = (u_int32_t)vtophys(&(mp->m_bi));
argv[5] = (u_int32_t)vtophys(&bi);
/* legacy bootinfo structure */
mp->m_bi.bi_version = BOOTINFO_VERSION;
mp->m_bi.bi_memsizes_valid = 1;
/* XXX bi_vesa */
mp->m_bi.bi_basemem = getbasemem();
mp->m_bi.bi_extmem = getextmem();
bi.bi_version = BOOTINFO_VERSION;
bi.bi_kernelname = 0; /* XXX char * -> kernel name */
bi.bi_nfs_diskless = 0; /* struct nfs_diskless * */
bi.bi_n_bios_used = 0; /* XXX would have to hook biosdisk driver for these */
/* bi.bi_bios_geom[] */
bi.bi_size = sizeof(bi);
bi.bi_memsizes_valid = 1;
bi.bi_vesa = 0; /* XXX correct value? */
bi.bi_basemem = getbasemem();
bi.bi_extmem = getextmem();
bi.bi_symtab = mp->m_addr + ehdr->a_text + ehdr->a_data + ehdr->a_bss;
bi.bi_esymtab = bi.bi_symtab + sizeof(ehdr->a_syms) + ehdr->a_syms;
/* find the last module in the chain */
for (xp = amp; xp->m_next != NULL; xp = xp->m_next)
for (xp = mp; xp->m_next != NULL; xp = xp->m_next)
;
addr = xp->m_addr + xp->m_size;
/* pad to a page boundary */
@ -247,7 +112,7 @@ aout_exec(struct loaded_module *amp)
pad = PAGE_SIZE - pad;
addr += pad;
}
/* copy our environment XXX save addr here as env pointer */
/* copy our environment XXX save addr here as env pointer, store in bootinfo? */
addr = bi_copyenv(addr);
/* pad to a page boundary */
@ -256,9 +121,11 @@ aout_exec(struct loaded_module *amp)
pad = PAGE_SIZE - pad;
addr += pad;
}
/* copy module list and metadata */
/* copy module list and metadata XXX save addr here as env pointer, store in bootinfo? */
bi_copymodules(addr);
entry = ehdr->a_entry & 0xffffff;
#ifdef DEBUG
{
int i;
@ -266,9 +133,9 @@ aout_exec(struct loaded_module *amp)
printf("argv[%d]=%lx\n", i, argv[i]);
}
printf("Start @ 0x%lx ...\n", mp->m_entry);
printf("Start @ 0x%lx ...\n", entry);
#endif
startprog(mp->m_entry, 6, argv, (vm_offset_t)0x90000);
startprog(entry, 6, argv, (vm_offset_t)0x90000);
panic("exec returned");
}

View File

@ -0,0 +1,46 @@
/*
* mjs copyright
*/
/*
* MD primitives supporting placement of module data
*
* XXX should check load address/size against memory top.
*/
#include <stand.h>
#include "libi386.h"
#define READIN_BUF 4096
int
i386_copyin(void *src, vm_offset_t dest, size_t len)
{
vpbcopy(src, dest, len);
return(len);
}
int
i386_readin(int fd, vm_offset_t dest, size_t len)
{
void *buf;
size_t resid, chunk, get, got;
chunk = min(READIN_BUF, len);
buf = malloc(chunk);
if (buf == NULL)
return(0);
for (resid = len; resid > 0; resid -= got, dest += got) {
get = min(chunk, resid);
got = read(fd, buf, get);
if (got <= 0)
break;
vpbcopy(buf, dest, chunk);
}
free(buf);
if (resid != 0)
printf("i386_readin: %d bytes short\n", resid);
return(len - resid);
}

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: i386_module.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
*/
/*
@ -37,22 +37,6 @@
#include "bootstrap.h"
#include "libi386.h"
/*
* Look for a method and having found it, boot the kernel module.
*/
int
i386_boot(void)
{
int i;
for (i = 0; module_formats[i] != NULL; i++) {
if (((loaded_modules->m_flags & MF_FORMATMASK) == module_formats[i]->l_format) &&
(module_formats[i]->l_exec != NULL)) {
return((module_formats[i]->l_exec)(loaded_modules));
}
}
}
/*
* Use voodoo to load modules required by current hardware.
*/

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: libi386.h,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
*/
@ -69,7 +69,12 @@ extern void pvbcopy(vm_offset_t, void*, int);
extern void pbzero(vm_offset_t, int);
extern vm_offset_t vtophys(void*);
extern int i386_copyin(void *src, vm_offset_t 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, int, u_int32_t *, vm_offset_t);
extern void delay(int);
@ -79,7 +84,6 @@ extern int getextmem(void);
extern void reboot(void);
extern void gateA20(void);
extern int i386_boot(void);
extern int i386_autoload(void);
extern int bi_getboothowto(char *kargs);

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: main.c,v 1.1.1.1 1998/08/21 03:17:41 msmith Exp $
*/
/*
@ -100,8 +100,9 @@ main(void)
setenv("LINES", "24", 1); /* optional */
archsw.arch_autoload = i386_autoload;
archsw.arch_boot = i386_boot;
archsw.arch_getdev = i386_getdev;
archsw.arch_copyin = i386_copyin;
archsw.arch_readin = i386_readin;
/*
* XXX should these be in the MI source?
*/

View File

@ -0,0 +1,50 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $Id$
*/
/*
* MD primitives supporting placement of module data
*
* XXX should check load address/size against memory top.
*/
#include <stand.h>
#include "libalpha.h"
int
alpha_copyin(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)
{
return(read(fd, dest, len));
}

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: alpha_module.c,v 1.1.1.1 1998/08/21 03:17:42 msmith Exp $
*/
/*
@ -37,22 +37,6 @@
#include "bootstrap.h"
#include "libalpha.h"
/*
* Look for a method and having found it, boot the kernel module.
*/
int
alpha_boot(void)
{
int i;
for (i = 0; module_formats[i] != NULL; i++) {
if (((loaded_modules->m_flags & MF_FORMATMASK) == module_formats[i]->l_format) &&
(module_formats[i]->l_exec != NULL)) {
return((module_formats[i]->l_exec)(loaded_modules));
}
}
}
/*
* Use voodoo to load modules required by current hardware.
*/