static void chain(void (*entry)(), char *args, void *ssym, void *esym) { extern char end[]; int l; #ifdef __notyet__ int machine_tag; #endif freeall(); /* * Stash pointer to end of symbol table after the argument * strings. */ l = strlen(args) + 1; bcopy(&ssym, args + l, sizeof(ssym)); l += sizeof(ssym); bcopy(&esym, args + l, sizeof(esym)); l += sizeof(esym); #ifdef __notyet__ /* * Tell the kernel we're an OpenFirmware system. */ machine_tag = POWERPC_MACHINE_OPENFIRMWARE; bcopy(&machine_tag, args + l, sizeof(machine_tag)); l += sizeof(machine_tag); #endif OF_chain((void *)RELOC, end - (char *)RELOC, entry, args, l); panic("chain"); }
int __elfN(ofw_exec)(struct preloaded_file *fp) { struct file_metadata *fmp; vm_offset_t mdp; Elf_Ehdr *e; int error; intptr_t entry; if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) { return(EFTYPE); } e = (Elf_Ehdr *)&fmp->md_data; entry = e->e_entry; if ((error = md_load(fp->f_args, &mdp)) != 0) return (error); printf("Kernel entry at 0x%lx ...\n", e->e_entry); dev_cleanup(); ofw_release_heap(); OF_chain((void *)reloc, end - (char *)reloc, (void *)entry, (void *)mdp, sizeof(mdp)); panic("exec returned"); }
static void chain(void (*entry)(int (*)(void *), void *, u_int), char *args, void *ssym, void *esym) { extern char end[]; u_int l, magic = 0x19730224; freeall(); /* * Stash pointer to start and end of symbol table after the argument * strings. */ l = strlen(args) + 1; l = (l + 3) & ~3; /* align */ DPRINTF("magic @ %p\n", args + l); memcpy(args + l, &magic, sizeof(magic)); l += sizeof(magic); DPRINTF("ssym @ %p\n", args + l); memcpy(args + l, &ssym, sizeof(ssym)); l += sizeof(ssym); DPRINTF("esym @ %p\n", args + l); memcpy(args + l, &esym, sizeof(esym)); l += sizeof(esym); DPRINTF("args + l -> %p\n", args + l); DPRINTF("Calling OF_chain(%p, %tx, %p, %p, %u)\n", (void *)RELOC, end - (char *)RELOC, entry, args, l); OF_chain((void *)RELOC, end - (char *)RELOC, entry, args, l); panic("chain"); }
int ppc64_ofw_elf_exec(struct preloaded_file *fp) { struct file_metadata *fmp; vm_offset_t mdp, dtbp; Elf_Ehdr *e; int error; intptr_t entry; if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) { return(EFTYPE); } e = (Elf_Ehdr *)&fmp->md_data; /* Handle function descriptor for ELFv1 kernels */ if ((e->e_flags & 3) == 2) entry = e->e_entry; else entry = *(uint64_t *)e->e_entry; if ((error = md_load64(fp->f_args, &mdp, &dtbp)) != 0) return (error); printf("Kernel entry at 0x%lx ...\n", entry); dev_cleanup(); ofw_release_heap(); if (dtbp != 0) { OF_quiesce(); ((int (*)(u_long, u_long, u_long, void *, u_long))entry)(dtbp, 0, 0, mdp, sizeof(mdp)); } else { OF_chain((void *)reloc, end - (char *)reloc, (void *)entry, (void *)mdp, sizeof(mdp)); } panic("exec returned"); }