void boot(int a1, int a2, void *prom) { unsigned sa, len; void *dst; unsigned char *im; unsigned initrd_start, initrd_size; printf("coffboot starting: loaded at 0x%p\n", &_start); setup_bats(ram_start); initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin); if (initrd_size) { initrd_start = (ram_end - initrd_size) & ~0xFFF; a1 = initrd_start; a2 = initrd_size; claim(initrd_start, ram_end - initrd_start, 0); printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", initrd_start, (char *)(&__ramdisk_begin), initrd_size); memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size); prog_size = initrd_start - prog_start; } else a2 = 0xdeadbeef; im = (char *)(&__image_begin); len = (char *)(&__image_end) - (char *)(&__image_begin); /* claim 4MB starting at PROG_START */ claim(prog_start, prog_size, 0); map(prog_start, prog_start, prog_size); dst = (void *) prog_start; if (im[0] == 0x1f && im[1] == 0x8b) { /* set up scratch space */ begin_avail = avail_high = avail_ram = heap; end_avail = heap + sizeof(heap); printf("heap at 0x%p\n", avail_ram); printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len); gunzip(dst, prog_size, im, &len); printf("done %u bytes\n", len); printf("%u bytes of heap consumed, max in use %u\n", avail_high - begin_avail, heap_max); } else { memmove(dst, im, len); } flush_cache(dst, len); make_bi_recs(((unsigned long) dst + len), "coffboot", _MACH_Pmac, (prog_start + prog_size)); sa = (unsigned long)prog_start; printf("start address = 0x%x\n", sa); (*(kernel_start_t)sa)(a1, a2, prom); printf("returned?\n"); pause(); }
void chrpboot(int a1, int a2, void *prom) { unsigned sa, len; void *dst; unsigned char *im; unsigned int initrd_size, initrd_start; printf("chrpboot starting: loaded at 0x%p\n\r", &_start); initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin); if (initrd_size) { initrd_start = (RAM_END - initrd_size) & ~0xFFF; a1 = initrd_start; a2 = initrd_size; claim(initrd_start, RAM_END - initrd_start, 0); printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r", initrd_start, (char *)(&__ramdisk_begin), initrd_size); memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size); } else { initrd_start = 0; initrd_size = 0; a2 = 0xdeadbeef; } im = (char *)(&__image_begin); len = (char *)(&__image_end) - (char *)(&__image_begin); /* claim 4MB starting at PROG_START */ claim(PROG_START, PROG_SIZE - PROG_START, 0); dst = (void *) PROG_START; if (im[0] == 0x1f && im[1] == 0x8b) { avail_ram = scratch; begin_avail = avail_high = avail_ram; end_avail = scratch + sizeof(scratch); printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len); gunzip(dst, 0x400000, im, &len); printf("done %u bytes\n\r", len); printf("%u bytes of heap consumed, max in use %u\n\r", avail_high - begin_avail, heap_max); } else { memmove(dst, im, len); } flush_cache(dst, len); make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_chrp, (PROG_START + PROG_SIZE)); sa = (unsigned long)PROG_START; printf("start address = 0x%x\n\r", sa); (*(void (*)())sa)(a1, a2, prom, initrd_start, initrd_size); printf("returned?\n\r"); pause(); }
boot(int a1, int a2, void *prom) { int ns, oh, i; unsigned sa, len; void *dst; unsigned char *im; unsigned initrd_start, initrd_size; extern char _start; printf("chrpboot starting: loaded at 0x%x\n", &_start); if (initrd_len) { initrd_size = initrd_len; initrd_start = (RAM_END - initrd_size) & ~0xFFF; a1 = initrd_start; a2 = initrd_size; claim(initrd_start, RAM_END - initrd_start, 0); printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", initrd_start, initrd_data,initrd_size); memcpy((char *)initrd_start, initrd_data, initrd_size); } im = image_data; len = image_len; /* claim 3MB starting at PROG_START */ claim(PROG_START, PROG_SIZE, 0); dst = (void *) PROG_START; if (im[0] == 0x1f && im[1] == 0x8b) { /* claim some memory for scratch space */ avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10); begin_avail = avail_high = avail_ram; end_avail = avail_ram + SCRATCH_SIZE; printf("heap at 0x%x\n", avail_ram); printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len); gunzip(dst, PROG_SIZE, im, &len); printf("done %u bytes\n", len); printf("%u bytes of heap consumed, max in use %u\n", avail_high - begin_avail, heap_max); } else { memmove(dst, im, len); } flush_cache(dst, len); make_bi_recs((unsigned long) dst + len); sa = (unsigned long)PROG_START; printf("start address = 0x%x\n", sa); (*(void (*)())sa)(a1, a2, prom); printf("returned?\n"); pause(); }
boot(int a1, int a2, void *prom) { int ns, oh, i; unsigned sa, len; void *dst; unsigned char *im; unsigned initrd_start, initrd_size; printf("coffboot starting: loaded at 0x%x\n", _start); setup_bats(RAM_START); if (initrd_len) { initrd_size = initrd_len; initrd_start = (RAM_END - initrd_size) & ~0xFFF; a1 = initrd_start; a2 = initrd_size; claim(initrd_start - RAM_START, RAM_END - initrd_start, 0); printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", initrd_start, initrd_data, initrd_size); memcpy((char *)initrd_start, initrd_data, initrd_size); } im = image_data; len = image_len; /* claim 3MB starting at 0 */ claim(0, 3 << 20, 0); dst = (void *) RAM_START; if (im[0] == 0x1f && im[1] == 0x8b) { /* claim 512kB for scratch space */ avail_ram = claim(0, 512 << 10, 0x10) + RAM_START; end_avail = avail_ram + (512 << 10); printf("avail_ram = %x\n", avail_ram); printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len); gunzip(dst, 3 << 20, im, &len); printf("done %u bytes\n", len); } else { memmove(dst, im, len); } flush_cache(dst, len); make_bi_recs((unsigned long)dst + len); sa = (unsigned long)PROG_START; printf("start address = 0x%x\n", sa); #if 0 pause(); #endif (*(void (*)())sa)(a1, a2, prom); printf("returned?\n"); pause(); }
void start(unsigned long a1, unsigned long a2, void *promptr) { unsigned long i, claim_addr, claim_size; extern char _start; struct bi_record *bi_recs; kernel_entry_t kernel_entry; Elf64_Ehdr *elf64; Elf64_Phdr *elf64ph; prom = (int (*)(void *)) promptr; chosen_handle = finddevice("/chosen"); if (chosen_handle == (void *) -1) exit(); if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) exit(); stderr = stdout; if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) exit(); printf("zImage starting: loaded at 0x%x\n\r", (unsigned)&_start); #if 0 sysmap.size = (unsigned long)(_sysmap_end - _sysmap_start); sysmap.memsize = sysmap.size; if ( sysmap.size > 0 ) { sysmap.addr = (RAM_END - sysmap.size) & ~0xFFF; claim(sysmap.addr, RAM_END - sysmap.addr, 0); printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r", sysmap.addr, (unsigned long)_sysmap_start, sysmap.size); memcpy((void *)sysmap.addr, (void *)_sysmap_start, sysmap.size); } #endif initrd.size = (unsigned long)(_initrd_end - _initrd_start); initrd.memsize = initrd.size; if ( initrd.size > 0 ) { initrd.addr = (RAM_END - initrd.size) & ~0xFFF; a1 = a2 = 0; claim(initrd.addr, RAM_END - initrd.addr, 0); printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r", initrd.addr, (unsigned long)_initrd_start, initrd.size); memcpy((void *)initrd.addr, (void *)_initrd_start, initrd.size); } vmlinuz.addr = (unsigned long)_vmlinux_start; vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start); vmlinux.addr = (unsigned long)(void *)-1; vmlinux.size = PAGE_ALIGN(vmlinux_filesize); vmlinux.memsize = vmlinux_memsize; claim_size = vmlinux.memsize /* PPPBBB: + fudge for bi_recs */; for(claim_addr = PROG_START; claim_addr <= PROG_START * 8; claim_addr += 0x100000) { printf(" trying: 0x%08lx\n\r", claim_addr); vmlinux.addr = (unsigned long)claim(claim_addr, claim_size, 0); if ((void *)vmlinux.addr != (void *)-1) break; } if ((void *)vmlinux.addr == (void *)-1) { printf("claim error, can't allocate kernel memory\n\r"); exit(); } /* PPPBBB: should kernel always be gziped? */ if (*(unsigned short *)vmlinuz.addr == 0x1f8b) { avail_ram = scratch; begin_avail = avail_high = avail_ram; end_avail = scratch + sizeof(scratch); printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...", vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size); gunzip((void *)vmlinux.addr, vmlinux.size, (unsigned char *)vmlinuz.addr, (int *)&vmlinuz.size); printf("done %lu bytes\n\r", vmlinuz.size); printf("%u bytes of heap consumed, max in use %u\n\r", (unsigned)(avail_high - begin_avail), heap_max); } else { memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size); } /* Skip over the ELF header */ elf64 = (Elf64_Ehdr *)vmlinux.addr; if ( elf64->e_ident[EI_MAG0] != ELFMAG0 || elf64->e_ident[EI_MAG1] != ELFMAG1 || elf64->e_ident[EI_MAG2] != ELFMAG2 || elf64->e_ident[EI_MAG3] != ELFMAG3 || elf64->e_ident[EI_CLASS] != ELFCLASS64 || elf64->e_ident[EI_DATA] != ELFDATA2MSB || elf64->e_type != ET_EXEC || elf64->e_machine != EM_PPC64 ) { printf("Error: not a valid PPC64 ELF file!\n\r"); exit(); } elf64ph = (Elf64_Phdr *)((unsigned long)elf64 + (unsigned long)elf64->e_phoff); for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) { if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0) break; } printf("... skipping 0x%lx bytes of ELF header\n\r", (unsigned long)elf64ph->p_offset); vmlinux.addr += (unsigned long)elf64ph->p_offset; vmlinux.size -= (unsigned long)elf64ph->p_offset; flush_cache((void *)vmlinux.addr, vmlinux.memsize); bi_recs = make_bi_recs(vmlinux.addr + vmlinux.memsize); kernel_entry = (kernel_entry_t)vmlinux.addr; printf( "kernel:\n\r" " entry addr = 0x%lx\n\r" " a1 = 0x%lx,\n\r" " a2 = 0x%lx,\n\r" " prom = 0x%lx,\n\r" " bi_recs = 0x%lx,\n\r", (unsigned long)kernel_entry, a1, a2, (unsigned long)prom, (unsigned long)bi_recs); kernel_entry( a1, a2, prom, bi_recs ); printf("Error: Linux kernel returned to zImage bootloader!\n\r"); exit(); }