summaryrefslogtreecommitdiffstats
path: root/sys/boot/common/load_aout.c
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>1998-08-31 21:10:43 +0000
committermsmith <msmith@FreeBSD.org>1998-08-31 21:10:43 +0000
commit815f3686d0275b1e63d326042e37d5244e051121 (patch)
treea32c9c92f2b120f904fc9aa7d0755d8b8a74f6b0 /sys/boot/common/load_aout.c
parentc3fa37d604772f443b31aa7d26c331bd64c2675d (diff)
downloadFreeBSD-src-815f3686d0275b1e63d326042e37d5244e051121.zip
FreeBSD-src-815f3686d0275b1e63d326042e37d5244e051121.tar.gz
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>
Diffstat (limited to 'sys/boot/common/load_aout.c')
-rw-r--r--sys/boot/common/load_aout.c202
1 files changed, 202 insertions, 0 deletions
diff --git a/sys/boot/common/load_aout.c b/sys/boot/common/load_aout.c
new file mode 100644
index 0000000..45b6328
--- /dev/null
+++ b/sys/boot/common/load_aout.c
@@ -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);
+}
+
OpenPOWER on IntegriCloud