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:
parent
f471c44869
commit
c73b70eec4
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
/* $Id$ */
|
||||
DEFINE_SET(Xcommand_set, 15);
|
|
@ -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";
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
@ -1,2 +0,0 @@
|
|||
/* $Id$ */
|
||||
DEFINE_SET(Xcommand_set, 15);
|
|
@ -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";
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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?
|
||||
*/
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
@ -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.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue