summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2008-05-20 18:12:20 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2008-05-20 18:12:20 +0000
commit86480375cdfab01471990bda620c046c8138c33b (patch)
treefaecf41e96a8e63bece9e770e840b7aeccec2cac
parentf4370fd03064afd7649f12473e875aaa94a3db9c (diff)
Change the OpenBSD/sgi boot loader so that we use libsa loadfile(), rather
than rolling our own load functions. tested jasper@, feedback and ok miod@
-rw-r--r--sys/arch/sgi/include/loadfile_machdep.h16
-rw-r--r--sys/arch/sgi/stand/boot/Makefile9
-rw-r--r--sys/arch/sgi/stand/boot/boot.c430
3 files changed, 38 insertions, 417 deletions
diff --git a/sys/arch/sgi/include/loadfile_machdep.h b/sys/arch/sgi/include/loadfile_machdep.h
index d0e5940445b..01cdd5713bb 100644
--- a/sys/arch/sgi/include/loadfile_machdep.h
+++ b/sys/arch/sgi/include/loadfile_machdep.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: loadfile_machdep.h,v 1.1 2004/08/06 21:12:19 pefo Exp $ */
+/* $OpenBSD: loadfile_machdep.h,v 1.2 2008/05/20 18:12:19 jsing Exp $ */
/* $NetBSD: loadfile_machdep.h,v 1.2 2001/10/31 17:20:49 thorpej Exp $ */
/*-
@@ -37,15 +37,11 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _SGIMIPS_LOADFILE_MACHDEP_H_
-#define _SGIMIPS_LOADFILE_MACHDEP_H_
+#define BOOT_ELF
+#define ELFSIZE 64
-#define BOOT_AOUT
-#define BOOT_ECOFF
-#define BOOT_ELF32
-
-#define LOAD_KERNEL (LOAD_ALL & ~LOAD_TEXTA)
-#define COUNT_KERNEL (COUNT_ALL & ~COUNT_TEXTA)
+#define LOAD_KERNEL (LOAD_ALL & ~LOAD_TEXTA)
+#define COUNT_KERNEL (COUNT_ALL & ~COUNT_TEXTA)
#define LOADADDR(a) (((u_long)(a)) + offset)
#define ALIGNENTRY(a) ((u_long)(a))
@@ -59,5 +55,3 @@
#define ALLOC(a) alloc(a)
#define FREE(a, b) free(a, b)
#define OKMAGIC(a) ((a) == OMAGIC)
-
-#endif /* !_SGIMIPS_LOADFILE_MACHDEP_H_ */
diff --git a/sys/arch/sgi/stand/boot/Makefile b/sys/arch/sgi/stand/boot/Makefile
index 784d1c10570..e7b281e12c1 100644
--- a/sys/arch/sgi/stand/boot/Makefile
+++ b/sys/arch/sgi/stand/boot/Makefile
@@ -1,5 +1,4 @@
-# $OpenBSD: Makefile,v 1.9 2007/11/30 14:02:00 jsing Exp $
-
+# $OpenBSD: Makefile,v 1.10 2008/05/20 18:12:19 jsing Exp $
PROG= boot
NOMAN= noman
@@ -17,12 +16,15 @@ LDFLAGS+= ${SALDFLAGS} -T ${.CURDIR}/ld.script -e __start
S= ${.CURDIR}/../../../..
SRCS= start.S boot.c filesystem.c conf.c diskio.c arcbios.c strstr.c
-CLEANFILES+= machine mips64
+.PATH: ${S}/lib/libsa
+SRCS+= loadfile.c
.PATH: ${S}/lib/libkern/arch/mips64 ${S}/lib/libkern
SRCS+= strlcpy.c memcpy.c strlen.c strrchr.c strlcat.c ashrdi3.c strncmp.c \
strcmp.S udivdi3.c umoddi3.c qdivrem.c
+CLEANFILES+= machine mips64
+
.if !make(libdep) && !make(sadep) && !make(salibdir) && !make(obj)
.BEGIN:
@([ -h machine ] || ln -s ${.CURDIR}/../../include machine)
@@ -33,7 +35,6 @@ ${PROG}: $(OBJS) $(LDADD)
$(LD) $(LDFLAGS) -o boot $(OBJS) -L${LIBSADIR} ${LIBSA} \
-L${LIBZDIR} ${LIBZ}
-
install:
install -c -m 555 -g bin -o bin ${PROG} ${DESTDIR}/usr/mdec
diff --git a/sys/arch/sgi/stand/boot/boot.c b/sys/arch/sgi/stand/boot/boot.c
index 4c9045e2108..7cab9da553b 100644
--- a/sys/arch/sgi/stand/boot/boot.c
+++ b/sys/arch/sgi/stand/boot/boot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: boot.c,v 1.10 2008/03/28 02:50:02 jsing Exp $ */
+/* $OpenBSD: boot.c,v 1.11 2008/05/20 18:12:19 jsing Exp $ */
/*
* Copyright (c) 2004 Opsycon AB, www.opsycon.se.
@@ -33,18 +33,12 @@
#include <stand.h>
#include <mips64/arcbios.h>
+#include <mips64/cpu.h>
-void gets(char *);
-ssize_t read(int, void *, size_t);
-int close(int);
+#include "loadfile.h"
int main(int, char **);
void dobootopts(int, char **);
-Elf32_Addr loadfile(char *);
-Elf32_Addr loadfile32(int, Elf32_Ehdr *);
-Elf32_Addr loadfile64(int, Elf64_Ehdr *);
-int loadsymtab32(int, Elf32_Ehdr *, int);
-int loadsymtab64(int, Elf64_Ehdr *, int);
enum {
AUTO_NONE,
@@ -57,40 +51,17 @@ enum {
char *OSLoadPartition = NULL;
char *OSLoadFilename = NULL;
-unsigned long tablebase;
-
-static void *
-readtable(int fd, int offs, void *base, int size, char *name, int flags)
-{
- if (lseek(fd, offs, SEEK_SET) != offs ||
- read(fd, base, size) != size) {
- printf("\nCannot read %s table!", name);
- return (0);
- }
- return ((void *) base);
-}
-
-static void *
-gettable(int size, char *name, int flags, size_t align)
-{
- long base;
-
- /* Put table after loaded code to support kernel DDB. */
- tablebase = roundup(tablebase, align);
- base = tablebase;
- tablebase += size;
- return ((void *) base);
-}
-
/*
- * OpenBSD/sgi boot loader.
+ * OpenBSD/sgi Boot Loader.
*/
int
main(int argc, char *argv[])
{
+ u_long marks[MARK_MAX];
+ u_int64_t *esym;
char line[1024];
- int i;
- Elf32_Addr entry;
+ u_long entry;
+ int fd, i;
dobootopts(argc, argv);
if (OSLoadPartition != NULL) {
@@ -108,9 +79,26 @@ main(int argc, char *argv[])
printf("Boot: %s\n", line);
- entry = loadfile(line);
- if (entry != NULL)
- ((void (*)())entry)(argc, argv);
+ /*
+ * Load the kernel and symbol table.
+ */
+
+ marks[MARK_START] = 0;
+ if ((fd = loadfile(line, marks, LOAD_KERNEL | COUNT_KERNEL)) != -1) {
+ (void)close(fd);
+
+ entry = marks[MARK_ENTRY];
+#ifdef __LP64__
+ esym = (u_int64_t *)marks[MARK_END];
+#else
+#undef KSEG0_BASE
+#define KSEG0_BASE 0xffffffff80000000ULL
+ esym = (u_int64_t *)PHYS_TO_KSEG0(marks[MARK_END]);
+#endif
+
+ if (entry != NULL)
+ ((void (*)())entry)(argc, argv, esym);
+ }
/* We failed to load the kernel. */
printf("Boot FAILED!\n");
@@ -166,365 +154,3 @@ dobootopts(int argc, char **argv)
}
}
}
-
-/*
- * Open 'filename', read in program and return the entry point or -1 if error.
- */
-Elf32_Addr
-loadfile(register char *fname)
-{
- union {
- Elf32_Ehdr eh32;
- Elf64_Ehdr eh64;
- } eh;
- int fd;
- Elf32_Addr entry = NULL;
-
- if ((fd = open(fname, 0)) < 0) {
- printf("Cannot open file %s!\n", fname);
- return (NULL);
- }
-
- /* Read the ELF header and check that it IS an ELF header. */
- if (read(fd, (char *)&eh, sizeof(eh)) != sizeof(eh)) {
- printf("Error: ELF header read error.\n");
- return (NULL);
- }
- if (!IS_ELF(eh.eh32)) {
- printf("Not an ELF file.\n");
- return (NULL);
- }
-
- /* Determine CLASS. */
- if (eh.eh32.e_ident[EI_CLASS] == ELFCLASS32)
- entry = loadfile32(fd, (void *)&eh);
- else if (eh.eh32.e_ident[EI_CLASS] == ELFCLASS64)
- entry = loadfile64(fd, (void *)&eh);
- else
- printf("Unknown ELF class.\n");
-
- return (entry);
-}
-
-Elf32_Addr
-loadfile32(int fd, Elf32_Ehdr *eh)
-{
- char buf[4096];
- Elf32_Phdr *ph;
- int i;
-
- ph = (Elf32_Phdr *) buf;
- lseek(fd, eh->e_phoff, 0);
- if (read(fd, (char *)ph, 4096) != 4096) {
- printf("Unexpected EOF!\n");
- return (NULL);
- }
-
- tablebase = 0;
- printf("Loading ELF32 file\n");
-
- for (i = 0; i < eh->e_phnum; i++, ph++) {
- if (ph->p_type == PT_LOAD) {
- lseek(fd, ph->p_offset, 0);
- printf("0x%x:0x%x, ",(long)ph->p_paddr, (long)ph->p_filesz);
- if (read(fd, (char *)ph->p_paddr,
- ph->p_filesz) != ph->p_filesz) {
- printf("Unexpected EOF!\n");
- return (NULL);
- }
- if (ph->p_memsz > ph->p_filesz) {
- printf("Zero 0x%x:0x%x, ",
- (long)(ph->p_paddr + ph->p_filesz),
- (long)(ph->p_memsz - ph->p_filesz));
- bzero((void *)(ph->p_paddr + ph->p_filesz),
- ph->p_memsz - ph->p_filesz);
- }
- if ((ph->p_paddr + ph->p_memsz) > tablebase)
- tablebase = ph->p_paddr + ph->p_memsz;
- }
- }
- memset((void *)tablebase, 0, 4096);
- loadsymtab32(fd, eh, 0);
- printf("Start at 0x%x\n", eh->e_entry);
- return(eh->e_entry);
-}
-
-Elf32_Addr
-loadfile64(int fd, Elf64_Ehdr *eh)
-{
- char buf[4096];
- Elf64_Phdr *ph;
- int i;
-
- ph = (Elf64_Phdr *) buf;
- lseek(fd, eh->e_phoff, 0);
- if (read(fd, (char *)ph, 4096) != 4096) {
- printf("Unexpected EOF!\n");
- return (NULL);
- }
-
- tablebase = 0;
- printf("Loading ELF64 file\n");
-
- for (i = 0; i < eh->e_phnum; i++, ph++) {
- if (ph->p_type == PT_LOAD) {
- lseek(fd, ph->p_offset, 0);
- printf("0x%llx:0x%llx, ",ph->p_paddr, ph->p_filesz);
- if (read(fd, (char *)(long)ph->p_paddr,
- ph->p_filesz) != ph->p_filesz) {
- printf("Unexpected EOF!\n");
- return (NULL);
- }
- if (ph->p_memsz > ph->p_filesz) {
- printf("Zero 0x%llx:0x%llx, ",
- ph->p_paddr + ph->p_filesz,
- ph->p_memsz - ph->p_filesz);
- bzero((void *)(long)(ph->p_paddr + ph->p_filesz),
- ph->p_memsz - ph->p_filesz);
- }
- if ((ph->p_paddr + ph->p_memsz) > tablebase)
- tablebase = ph->p_paddr + ph->p_memsz;
- }
- }
- memset((void *)tablebase, 0, 4096);
- loadsymtab64(fd, eh, 0);
- printf("Start at 0x%llx\n", eh->e_entry);
- return(eh->e_entry);
-}
-
-int
-loadsymtab32(int fd, Elf32_Ehdr *eh, int flags)
-{
- Elf32_Ehdr *keh;
- Elf32_Shdr *shtab;
- Elf32_Shdr *sh, *ksh, *shstrh, *strh;
- Elf32_Sym *symtab;
- int *symptr;
- char *shstrtab, *strtab, *symend;
- int i, nsym, offs, size;
-
- printf("Loading symbol table\n");
- size = eh->e_shnum * sizeof(Elf32_Shdr);
- shtab = (Elf32_Shdr *) alloc(size);
- if (lseek (fd, eh->e_shoff, SEEK_SET) != eh->e_shoff ||
- read (fd, shtab, size) != size) {
- printf("Seek to section headers failed.\n");
- return (-1);
- }
-
- tablebase = roundup(tablebase, sizeof(long));
- symptr = (int *)tablebase;
- tablebase = roundup(tablebase, 4096);
- keh = (Elf32_Ehdr *)tablebase;
- tablebase += sizeof(Elf32_Ehdr);
- tablebase = roundup(tablebase, sizeof(long));
- ksh = (Elf32_Shdr *)tablebase;
- tablebase += roundup((sizeof(Elf32_Shdr) * eh->e_shnum), sizeof(long));
- memcpy(ksh, shtab, roundup((sizeof(Elf32_Shdr) * eh->e_shnum), sizeof(long)));
- sh = ksh;
-
- shstrh = &sh[eh->e_shstrndx];
-
- for (i = 0; i < eh->e_shnum; sh++, i++) {
- if (sh->sh_type == SHT_SYMTAB)
- break;
- }
- if (i >= eh->e_shnum) {
- printf("No symbol table found!\n");
- return (-1);
- }
-
- strh = &ksh[sh->sh_link];
- nsym = sh->sh_size / sh->sh_entsize;
- offs = sh->sh_offset;
- size = sh->sh_size;
-
- /*
- * Allocate tables in correct order so that the kernel groks it.
- * Then we read them in the order they are in the ELF file.
- */
- shstrtab = gettable(shstrh->sh_size, "shstrtab", flags, sizeof(long));
- strtab = gettable(strh->sh_size, "strtab", flags, sizeof(long));
- symtab = gettable(size, "symtab", flags, sizeof(long));
- symend = (char *)symtab + size;
-
- do {
- if(shstrh->sh_offset < offs && shstrh->sh_offset < strh->sh_offset) {
-#if 0
- /*
- * We would like to read the shstrtab from the file
- * but since this table is located in front of the shtab
- * it is already gone. We can't position backwards
- * outside the current segment when using tftp.
- * Instead we create the names we need in the string
- * table because it can be reconstructed from the info
- * we now have access to.
- */
- if (!readtable (shstrh->sh_offset, (void *)shstrtab,
- shstrh->sh_size, "shstring", flags))
- return(0);
-#else
- memset(shstrtab, 0, shstrh->sh_size);
- strncpy(shstrtab + shstrh->sh_name, ".shstrtab", 10);
- strncpy(shstrtab + strh->sh_name, ".strtab", 10);
- strncpy(shstrtab + sh->sh_name, ".symtab", 10);
-#endif
- shstrh->sh_offset = 0x7fffffff;
- }
-
- if (offs < strh->sh_offset && offs < shstrh->sh_offset) {
- if (!(readtable(fd, offs, (void *)symtab, size,
- "sym", flags)))
- return (0);
- offs = 0x7fffffff;
- }
-
- if (strh->sh_offset < offs && strh->sh_offset < shstrh->sh_offset) {
- if (!(readtable (fd, strh->sh_offset, (void *)strtab,
- strh->sh_size, "string", flags)))
- return (0);
- strh->sh_offset = 0x7fffffff;
- }
- if (offs == 0x7fffffff && strh->sh_offset == 0x7fffffff &&
- shstrh->sh_offset == 0x7fffffff)
- break;
- } while (1);
-
- /*
- * Update the kernel headers with the current info.
- */
- shstrh->sh_offset = (Elf32_Off)shstrtab - (Elf32_Off)keh;
- strh->sh_offset = (Elf32_Off)strtab - (Elf32_Off)keh;
- sh->sh_offset = (Elf32_Off)symtab - (Elf32_Off)keh;
- memcpy(keh, eh, sizeof(Elf32_Ehdr));
- keh->e_phoff = 0;
- keh->e_shoff = sizeof(Elf32_Ehdr);
- keh->e_phentsize = 0;
- keh->e_phnum = 0;
-
- symptr[0] = (int)keh;
- symptr[1] = roundup((int)symend, sizeof(int));
-
- return(0);
-}
-
-int
-loadsymtab64(int fd, Elf64_Ehdr *eh, int flags)
-{
- Elf64_Ehdr *keh;
- Elf64_Shdr *shtab;
- Elf64_Shdr *sh, *ksh, *shstrh, *strh;
- Elf64_Sym *symtab;
- u_int64_t *symptr;
- char *shstrtab, *strtab, *symend;
- int i, nsym;
- Elf64_Xword size;
- Elf64_Off offs;
-
- printf("Loading symbol table\n");
- size = eh->e_shnum * sizeof(Elf64_Shdr);
- shtab = (Elf64_Shdr *) alloc(size);
- if (lseek (fd, (int)eh->e_shoff, SEEK_SET) != (int)eh->e_shoff ||
- read (fd, shtab, size) != size) {
- printf("Seek to section headers failed.\n");
- return (-1);
- }
-
- tablebase = roundup(tablebase, sizeof(u_int64_t));
- symptr = (u_int64_t *)tablebase;
- tablebase = roundup(tablebase, 4096);
- keh = (Elf64_Ehdr *)tablebase;
- tablebase += sizeof(Elf64_Ehdr);
- tablebase = roundup(tablebase, sizeof(u_int64_t));
- ksh = (Elf64_Shdr *)tablebase;
- tablebase += roundup((sizeof(Elf64_Shdr) * eh->e_shnum), sizeof(u_int64_t));
- memcpy(ksh, shtab, roundup((sizeof(Elf64_Shdr) * eh->e_shnum),
- sizeof(u_int64_t)));
- sh = ksh;
-
- shstrh = &sh[eh->e_shstrndx];
-
- for (i = 0; i < eh->e_shnum; sh++, i++) {
- if (sh->sh_type == SHT_SYMTAB) {
- break;
- }
- }
- if (i >= eh->e_shnum) {
- printf("No symbol table found!\n");
- return (-1);
- }
-
- strh = &ksh[sh->sh_link];
- nsym = sh->sh_size / sh->sh_entsize;
- offs = sh->sh_offset;
- size = sh->sh_size;
-
- /*
- * Allocate tables in correct order so that the kernel groks it.
- * Then we read them in the order they are in the ELF file.
- */
- shstrtab = gettable(shstrh->sh_size, "shstrtab", flags, sizeof(u_int64_t));
- strtab = gettable(strh->sh_size, "strtab", flags, sizeof(u_int64_t));
- symtab = gettable(size, "symtab", flags, sizeof(u_int64_t));
- symend = (char *)symtab + size;
-
- do {
- if(shstrh->sh_offset < offs && shstrh->sh_offset < strh->sh_offset) {
-#if 0
- /*
- * We would like to read the shstrtab from the file
- * but since this table is located in front of the shtab
- * it is already gone. We can't position backwards
- * outside the current segment when using tftp.
- * Instead we create the names we need in the string
- * table because it can be reconstructed from the
- * info we now have access to.
- */
- if (!readtable (shstrh->sh_offset, (void *)shstrtab,
- shstrh->sh_size, "shstring", flags))
- return (0);
-#else
- memset(shstrtab, 0, shstrh->sh_size);
- strncpy(shstrtab + shstrh->sh_name, ".shstrtab", 10);
- strncpy(shstrtab + strh->sh_name, ".strtab", 10);
- strncpy(shstrtab + sh->sh_name, ".symtab", 10);
-#endif
- shstrh->sh_offset = 0x7fffffff;
- }
-
- if (offs < strh->sh_offset && offs < shstrh->sh_offset) {
- if (!(readtable(fd, offs, (void *)symtab,
- size, "sym", flags)))
- return (0);
- offs = 0x7fffffff;
- }
-
- if (strh->sh_offset < offs && strh->sh_offset < shstrh->sh_offset) {
- if (!(readtable (fd, strh->sh_offset, (void *)strtab,
- strh->sh_size, "string", flags))) {
- return (0);
- }
- strh->sh_offset = 0x7fffffff;
- }
- if (offs == 0x7fffffff && strh->sh_offset == 0x7fffffff &&
- shstrh->sh_offset == 0x7fffffff)
- break;
- } while (1);
-
- /*
- * Update the kernel headers with the current info.
- */
- shstrh->sh_offset = (Elf64_Off)(long)shstrtab - (Elf64_Off)(long)keh;
- strh->sh_offset = (Elf64_Off)(long)strtab - (Elf64_Off)(long)keh;
- sh->sh_offset = (Elf64_Off)(long)symtab - (Elf64_Off)(long)keh;
- memcpy(keh, eh, sizeof(Elf64_Ehdr));
- keh->e_phoff = 0;
- keh->e_shoff = sizeof(Elf64_Ehdr);
- keh->e_phentsize = 0;
- keh->e_phnum = 0;
-
- symptr[0] = (Elf64_Off)keh;
- symptr[1] = (Elf64_Off)roundup((Elf64_Off)symend, sizeof(u_int64_t));
-
- return (0);
-}