summaryrefslogtreecommitdiff
path: root/sys/arch/powerpc/stand/boot.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/powerpc/stand/boot.c')
-rw-r--r--sys/arch/powerpc/stand/boot.c319
1 files changed, 20 insertions, 299 deletions
diff --git a/sys/arch/powerpc/stand/boot.c b/sys/arch/powerpc/stand/boot.c
index d274c9a92be..2a06832305f 100644
--- a/sys/arch/powerpc/stand/boot.c
+++ b/sys/arch/powerpc/stand/boot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: boot.c,v 1.12 2000/01/24 03:07:54 rahnds Exp $ */
+/* $OpenBSD: boot.c,v 1.13 2001/06/23 01:53:01 drahn Exp $ */
/* $NetBSD: boot.c,v 1.1 1997/04/16 20:29:17 thorpej Exp $ */
/*
@@ -45,19 +45,18 @@
#define ELFSIZE 32 /* We use 32-bit ELF. */
-#include <lib/libkern/libkern.h>
-#include <lib/libsa/stand.h>
-
#include <sys/param.h>
#include <sys/exec.h>
#include <sys/exec_elf.h>
#include <sys/reboot.h>
#include <sys/disklabel.h>
+#include <lib/libkern/libkern.h>
+#include <lib/libsa/stand.h>
+#include <lib/libsa/loadfile.h>
+
+
#include <machine/cpu.h>
-/*
-#include <machine/machine_type.h>
-*/
#include <powerpc/stand/ofdev.h>
#include <powerpc/stand/openfirm.h>
@@ -140,9 +139,10 @@ parseargs(str, howtop)
}
static void
-chain(entry, args, esym)
+chain(entry, args, ssym, esym)
void (*entry)();
char *args;
+ void *ssym;
void *esym;
{
extern char end[];
@@ -155,6 +155,8 @@ chain(entry, args, esym)
* strings.
*/
l = strlen(args) + 1;
+ bcopy(&ssym, args + l, sizeof(ssym));
+ l += sizeof(ssym);
bcopy(&esym, args + l, sizeof(esym));
l += sizeof(esym);
@@ -172,299 +174,14 @@ chain(entry, args, esym)
}
int
-loadfile(fd, args)
- int fd;
- char *args;
-{
- union {
-#ifdef POWERPC_BOOT_AOUT
- struct exec aout;
-#endif
-#ifdef POWERPC_BOOT_ELF
- Elf32_Ehdr elf;
-#endif
- } hdr;
- int rval;
- u_int32_t entry;
- void *esym;
-
- rval = 1;
- esym = NULL;
-
- /* Load the header. */
- if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
- printf("read header: %s\n", strerror(errno));
- goto err;
- }
-
- /* Determine file type, load kernel. */
-#ifdef POWERPC_BOOT_AOUT
- if (N_BADMAG(hdr.aout) == 0 && N_GETMID(hdr.aout) == MID_POWERPC) {
- rval = aout_exec(fd, &hdr.aout, &entry, &esym);
- } else
-#endif
-#ifdef POWERPC_BOOT_ELF
- if (IS_ELF(hdr.elf)) {
- rval = elf_exec(fd, &hdr.elf, &entry, &esym);
- } else
-#endif
- {
- printf("unknown executable format\n");
- }
-
- if (rval)
- goto err;
-
- printf(" start=0x%x\n", entry);
-
- close(fd);
-
- chain((void *)entry, args, esym);
- /* NOTREACHED */
-
- err:
- close(fd);
- return (rval);
-}
-
-#ifdef POWERPC_BOOT_AOUT
-int
-aout_exec(fd, hdr, entryp, esymp)
- int fd;
- struct exec *hdr;
- u_int32_t *entryp;
- void **esymp;
-{
- void *addr;
- int n, *paddr;
-
- /* Display the load address (entry point) for a.out. */
- printf("Booting %s @ 0x%lx\n", opened_name, hdr->a_entry);
- addr = (void *)(hdr->a_entry);
-
- /*
- * Determine memory needed for kernel and allocate it from
- * the firmware.
- */
- n = hdr->a_text + hdr->a_data + hdr->a_bss + hdr->a_syms + sizeof(int);
- if ((paddr = OF_claim(addr, n, 0)) == (int *)-1)
- panic("cannot claim memory");
-
- /* Load text. */
- lseek(fd, N_TXTOFF(*hdr), SEEK_SET);
- printf("%lu", hdr->a_text);
- if (read(fd, paddr, hdr->a_text) != hdr->a_text) {
- printf("read text: %s\n", strerror(errno));
- return (1);
- }
- syncicache((void *)paddr, hdr->a_text);
-
- /* Load data. */
- printf("+%lu", hdr->a_data);
- if (read(fd, (void *)paddr + hdr->a_text, hdr->a_data) != hdr->a_data) {
- printf("read data: %s\n", strerror(errno));
- return (1);
- }
-
- /* Zero BSS. */
- printf("+%lu", hdr->a_bss);
- bzero((void *)paddr + hdr->a_text + hdr->a_data, hdr->a_bss);
-
- /* Symbols. */
- *esymp = paddr;
- paddr = (int *)((void *)paddr + hdr->a_text + hdr->a_data + hdr->a_bss);
- *paddr++ = hdr->a_syms;
- if (hdr->a_syms) {
- printf(" [%lu", hdr->a_syms);
- if (read(fd, paddr, hdr->a_syms) != hdr->a_syms) {
- printf("read symbols: %s\n", strerror(errno));
- return (1);
- }
- paddr = (int *)((void *)paddr + hdr->a_syms);
- if (read(fd, &n, sizeof(int)) != sizeof(int)) {
- printf("read symbols: %s\n", strerror(errno));
- return (1);
- }
- if (OF_claim((void *)paddr, n + sizeof(int), 0) == (void *)-1)
- panic("cannot claim memory");
- *paddr++ = n;
- if (read(fd, paddr, n - sizeof(int)) != n - sizeof(int)) {
- printf("read symbols: %s\n", strerror(errno));
- return (1);
- }
- printf("+%d]", n - sizeof(int));
- *esymp = paddr + (n - sizeof(int));
- }
-
- *entryp = hdr->a_entry;
- return (0);
-}
-#endif /* POWERPC_BOOT_AOUT */
-
-#define LOAD_HDR 1
-#define LOAD_SYM 2
-#ifdef POWERPC_BOOT_ELF
-int
-elf_exec(fd, elf, entryp, esymp)
- int fd;
- Elf32_Ehdr *elf;
- u_int32_t *entryp;
- void **esymp;
-
-{
- Elf32_Shdr *shp;
- Elf32_Off off;
- void *addr;
- size_t size;
- int i, first = 1;
- int n;
- u_int32_t maxp = 0; /* correct type? */
- int flags = LOAD_HDR| LOAD_SYM;
-
- /*
- * Don't display load address for ELF; it's encoded in
- * each section.
- */
- printf("Booting %s\n", opened_name);
-
- for (i = 0; i < elf->e_phnum; i++) {
- Elf32_Phdr phdr;
- (void)lseek(fd, elf->e_phoff + sizeof(phdr) * i, SEEK_SET);
- if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr)) {
- printf("read phdr: %s\n", strerror(errno));
- return (1);
- }
- if (phdr.p_type != PT_LOAD ||
- (phdr.p_flags & (PF_W|PF_X)) == 0)
- continue;
-
- /* Read in segment. */
- printf("%s%lu@0x%lx", first ? "" : "+", phdr.p_filesz,
- (u_long)phdr.p_vaddr);
- (void)lseek(fd, phdr.p_offset, SEEK_SET);
- if (OF_claim((void *)phdr.p_vaddr, phdr.p_memsz, 0) ==
- (void *)-1)
- panic("cannot claim memory");
- maxp = maxp > (phdr.p_vaddr+ phdr.p_memsz) ?
- maxp : (phdr.p_vaddr+ phdr.p_memsz);
- if (read(fd, (void *)phdr.p_vaddr, phdr.p_filesz) !=
- phdr.p_filesz) {
- printf("read segment: %s\n", strerror(errno));
- return (1);
- }
- syncicache((void *)phdr.p_vaddr, phdr.p_filesz);
-
- /* Zero BSS. */
- if (phdr.p_filesz < phdr.p_memsz) {
- printf("+%lu@0x%lx", phdr.p_memsz - phdr.p_filesz,
- (u_long)(phdr.p_vaddr + phdr.p_filesz));
- bzero((void *)(phdr.p_vaddr + phdr.p_filesz),
- phdr.p_memsz - phdr.p_filesz);
- }
- first = 0;
- }
- *esymp = 0; /* in case it is not set later */
-
-#if 0
- /*
- * Copy the ELF and section headers.
- */
- maxp = roundup(maxp, sizeof(long));
- if (flags & (LOAD_HDR|COUNT_HDR)) {
- if (OF_claim((void *)maxp, sizeof(Elf_Ehdr), 0) ==
- (void *)-1)
- panic("cannot claim memory");
- elfp = maxp;
- maxp += sizeof(Elf_Ehdr);
- }
-
- if (flags & (LOAD_SYM|COUNT_SYM)) {
- if (lseek(fd, elf->e_shoff, SEEK_SET) == -1) {
- WARN(("lseek section headers"));
- return 1;
- }
- sz = elf->e_shnum * sizeof(Elf_Shdr);
-
- if (OF_claim((void *)maxp, sizeof(Elf_Ehdr), 0) ==
- (void *)-1)
- panic("cannot claim memory");
- shpp = maxp;
- maxp += roundup(sz, sizeof(long));
-
- if (read(fd, shpp, sz) != sz) {
- WARN(("read section headers"));
- return 1;
- }
- /*
- * Now load the symbol sections themselves. Make sure the
- * sections are aligned. Don't bother with string tables if
- * there are no symbol sections.
- */
- off = roundup((sizeof(Elf_Ehdr) + sz), sizeof(long));
-
- for (havesyms = i = 0; i < elf->e_shnum; i++)
- if (shpp[i].sh_type == Elf_sht_symtab)
- havesyms = 1;
-
- for (first = 1, i = 0; i < elf->e_shnum; i++) {
- if (shpp[i].sh_type == Elf_sht_symtab ||
- shpp[i].sh_type == Elf_sht_strtab) {
- if (havesyms && (flags & LOAD_SYM)) {
- PROGRESS(("%s%ld", first ? " [" : "+",
- (u_long)shpp[i].sh_size));
- if (lseek(fd, shpp[i].sh_offset,
- SEEK_SET) == -1) {
- WARN(("lseek symbols"));
- FREE(shp, sz);
- return 1;
- }
- if (READ(fd, maxp, shpp[i].sh_size) !=
- shpp[i].sh_size) {
- WARN(("read symbols"));
- return 1;
- }
- }
- maxp += roundup(shpp[i].sh_size,
- sizeof(long));
- shpp[i].sh_offset = off;
- off += roundup(shpp[i].sh_size, sizeof(long));
- first = 0;
- }
- }
- if (flags & LOAD_SYM) {
- BCOPY(shp, shpp, sz);
-
- if (first == 0)
- PROGRESS(("]"));
- }
- }
-
- /*
- * Frob the copied ELF header to give information relative
- * to elfp.
- */
- if (flags & LOAD_HDR) {
- elf->e_phoff = 0;
- elf->e_shoff = sizeof(Elf_Ehdr);
- elf->e_phentsize = 0;
- elf->e_phnum = 0;
- BCOPY(elf, elfp, sizeof(*elf));
- }
-#endif
- printf(" \n");
-
-
- *entryp = elf->e_entry;
- return (0);
-}
-#endif /* POWERPC_BOOT_ELF */
-
-int
main()
{
int chosen;
char bootline[512]; /* Should check size? */
char *cp;
+ u_long marks[MARK_MAX];
+ u_int32_t entry;
+ void *ssym, *esym;
int fd;
printf("\n>> OpenBSD/powerpc Boot\n");
@@ -486,7 +203,8 @@ main()
gets(bootline);
parseargs(bootline, &boothowto);
}
- if ((fd = open(bootline, 0)) >= 0)
+ marks[MARK_START] = 0;
+ if (loadfile(bootline, marks, LOAD_ALL) >= 0)
break;
if (errno)
printf("open %s: %s\n", opened_name, strerror(errno));
@@ -518,8 +236,11 @@ main()
#ifdef __notyet__
OF_setprop(chosen, "bootargs", bootline, strlen(bootline) + 1);
#endif
- /* XXX void, for now */
- (void)loadfile(fd, bootline);
+ entry = marks[MARK_ENTRY];
+ ssym = (void *)marks[MARK_SYM];
+ esym = (void *)marks[MARK_END];
+
+ chain ((void*)entry, bootline, ssym, esym);
_rtt();
return 0;