static void check_preloaded_kernel(void) { unsigned long kernel_image, kernel_size; unsigned long initrd_image, initrd_size; const char * kernel_cmdline; volatile struct context *ctx = __context; kernel_size = fw_cfg_read_i32(FW_CFG_KERNEL_SIZE); if (kernel_size) { kernel_image = fw_cfg_read_i32(FW_CFG_KERNEL_ADDR); kernel_cmdline = (const char *)(uintptr_t) fw_cfg_read_i32(FW_CFG_KERNEL_CMDLINE); initrd_image = fw_cfg_read_i32(FW_CFG_INITRD_ADDR); initrd_size = fw_cfg_read_i32(FW_CFG_INITRD_SIZE); printk("[ppc] Kernel already loaded (0x%8.8lx + 0x%8.8lx) " "(initrd 0x%8.8lx + 0x%8.8lx)\n", kernel_image, kernel_size, initrd_image, initrd_size); if (kernel_cmdline) { phandle_t ph; printk("[ppc] Kernel command line: %s\n", kernel_cmdline); ph = find_dev("/chosen"); set_property(ph, "bootargs", strdup(kernel_cmdline), strlen(kernel_cmdline) + 1); } arch_init_program(); ctx->regs[REG_R3] = initrd_image; ctx->regs[REG_R4] = initrd_size; ctx->pc = kernel_image; start_elf(); } }
void fcode_init_program(void) { /* Use trampoline context to execute FCode */ PUSH((ucell)&init_fcode_context); feval("load-state >ls.entry !"); arch_init_program(); feval("-1 state-valid !"); }
void boot(void) { /* Boot preloaded kernel */ if (kernel_size) { printk("[sparc] Kernel already loaded\n"); PUSH(kernel_image); feval("load-state >ls.entry !"); arch_init_program(); start_elf(); } }
void aout_init_program(void) { ucell start, size; // Relocate a.out text down from load-base to load-base - header. This // is similar to what OBP does and is needed for NextStep. fword("load-base"); start = POP(); feval("load-state >ls.file-size @"); size = POP(); memmove((char *)start - sizeof(struct exec), (char *)start, size); PUSH(start); feval("load-state >ls.entry !"); arch_init_program(); feval("-1 state-valid !"); }
void xcoff_init_program(void) { char *base; COFF_filehdr_t *fhdr; COFF_aouthdr_t *ahdr; COFF_scnhdr_t *shdr; uint32_t offset; size_t total_size = 0; int i; feval("load-base"); base = (char*)cell2pointer(POP()); fhdr = (COFF_filehdr_t*)base; /* Is it an XCOFF file ? */ if (!is_xcoff(fhdr)) { DPRINTF("Not a XCOFF file %02x\n", fhdr->f_magic); return; } /* Is it executable ? */ if (fhdr->f_magic != 0x01DF && (fhdr->f_flags & COFF_F_EXEC) == 0) { DPRINTF("Not an executable XCOFF file %02x\n", fhdr->f_flags); return; } /* Optional header is a.out ? */ if (fhdr->f_opthdr != sizeof(COFF_aouthdr_t)) { DPRINTF("AOUT optional error size mismatch in XCOFF file\n"); return; } ahdr = (COFF_aouthdr_t*)(base + sizeof(COFF_filehdr_t)); /* check a.out magic number */ if (ahdr->magic != AOUT_MAGIC) { DPRINTF("Invalid AOUT optional header\n"); return; } offset = sizeof(COFF_filehdr_t) + sizeof(COFF_aouthdr_t); DPRINTF("XCOFF file with %d sections\n", fhdr->f_nscns); for (i = 0; i < fhdr->f_nscns; i++) { DPRINTF("Read header at offset %0x\n", offset); shdr = (COFF_scnhdr_t*)(base + offset); DPRINTF("Initializing '%s' section from %0x %0x to %0x (%0x)\n", shdr->s_name, offset, shdr->s_scnptr, shdr->s_vaddr, shdr->s_size); if (strcmp(shdr->s_name, ".text") == 0) { memcpy((char*)(uintptr_t)shdr->s_vaddr, base + shdr->s_scnptr, shdr->s_size); total_size += shdr->s_size; #ifdef CONFIG_PPC flush_icache_range((char*)(uintptr_t)shdr->s_vaddr, (char*)(uintptr_t)(shdr->s_vaddr + shdr->s_size)); #endif } else if (strcmp(shdr->s_name, ".data") == 0) { memcpy((char*)(uintptr_t)shdr->s_vaddr, base + shdr->s_scnptr, shdr->s_size); total_size += shdr->s_size; } else if (strcmp(shdr->s_name, ".bss") == 0) { memset((void *)(uintptr_t)shdr->s_vaddr, 0, shdr->s_size); total_size += shdr->s_size; } else { DPRINTF(" Skip '%s' section\n", shdr->s_name); } offset += sizeof(COFF_scnhdr_t); } DPRINTF("XCOFF entry point: %x\n", *(uint32_t*)ahdr->entry); // Initialise load-state PUSH(*(uint32_t*)(uintptr_t)ahdr->entry); feval("load-state >ls.entry !"); feval("xcoff load-state >ls.file-type !"); arch_init_program(); feval("-1 state-valid !"); }